diff --git a/website/amd/mobiledoc-kit.js b/website/amd/mobiledoc-kit.js index 12e276754..859e8d05c 100644 --- a/website/amd/mobiledoc-kit.js +++ b/website/amd/mobiledoc-kit.js @@ -128,6 +128,7 @@ define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-ren return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render(); case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0: case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1: + case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_2: return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render(); default: throw new Error('Unexpected Mobiledoc version "' + version + '"'); @@ -507,15 +508,16 @@ define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-render exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0; var MOBILEDOC_VERSION_0_3_1 = '0.3.1'; exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1; - var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_0; + var MOBILEDOC_VERSION_0_3_2 = '0.3.2'; - exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; + exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2; var IMAGE_SECTION_TAG_NAME = 'img'; function validateVersion(version) { switch (version) { case MOBILEDOC_VERSION_0_3_0: case MOBILEDOC_VERSION_0_3_1: + case MOBILEDOC_VERSION_0_3_2: return; default: throw new Error('Unexpected Mobiledoc version "' + version + '"'); @@ -934,19 +936,22 @@ define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-render }, { key: 'renderMarkupSection', value: function renderMarkupSection(_ref5) { - var _ref52 = _slicedToArray(_ref5, 3); + var _ref52 = _slicedToArray(_ref5, 4); var type = _ref52[0]; var tagName = _ref52[1]; var markers = _ref52[2]; + var _ref52$3 = _ref52[3]; + var attributes = _ref52$3 === undefined ? [] : _ref52$3; tagName = tagName.toLowerCase(); if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) { return; } + var attrsObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attributes); var renderer = this.sectionElementRendererFor(tagName); - var element = renderer(tagName, this.dom); + var element = renderer(tagName, this.dom, attrsObj); this.renderMarkersOnElement(element, markers); return element; @@ -985,6 +990,8 @@ define("mobiledoc-dom-renderer/utils/array-utils", ["exports"], function (export "use strict"; exports.includes = includes; + exports.kvArrayToObject = kvArrayToObject; + exports.objectToSortedKVArray = objectToSortedKVArray; function includes(array, detectValue) { for (var i = 0; i < array.length; i++) { @@ -995,6 +1002,43 @@ define("mobiledoc-dom-renderer/utils/array-utils", ["exports"], function (export } return false; } + + /** + * @param {Array} array of key1,value1,key2,value2,... + * @return {Object} {key1:value1, key2:value2, ...} + * @private + */ + + function kvArrayToObject(array) { + if (!Array.isArray(array)) { + return {}; + } + + var obj = {}; + for (var i = 0; i < array.length; i += 2) { + var key = array[i]; + var value = array[i + 1]; + + obj[key] = value; + } + return obj; + } + + /** + * @param {Object} {key1:value1, key2:value2, ...} + * @return {Array} array of key1,value1,key2,value2,... + * @private + */ + + function objectToSortedKVArray(obj) { + var keys = Object.keys(obj).sort(); + var result = []; + keys.forEach(function (k) { + result.push(k); + result.push(obj[k]); + }); + return result; + } }); define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) { 'use strict'; @@ -1032,11 +1076,31 @@ define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-r exports.defaultSectionElementRenderer = defaultSectionElementRenderer; exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer; + var VALID_ATTRIBUTES = ['data-md-text-align']; + + exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + function _isValidAttribute(attr) { + return VALID_ATTRIBUTES.indexOf(attr) !== -1; + } + + function handleMarkupSectionAttribute(element, attributeKey, attributeValue) { + if (!_isValidAttribute(attributeKey)) { + throw new Error('Cannot use attribute: ' + attributeKey); + } + + element.setAttribute(attributeKey, attributeValue); + } function defaultSectionElementRenderer(tagName, dom) { + var attrsObj = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; + var element = undefined; if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { element = dom.createElement(tagName); + + Object.keys(attrsObj).forEach(function (k) { + handleMarkupSectionAttribute(element, k, attrsObj[k]); + }); } else { element = dom.createElement('div'); element.setAttribute('class', tagName); @@ -1082,7 +1146,7 @@ define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc } function sanitizeHref(url) { - var protocol = getProtocol(url); + var protocol = getProtocol(url).toLowerCase(); if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) { return 'unsafe:' + url; } @@ -1166,8 +1230,6 @@ define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder type: 'dom', render: function render(_ref) { - var env = _ref.env; - var options = _ref.options; var payload = _ref.payload; var img = document.createElement('img'); @@ -1376,7 +1438,8 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array range: _mobiledocKitUtilsCursorRange['default'].blankRange(), activeMarkups: [], activeSections: [], - activeSectionTagNames: [] + activeSectionTagNames: [], + activeSectionAttributes: {} }; this.prevState = this.state = defaultState; @@ -1417,7 +1480,7 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array var state = this.state; var prevState = this.prevState; - return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames); + return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)((0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes)); } /** @@ -1454,6 +1517,7 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array state.activeSectionTagNames = state.activeSections.map(function (s) { return s.isNested ? s.parent.tagName : s.tagName; }); + state.activeSectionAttributes = this._readSectionAttributes(state.activeSections); return state; } }, { @@ -1476,6 +1540,22 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array return post.markupsInRange(range); } + }, { + key: '_readSectionAttributes', + value: function _readSectionAttributes(sections) { + return sections.reduce(function (sectionAttributes, s) { + var attributes = s.isNested ? s.parent.attributes : s.attributes; + Object.keys(attributes || {}).forEach(function (attrName) { + var camelizedAttrName = attrName.replace(/^data-md-/, ''); + var attrValue = attributes[attrName]; + sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || []; + if (!(0, _mobiledocKitUtilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) { + sectionAttributes[camelizedAttrName].push(attrValue); + } + }); + return sectionAttributes; + }, {}); + } }, { key: '_removeActiveMarkup', value: function _removeActiveMarkup(markup) { @@ -1502,6 +1582,15 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array return this.state.activeSections; } + /** + * @return {Object} + */ + }, { + key: 'activeSectionAttributes', + get: function get() { + return this.state.activeSectionAttributes; + } + /** * @return {Markup[]} */ @@ -1537,6 +1626,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', placeholder: 'Write here...', spellcheck: true, autofocus: true, + showLinkTooltips: true, undoDepth: 5, undoBlockTimeout: 5000, // ms for an undo event cards: [], @@ -1590,6 +1680,8 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', * a custom toolbar. * * {@link Editor#onTextInput} -- Register callbacks when the user enters text * that matches a given string or regex. + * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before + * applying changes from {@link Editor#toggleMarkup} */ var Editor = (function () { @@ -1610,6 +1702,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', * @param {String} [options.placeholder] Default text to show before user starts typing. * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered. + * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links * @param {number} [options.undoDepth=5] How many undo levels will be available. * Set to 0 to disable undo/redo functionality. * @return {Editor} @@ -1625,7 +1718,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType); this._views = []; - this.isEditable = null; + this.isEditable = true; this._parserPlugins = options.parserPlugins || []; // FIXME: This should merge onto this.options @@ -1654,6 +1747,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this); this._editState = new _mobiledocKitEditorEditState['default'](this); this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES)); + this._beforeHooks = { toggleMarkup: [] }; _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) { return _this.onTextInput(handler); @@ -1760,12 +1854,10 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', this.element = element; - if (this.isEditable === null) { - this.enableEditing(); + if (this.showLinkTooltips) { + this._addTooltip(); } - this._addTooltip(); - // A call to `run` will trigger the didUpdatePostCallbacks hooks with a // postEditor. this.run(function () {}); @@ -1779,6 +1871,12 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', this._mutationHandler.init(); this._eventManager.init(); + if (this.isEditable === false) { + this.disableEditing(); + } else { + this.enableEditing(); + } + if (this.autofocus) { this.selectRange(this.post.headPosition()); } @@ -2106,15 +2204,17 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', switch (format) { case 'html': - var result = undefined; - if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) { - rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc); - result = '
' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
'; - } else { - // Fallback to text serialization - result = this.serializePost(post, 'text', options); + { + var result = undefined; + if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) { + rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc); + result = '
' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
'; + } else { + // Fallback to text serialization + result = this.serializePost(post, 'text', options); + } + return result; } - return result; case 'text': rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc); return rendered.result; @@ -2179,12 +2279,9 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }, { key: 'disableEditing', value: function disableEditing() { - if (this.isEditable === false) { - return; - } - this.isEditable = false; if (this.hasRendered) { + this._eventManager.stop(); this.element.setAttribute('contentEditable', false); this.setPlaceholder(''); this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange()); @@ -2202,7 +2299,8 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', key: 'enableEditing', value: function enableEditing() { this.isEditable = true; - if (this.element) { + if (this.hasRendered) { + this._eventManager.start(); this.element.setAttribute('contentEditable', true); this.setPlaceholder(this.placeholder); } @@ -2440,22 +2538,55 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }); } + /** + * @callback editorBeforeCallback + * @param { Object } details + * @param { Markup } details.markup + * @param { Range } details.range + * @param { boolean } details.willAdd Whether the markup will be applied + */ + + /** + * Register a callback that will be run before {@link Editor#toggleMarkup} is applied. + * If any callback returns literal `false`, the toggling of markup will be canceled. + * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and + * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks. + * @param {editorBeforeCallback} + */ + }, { + key: 'beforeToggleMarkup', + value: function beforeToggleMarkup(callback) { + this._beforeHooks.toggleMarkup.push(callback); + } + /** * Toggles the given markup at the editor's current {@link Range}. * If the range is collapsed this changes the editor's state so that the * next characters typed will be affected. If there is text selected * (aka a non-collapsed range), the selections' markup will be toggled. * If the editor is not focused and has no active range, nothing happens. + * Hooks added using #beforeToggleMarkup will be run before toggling, + * and if any of them returns literal false, toggling the markup will be canceled + * and no change will be applied. * @param {String} markup E.g. "b", "em", "a" + * @param {Object} [attributes={}] E.g. {href: "http://bustle.com"} * @public * @see PostEditor#toggleMarkup */ }, { key: 'toggleMarkup', value: function toggleMarkup(markup) { - markup = this.builder.createMarkup(markup); + var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + + markup = this.builder.createMarkup(markup, attributes); var range = this.range; + var willAdd = !this.detectMarkupInRange(range, markup.tagName); + var shouldCancel = this._runBeforeHooks('toggleMarkup', { markup: markup, range: range, willAdd: willAdd }); + if (shouldCancel) { + return; + } + if (range.isCollapsed) { this._editState.toggleMarkupState(markup); this._inputModeDidChange(); @@ -2528,6 +2659,41 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }); } + /** + * Sets an attribute for the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @param {String} value The value of the attribute. + * @public + * @see PostEditor#setAttribute + */ + }, { + key: 'setAttribute', + value: function setAttribute(key, value) { + var _this7 = this; + + this.run(function (postEditor) { + return postEditor.setAttribute(key, value, _this7.range); + }); + } + + /** + * Removes an attribute from the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @public + * @see PostEditor#removeAttribute + */ + }, { + key: 'removeAttribute', + value: function removeAttribute(key) { + var _this8 = this; + + this.run(function (postEditor) { + return postEditor.removeAttribute(key, _this8.range); + }); + } + /** * Finds and runs the first matching key command for the event * @@ -2639,7 +2805,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }, { key: 'insertCard', value: function insertCard(cardName) { - var _this7 = this; + var _this9 = this; var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; @@ -2658,7 +2824,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', var position = range.tail; card = postEditor.builder.createCardSection(cardName, cardPayload); if (inEditMode) { - _this7.editCard(card); + _this9.editCard(card); } if (!range.isCollapsed) { @@ -2673,7 +2839,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', if (section.isBlank) { postEditor.replaceSection(section, card); } else { - var collection = _this7.post.sections; + var collection = _this9.post.sections; postEditor.insertSectionBefore(collection, card, section.next); } @@ -2745,6 +2911,28 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', } (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments); } + + /** + * Runs each callback for the given hookName. + * Only the hookName 'toggleMarkup' is currently supported + * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled + * @private + */ + }, { + key: '_runBeforeHooks', + value: function _runBeforeHooks(hookName) { + var hooks = this._beforeHooks[hookName] || []; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < hooks.length; i++) { + if (hooks[i].apply(hooks, args) === false) { + return true; + } + } + } }, { key: 'builder', get: function get() { @@ -2799,6 +2987,11 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', return activeSections[activeSections.length - 1]; } + }, { + key: 'activeSectionAttributes', + get: function get() { + return this._editState.activeSectionAttributes; + } }, { key: 'activeMarkups', get: function get() { @@ -2831,12 +3024,11 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor); this._listeners = []; this.modifierKeys = { - shift: false, - alt: false, - ctrl: false + shift: false }; this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this)); + this.started = true; } _createClass(EventManager, [{ @@ -2854,6 +3046,16 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as this._selectionManager.start(); } + }, { + key: 'start', + value: function start() { + this.started = true; + } + }, { + key: 'stop', + value: function stop() { + this.started = false; + } }, { key: 'registerInputHandler', value: function registerInputHandler(inputHandler) { @@ -2914,7 +3116,6 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as var _ref42 = _slicedToArray(_ref4, 3); var context = _ref42[0]; - var type = _ref42[1]; var listener = _ref42[2]; listener.call(context, event); @@ -2932,6 +3133,11 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as value: function _handleEvent(type, event) { var element = event.target; + if (!this.started) { + // abort handling this event + return true; + } + if (!this.isElementAddressable(element)) { // abort handling this event return true; @@ -3014,29 +3220,34 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as switch (true) { // FIXME This should be restricted to only card/atom boundaries case key.isHorizontalArrowWithoutModifiersOtherThanShift(): - var newRange = undefined; - if (key.isShift()) { - newRange = range.extend(key.direction * 1); - } else { - newRange = range.move(key.direction); - } + { + var newRange = undefined; + if (key.isShift()) { + newRange = range.extend(key.direction * 1); + } else { + newRange = range.move(key.direction); + } - editor.selectRange(newRange); - event.preventDefault(); - break; + editor.selectRange(newRange); + event.preventDefault(); + break; + } case key.isDelete(): - var direction = key.direction; - - var unit = 'char'; - if (this.modifierKeys.alt && _mobiledocKitUtilsBrowser['default'].isMac()) { - unit = 'word'; - } else if (this.modifierKeys.ctrl && _mobiledocKitUtilsBrowser['default'].isWin()) { - unit = 'word'; + { + var direction = key.direction; + + var unit = 'char'; + if (key.altKey && _mobiledocKitUtilsBrowser['default'].isMac()) { + unit = 'word'; + } else if (key.ctrlKey && !_mobiledocKitUtilsBrowser['default'].isMac()) { + unit = 'word'; + } + editor.performDelete({ direction: direction, unit: unit }); + event.preventDefault(); + break; } - editor.performDelete({ direction: direction, unit: unit }); - event.preventDefault(); - break; case key.isEnter(): + this._textInputHandler.handleNewLine(); editor.handleNewline(event); break; case key.isTab(): @@ -3144,10 +3355,6 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as if (key.isShiftKey()) { this.modifierKeys.shift = isDown; - } else if (key.isAltKey()) { - this.modifierKeys.alt = isDown; - } else if (key.isCtrlKey()) { - this.modifierKeys.ctrl = isDown; } } }]); @@ -3322,7 +3529,7 @@ define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key function characterToCode(character) { var upperCharacter = character.toUpperCase(); - var special = _mobiledocKitUtilsKey.SPECIAL_KEYS[upperCharacter]; + var special = (0, _mobiledocKitUtilsKey.specialCharacterToCode)(upperCharacter); if (special) { return special; } else { @@ -4477,8 +4684,6 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName); var post = this.editor.post; - var nextRange = range; - var everySectionHasTagName = true; post.walkMarkerableSections(range, function (section) { if (!_this13._isSameSectionType(section, sectionTagName)) { @@ -4487,17 +4692,91 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi }); var tagName = everySectionHasTagName ? 'p' : sectionTagName; - var firstChanged = undefined; + var sectionTransformations = []; post.walkMarkerableSections(range, function (section) { var changedSection = _this13.changeSectionTagName(section, tagName); - firstChanged = firstChanged || changedSection; + sectionTransformations.push({ + from: section, + to: changedSection + }); }); - if (firstChanged) { - nextRange = firstChanged.headPosition().toRange(); - } + var nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations); this.setRange(nextRange); } + }, { + key: '_determineNextRangeAfterToggleSection', + value: function _determineNextRangeAfterToggleSection(range, sectionTransformations) { + if (sectionTransformations.length) { + var changedHeadSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref2) { + var from = _ref2.from; + + return from === range.headSection; + }).to; + var changedTailSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref3) { + var from = _ref3.from; + + return from === range.tailSection; + }).to; + + if (changedHeadSection.isListSection || changedTailSection.isListSection) { + // We don't know to which ListItem's the original sections point at, so + // we don't have enough information to reconstruct the range when + // dealing with lists. + return sectionTransformations[0].to.headPosition().toRange(); + } else { + return _mobiledocKitUtilsCursorRange['default'].create(changedHeadSection, range.headSectionOffset, changedTailSection, range.tailSectionOffset, range.direction); + } + } else { + return range; + } + } + }, { + key: 'setAttribute', + value: function setAttribute(key, value) { + var range = arguments.length <= 2 || arguments[2] === undefined ? this._range : arguments[2]; + + this._mutateAttribute(key, range, function (section, attribute) { + if (section.getAttribute(attribute) !== value) { + section.setAttribute(attribute, value); + return true; + } + }); + } + }, { + key: 'removeAttribute', + value: function removeAttribute(key) { + var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1]; + + this._mutateAttribute(key, range, function (section, attribute) { + if (section.hasAttribute(attribute)) { + section.removeAttribute(attribute); + return true; + } + }); + } + }, { + key: '_mutateAttribute', + value: function _mutateAttribute(key, range, cb) { + var _this14 = this; + + range = (0, _mobiledocKitUtilsToRange['default'])(range); + var post = this.editor.post; + + var attribute = 'data-md-' + key; + + post.walkMarkerableSections(range, function (section) { + if (section.isListItem) { + section = section.parent; + } + + if (cb(section, attribute) === true) { + _this14._markDirty(section); + } + }); + + this.setRange(range); + } }, { key: '_isSameSectionType', value: function _isSameSectionType(section, sectionTagName) { @@ -4576,13 +4855,11 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi if (positionIsMiddle) { var item = position.section; - var _splitListItem3 = // jshint ignore:line - this._splitListItem(item, position); + var _splitListItem3 = this._splitListItem(item, position); - var _splitListItem32 = _slicedToArray(_splitListItem3, 2); + var _splitListItem32 = _slicedToArray(_splitListItem3, 1); var pre = _splitListItem32[0]; - var post = _splitListItem32[1]; position = pre.tailPosition(); } @@ -4621,10 +4898,10 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi }, { key: '_splitListAtItem', value: function _splitListAtItem(list, item) { - var _this14 = this; + var _this15 = this; var next = list; - var prev = this.builder.createListSection(next.tagName); + var prev = this.builder.createListSection(next.tagName, [], next.attributes); var mid = this.builder.createListSection(next.tagName); var addToPrev = true; @@ -4642,7 +4919,7 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi return; // break after iterating prev and mid parts of the list } listToAppend.join(i); - _this14.removeSection(i); + _this15.removeSection(i); }); var found = !addToPrev; (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found); @@ -4656,7 +4933,7 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi [prev, next].forEach(function (_list) { var isAttached = !!_list.parent; if (_list.isBlank && isAttached) { - _this14.removeSection(_list); + _this15.removeSection(_list); } }); }); @@ -4674,12 +4951,10 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi var _splitListAtItem2 = this._splitListAtItem(listSection, section); - var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 3); + var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 2); - var prev = _splitListAtItem22[0]; var mid = _splitListAtItem22[1]; - var next = _splitListAtItem22[2]; - // jshint ignore:line + this.replaceSection(mid, markupSection); return markupSection; } @@ -4699,12 +4974,10 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi if (section.isListItem) { var _splitListAtItem3 = this._splitListAtItem(section.parent, section); - var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 3); + var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 2); - var prev = _splitListAtItem32[0]; var mid = _splitListAtItem32[1]; - var next = _splitListAtItem32[2]; - // jshint ignore:line + sectionToReplace = mid; } else { sectionToReplace = section; @@ -4810,33 +5083,33 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi }, { key: 'removeAllSections', value: function removeAllSections() { - var _this15 = this; + var _this16 = this; this.editor.post.sections.toArray().forEach(function (section) { - _this15.removeSection(section); + _this16.removeSection(section); }); } }, { key: 'migrateSectionsFromPost', value: function migrateSectionsFromPost(post) { - var _this16 = this; + var _this17 = this; post.sections.toArray().forEach(function (section) { post.sections.remove(section); - _this16.insertSectionBefore(_this16.editor.post.sections, section, null); + _this17.insertSectionBefore(_this17.editor.post.sections, section, null); }); } }, { key: '_scheduleListRemovalIfEmpty', value: function _scheduleListRemovalIfEmpty(listSection) { - var _this17 = this; + var _this18 = this; this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () { // if the list is attached and blank after we do other rendering stuff, // remove it var isAttached = !!listSection.parent; if (isAttached && listSection.isBlank) { - _this17.removeSection(listSection); + _this18.removeSection(listSection); } }); } @@ -5103,12 +5376,10 @@ define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/uti } else { var _breakListAtCursor2 = this._breakListAtCursor(); - var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 3); + var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 2); - var pre = _breakListAtCursor22[0]; var blank = _breakListAtCursor22[1]; - var post = _breakListAtCursor22[2]; - // jshint ignore:line + this.cursorPosition = blank.tailPosition(); } } @@ -5183,13 +5454,11 @@ define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/uti }, { key: '_breakMarkerableAtCursor', value: function _breakMarkerableAtCursor() { - var _postEditor$splitSection = // jshint ignore:line - this.postEditor.splitSection(this.cursorPosition); + var _postEditor$splitSection = this.postEditor.splitSection(this.cursorPosition); - var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 2); + var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 1); var pre = _postEditor$splitSection2[0]; - var post = _postEditor$splitSection2[1]; this.cursorPosition = pre.tailPosition(); } @@ -5295,7 +5564,9 @@ define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/uti key: 'insert', value: function insert(cursorPosition, newPost) { var visitor = new Visitor(this, cursorPosition); - visitor.visit(newPost); + if (!newPost.isBlank) { + visitor.visit(newPost); + } return visitor.cursorPosition; } }]); @@ -5492,7 +5763,7 @@ define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/edit exports['default'] = SelectionManager; }); -define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate) { +define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsCharacters) { 'use strict'; var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); @@ -5543,13 +5814,29 @@ define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/uti } } }, { + key: 'handleNewLine', + value: function handleNewLine() { + var editor = this.editor; + + var matchedHandler = this._findHandler(_mobiledocKitUtilsCharacters.ENTER); + if (matchedHandler) { + var _matchedHandler2 = _slicedToArray(matchedHandler, 2); + + var handler = _matchedHandler2[0]; + var matches = _matchedHandler2[1]; + + handler.run(editor, matches); + } + } + }, { key: '_findHandler', value: function _findHandler() { + var string = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0]; var _editor$range = this.editor.range; var head = _editor$range.head; var section = _editor$range.head.section; - var preText = section.textUntil(head); + var preText = section.textUntil(head) + string; for (var i = 0; i < this._handlers.length; i++) { var handler = this._handlers[i]; @@ -5752,24 +6039,19 @@ define('mobiledoc-kit/editor/ui', ['exports'], function (exports) { var hasLink = editor.detectMarkupInRange(range, 'a'); if (hasLink) { - editor.run(function (postEditor) { - return postEditor.toggleMarkup('a'); - }); + editor.toggleMarkup('a'); } else { showPrompt('Enter a URL', defaultUrl, function (url) { if (!url) { return; } - editor.run(function (postEditor) { - var markup = postEditor.builder.createMarkup('a', { href: url }); - postEditor.toggleMarkup(markup); - }); + editor.toggleMarkup('a', { href: url }); }); } } }); -define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion) { +define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version', 'mobiledoc-kit/renderers/mobiledoc'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion, _mobiledocKitRenderersMobiledoc) { 'use strict'; exports.registerGlobal = registerGlobal; @@ -5781,7 +6063,8 @@ define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-ki Range: _mobiledocKitUtilsCursorRange['default'], Position: _mobiledocKitUtilsCursorPosition['default'], Error: _mobiledocKitUtilsMobiledocError['default'], - VERSION: _mobiledocKitVersion['default'] + VERSION: _mobiledocKitVersion['default'], + MOBILEDOC_VERSION: _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION }; function registerGlobal(global) { @@ -5792,8 +6075,53 @@ define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-ki exports.UI = _mobiledocKitEditorUi; exports.Range = _mobiledocKitUtilsCursorRange['default']; exports.Position = _mobiledocKitUtilsCursorPosition['default']; + exports.MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION; exports['default'] = Mobiledoc; }); +define('mobiledoc-kit/models/_attributable', ['exports', 'mobiledoc-kit/utils/object-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsObjectUtils, _mobiledocKitUtilsArrayUtils) { + 'use strict'; + + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + + exports.attributable = attributable; + var VALID_ATTRIBUTES = ['data-md-text-align']; + + exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + /* + * A "mixin" to add section attribute support + * to markup and list sections. + */ + + function attributable(ctx) { + ctx.attributes = {}; + + ctx.hasAttribute = function (key) { + return key in ctx.attributes; + }; + + ctx.setAttribute = function (key, value) { + if (!(0, _mobiledocKitUtilsArrayUtils.contains)(VALID_ATTRIBUTES, key)) { + throw new Error('Invalid attribute "' + key + '" was passed. Constrain attributes to the spec-compliant whitelist.'); + } + ctx.attributes[key] = value; + }; + ctx.removeAttribute = function (key) { + delete ctx.attributes[key]; + }; + ctx.getAttribute = function (key) { + return ctx.attributes[key]; + }; + ctx.eachAttribute = function (cb) { + (0, _mobiledocKitUtilsObjectUtils.entries)(ctx.attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return cb(k, v); + }); + }; + } +}); define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) { 'use strict'; @@ -6268,7 +6596,7 @@ define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-uti value: function nextLeafSection() { var next = this.next; if (next) { - if (!!next.items) { + if (next.items) { return next.items.head; } else { return next; @@ -6294,7 +6622,7 @@ define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-uti var prev = this.prev; if (prev) { - if (!!prev.items) { + if (prev.items) { return prev.items.tail; } else { return prev; @@ -6949,12 +7277,14 @@ define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_mark exports['default'] = ListItem; }); -define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitModels_attributable, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) { 'use strict'; + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -6971,10 +7301,12 @@ define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/lin _inherits(ListSection, _Section); function ListSection() { + var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; + var _this = this; - var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, ListSection); @@ -6983,6 +7315,15 @@ define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/lin this.isListSection = true; this.isLeafSection = false; + (0, _mobiledocKitModels_attributable.attributable)(this); + (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return _this.setAttribute(k, v); + }); + this.items = new _mobiledocKitUtilsLinkedList['default']({ adoptItem: function adoptItem(i) { (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem); @@ -7222,12 +7563,14 @@ define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', exports['default'] = Marker; }); -define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { +define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModels_attributable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsObjectUtils) { 'use strict'; + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -7250,11 +7593,25 @@ define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/ function MarkupSection() { var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; + + var _this = this; + var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, MarkupSection); _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers); + + (0, _mobiledocKitModels_attributable.attributable)(this); + (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return _this.setAttribute(k, v); + }); + this.isMarkupSection = true; } @@ -7267,7 +7624,7 @@ define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/ key: 'splitAtMarker', value: function splitAtMarker(marker) { var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; - var beforeSection = this.builder.createMarkupSection(this.tagName, []); + var beforeSection = this.builder.createMarkupSection(this.tagName, [], false, this.attributes); var afterSection = this.builder.createMarkupSection(); return this._redistributeMarkers(beforeSection, afterSection, marker, offset); @@ -7295,6 +7652,12 @@ define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils var VALID_ATTRIBUTES = ['href', 'rel']; exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + /** + * A Markup is similar with an inline HTML tag that might be added to + * text to modify its meaning and/or display. Examples of types of markup + * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links). + * @property {String} tagName + */ var Markup = (function () { /* @@ -7316,6 +7679,12 @@ define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1); } + /** + * Whether text in the forward direction of the cursor (i.e. to the right in ltr text) + * should be considered to have this markup applied to it. + * @private + */ + _createClass(Markup, [{ key: 'isForwardInclusive', value: function isForwardInclusive() { @@ -7331,6 +7700,11 @@ define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils value: function hasTag(tagName) { return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName); } + + /** + * Returns the attribute value + * @param {String} name, e.g. "href" + */ }, { key: 'getAttribute', value: function getAttribute(name) { @@ -7433,9 +7807,10 @@ define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/mode var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0]; var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; + var attributes = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName); - var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers); + var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers, attributes); if (isGenerated) { section.isGenerated = true; } @@ -7447,9 +7822,10 @@ define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/mode value: function createListSection() { var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0]; var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName); - var section = new _mobiledocKitModelsListSection['default'](tagName, items); + var section = new _mobiledocKitModelsListSection['default'](tagName, items, attributes); section.builder = this; return section; } @@ -7740,7 +8116,7 @@ define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'm if (next) { if (next.isLeafSection) { return next; - } else if (!!next.items) { + } else if (next.items) { return next.items.head; } else { (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false); @@ -7790,6 +8166,7 @@ define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'm }); } else { newSection = section.clone(); + sectionParent = post; } if (sectionParent) { sectionParent.sections.append(newSection); @@ -8099,6 +8476,7 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); exports.transformHTMLText = transformHTMLText; + exports.trimSectionText = trimSectionText; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -8114,6 +8492,17 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- return text; } + function trimSectionText(section) { + if (section.isMarkerable && section.markers.length) { + var _section$markers = section.markers; + var head = _section$markers.head; + var tail = _section$markers.tail; + + head.value = head.value.replace(/^\s+/, ''); + tail.value = tail.value.replace(/\s+$/, ''); + } + } + function isGoogleDocsContainer(element) { return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id); } @@ -8186,6 +8575,12 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- _this.appendSections(post, sections); }); + // trim leading/trailing whitespace of markerable sections to avoid + // unnessary whitespace from indented HTML input + (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) { + return trimSectionText(section); + }); + return post; } }, { @@ -8200,7 +8595,9 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- }, { key: 'appendSection', value: function appendSection(post, section) { - if (section.isBlank || section.isMarkerable && trim(section.text) === '') { + if (section.isBlank || section.isMarkerable && trim(section.text) === "" && !(0, _mobiledocKitUtilsArrayUtils.any)(section.markers, function (marker) { + return marker.isAtom; + })) { return; } @@ -8474,7 +8871,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sectionData = _ref.sections; try { @@ -8550,7 +8946,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseCardSection(_ref3, post) { var _ref32 = _slicedToArray(_ref3, 3); - var type = _ref32[0]; var name = _ref32[1]; var payload = _ref32[2]; @@ -8562,7 +8957,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseImageSection(_ref4, post) { var _ref42 = _slicedToArray(_ref4, 2); - var type = _ref42[0]; var src = _ref42[1]; var section = this.builder.createImageSection(src); @@ -8573,7 +8967,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseMarkupSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 3); - var type = _ref52[0]; var tagName = _ref52[1]; var markers = _ref52[2]; @@ -8593,7 +8986,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseListSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 3); - var type = _ref62[0]; var tagName = _ref62[1]; var items = _ref62[2]; @@ -8679,7 +9071,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sections = _ref.sections; var markerTypes = _ref.markups; var cardTypes = _ref.cards; @@ -8810,7 +9201,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseCardSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 2); - var type = _ref52[0]; var cardIndex = _ref52[1]; var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); @@ -8828,7 +9218,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseImageSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 2); - var type = _ref62[0]; var src = _ref62[1]; var section = this.builder.createImageSection(src); @@ -8839,7 +9228,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseMarkupSection(_ref7, post) { var _ref72 = _slicedToArray(_ref7, 3); - var type = _ref72[0]; var tagName = _ref72[1]; var markers = _ref72[2]; @@ -8859,7 +9247,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseListSection(_ref8, post) { var _ref82 = _slicedToArray(_ref8, 3); - var type = _ref82[0]; var tagName = _ref82[1]; var items = _ref82[2]; @@ -8920,13 +9307,325 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE: - var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value), - _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3), - atomName = _getAtomTypeFromIndex2[0], - atomValue = _getAtomTypeFromIndex2[1], - atomPayload = _getAtomTypeFromIndex2[2]; + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; - return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } + default: + (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false); + } + } + }]); + + return MobiledocParser; + })(); + + exports['default'] = MobiledocParser; +}); +define('mobiledoc-kit/parsers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) { + 'use strict'; + + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + /* + * Parses from mobiledoc -> post + */ + + var MobiledocParser = (function () { + function MobiledocParser(builder) { + _classCallCheck(this, MobiledocParser); + + this.builder = builder; + } + + /** + * @param {Mobiledoc} + * @return {Post} + */ + + _createClass(MobiledocParser, [{ + key: 'parse', + value: function parse(_ref) { + var sections = _ref.sections; + var markerTypes = _ref.markups; + var cardTypes = _ref.cards; + var atomTypes = _ref.atoms; + + try { + var post = this.builder.createPost(); + + this.markups = []; + this.markerTypes = this.parseMarkerTypes(markerTypes); + this.cardTypes = this.parseCardTypes(cardTypes); + this.atomTypes = this.parseAtomTypes(atomTypes); + this.parseSections(sections, post); + + return post; + } catch (e) { + (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false); + } + } + }, { + key: 'parseMarkerTypes', + value: function parseMarkerTypes(markerTypes) { + var _this = this; + + return markerTypes.map(function (markerType) { + return _this.parseMarkerType(markerType); + }); + } + }, { + key: 'parseMarkerType', + value: function parseMarkerType(_ref2) { + var _ref22 = _slicedToArray(_ref2, 2); + + var tagName = _ref22[0]; + var attributesArray = _ref22[1]; + + var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []); + return this.builder.createMarkup(tagName, attributesObject); + } + }, { + key: 'parseCardTypes', + value: function parseCardTypes(cardTypes) { + var _this2 = this; + + return cardTypes.map(function (cardType) { + return _this2.parseCardType(cardType); + }); + } + }, { + key: 'parseCardType', + value: function parseCardType(_ref3) { + var _ref32 = _slicedToArray(_ref3, 2); + + var cardName = _ref32[0]; + var cardPayload = _ref32[1]; + + return [cardName, cardPayload]; + } + }, { + key: 'parseAtomTypes', + value: function parseAtomTypes(atomTypes) { + var _this3 = this; + + return atomTypes.map(function (atomType) { + return _this3.parseAtomType(atomType); + }); + } + }, { + key: 'parseAtomType', + value: function parseAtomType(_ref4) { + var _ref42 = _slicedToArray(_ref4, 3); + + var atomName = _ref42[0]; + var atomValue = _ref42[1]; + var atomPayload = _ref42[2]; + + return [atomName, atomValue, atomPayload]; + } + }, { + key: 'parseSections', + value: function parseSections(sections, post) { + var _this4 = this; + + sections.forEach(function (section) { + return _this4.parseSection(section, post); + }); + } + }, { + key: 'parseSection', + value: function parseSection(section, post) { + var _section = _slicedToArray(section, 1); + + var type = _section[0]; + + switch (type) { + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_SECTION_TYPE: + this.parseMarkupSection(section, post); + break; + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_IMAGE_SECTION_TYPE: + this.parseImageSection(section, post); + break; + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_CARD_SECTION_TYPE: + this.parseCardSection(section, post); + break; + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_LIST_SECTION_TYPE: + this.parseListSection(section, post); + break; + default: + (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false); + } + } + }, { + key: 'getAtomTypeFromIndex', + value: function getAtomTypeFromIndex(index) { + var atomType = this.atomTypes[index]; + (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType); + return atomType; + } + }, { + key: 'getCardTypeFromIndex', + value: function getCardTypeFromIndex(index) { + var cardType = this.cardTypes[index]; + (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType); + return cardType; + } + }, { + key: 'parseCardSection', + value: function parseCardSection(_ref5, post) { + var _ref52 = _slicedToArray(_ref5, 2); + + var cardIndex = _ref52[1]; + + var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); + + var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2); + + var name = _getCardTypeFromIndex2[0]; + var payload = _getCardTypeFromIndex2[1]; + + var section = this.builder.createCardSection(name, payload); + post.sections.append(section); + } + }, { + key: 'parseImageSection', + value: function parseImageSection(_ref6, post) { + var _ref62 = _slicedToArray(_ref6, 2); + + var src = _ref62[1]; + + var section = this.builder.createImageSection(src); + post.sections.append(section); + } + }, { + key: 'parseMarkupSection', + value: function parseMarkupSection(_ref7, post) { + var _ref72 = _slicedToArray(_ref7, 4); + + var tagName = _ref72[1]; + var markers = _ref72[2]; + var attributesArray = _ref72[3]; + + var section = this.builder.createMarkupSection(tagName); + post.sections.append(section); + if (attributesArray) { + (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref8) { + var _ref82 = _slicedToArray(_ref8, 2); + + var key = _ref82[0]; + var value = _ref82[1]; + + section.setAttribute(key, value); + }); + } + this.parseMarkers(markers, section); + // Strip blank markers after they have been created. This ensures any + // markup they include has been correctly populated. + (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) { + return m.isBlank; + }).forEach(function (m) { + section.markers.remove(m); + }); + } + }, { + key: 'parseListSection', + value: function parseListSection(_ref9, post) { + var _ref92 = _slicedToArray(_ref9, 4); + + var tagName = _ref92[1]; + var items = _ref92[2]; + var attributesArray = _ref92[3]; + + var section = this.builder.createListSection(tagName); + post.sections.append(section); + if (attributesArray) { + (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref10) { + var _ref102 = _slicedToArray(_ref10, 2); + + var key = _ref102[0]; + var value = _ref102[1]; + + section.setAttribute(key, value); + }); + } + this.parseListItems(items, section); + } + }, { + key: 'parseListItems', + value: function parseListItems(items, section) { + var _this5 = this; + + items.forEach(function (i) { + return _this5.parseListItem(i, section); + }); + } + }, { + key: 'parseListItem', + value: function parseListItem(markers, section) { + var item = this.builder.createListItem(); + this.parseMarkers(markers, item); + section.items.append(item); + } + }, { + key: 'parseMarkers', + value: function parseMarkers(markers, parent) { + var _this6 = this; + + markers.forEach(function (m) { + return _this6.parseMarker(m, parent); + }); + } + }, { + key: 'parseMarker', + value: function parseMarker(_ref11, parent) { + var _this7 = this; + + var _ref112 = _slicedToArray(_ref11, 4); + + var type = _ref112[0]; + var markerTypeIndexes = _ref112[1]; + var closeCount = _ref112[2]; + var value = _ref112[3]; + + markerTypeIndexes.forEach(function (index) { + _this7.markups.push(_this7.markerTypes[index]); + }); + + var marker = this.buildMarkerType(type, value); + parent.markers.append(marker); + + this.markups = this.markups.slice(0, this.markups.length - closeCount); + } + }, { + key: 'buildMarkerType', + value: function buildMarkerType(type, value) { + switch (type) { + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_MARKER_TYPE: + return this.builder.createMarker(value, this.markups.slice()); + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_ATOM_MARKER_TYPE: + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; + + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false); } @@ -8966,7 +9665,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sections = _ref.sections; var markerTypes = _ref.markups; var cardTypes = _ref.cards; @@ -9097,7 +9795,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseCardSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 2); - var type = _ref52[0]; var cardIndex = _ref52[1]; var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); @@ -9115,7 +9812,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseImageSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 2); - var type = _ref62[0]; var src = _ref62[1]; var section = this.builder.createImageSection(src); @@ -9126,7 +9822,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseMarkupSection(_ref7, post) { var _ref72 = _slicedToArray(_ref7, 3); - var type = _ref72[0]; var tagName = _ref72[1]; var markers = _ref72[2]; @@ -9146,7 +9841,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseListSection(_ref8, post) { var _ref82 = _slicedToArray(_ref8, 3); - var type = _ref82[0]; var tagName = _ref82[1]; var items = _ref82[2]; @@ -9207,13 +9901,17 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE: - var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value), - _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3), - atomName = _getAtomTypeFromIndex2[0], - atomValue = _getAtomTypeFromIndex2[1], - atomPayload = _getAtomTypeFromIndex2[2]; + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; - return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false); } @@ -9225,7 +9923,7 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere exports['default'] = MobiledocParser; }); -define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/parsers/mobiledoc/0-3-2', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitParsersMobiledoc032, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) { 'use strict'; function parseVersion(mobiledoc) { @@ -9242,6 +9940,8 @@ define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mob return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc); case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION: return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc); + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION: + return new _mobiledocKitParsersMobiledoc032['default'](builder).parse(mobiledoc); default: (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false); } @@ -9261,8 +9961,7 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup var NEWLINES = /\n/g; function sanitize(text) { - text = text.replace(NEWLINES, ''); - return text; + return text.replace(NEWLINES, ' '); } /** @@ -9294,11 +9993,17 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup this._updateStateFromElement(element); - var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes; + var finished = false; + + // top-level text nodes will be run through parseNode later so avoid running + // the node through parserPlugins twice + if (!(0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) { + finished = this.runPlugins(element); + } + + if (!finished) { + var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes; - if (this.state.section.isListSection) { - this.parseListItems(childNodes); - } else { (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) { _this.parseNode(el); }); @@ -9308,39 +10013,30 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup return this.sections; } - }, { - key: 'parseListItems', - value: function parseListItems(childNodes) { - var _this2 = this; - - var state = this.state; - - (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) { - var parsed = new _this2.constructor(_this2.builder).parse(el); - var li = parsed[0]; - if (li && li.isListItem) { - state.section.items.append(li); - } - }); - } }, { key: 'runPlugins', value: function runPlugins(node) { - var _this3 = this; + var _this2 = this; var isNodeFinished = false; var env = { addSection: function addSection(section) { - _this3._closeCurrentSection(); - _this3.sections.push(section); + // avoid creating empty paragraphs due to wrapper elements around + // parser-plugin-handled elements + if (_this2.state.section.isMarkerable && !_this2.state.text && !_this2.state.section.text) { + _this2.state.section = null; + } else { + _this2._closeCurrentSection(); + } + _this2.sections.push(section); }, addMarkerable: function addMarkerable(marker) { - var state = _this3.state; + var state = _this2.state; var section = state.section; (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable); if (state.text) { - _this3._createMarker(); + _this2._createMarker(); } section.markers.append(marker); }, @@ -9357,9 +10053,13 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup } return false; } + + /* eslint-disable complexity */ }, { key: 'parseNode', value: function parseNode(node) { + var _this3 = this; + if (!this.state.section) { this._updateStateFromElement(node); } @@ -9369,6 +10069,72 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup return; } + // handle closing the current section and starting a new one if we hit a + // new-section-creating element. + if (this.state.section && !(0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.tagName) { + var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.tagName); + var isListSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName); + var isListItem = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName); + var isMarkupSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName); + var isNestedListSection = isListSection && this.state.section.isListItem; + var lastSection = this.sections[this.sections.length - 1]; + + // we can hit a list item after parsing a nested list, when that happens + // and the lists are of different types we need to make sure we switch + // the list type back + if (isListItem && lastSection && lastSection.isListSection) { + var parentElement = node.parentElement; + var parentElementTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(parentElement.tagName); + if (parentElementTagName !== lastSection.tagName) { + this._closeCurrentSection(); + this._updateStateFromElement(parentElement); + } + } + + // if we've broken out of a list due to nested section-level elements we + // can hit the next list item without having a list section in the current + // state. In this instance we find the parent list node and use it to + // re-initialize the state with a new list section + if (isListItem && !(this.state.section.isListItem || this.state.section.isListSection) && !lastSection.isListSection) { + this._closeCurrentSection(); + this._updateStateFromElement(node.parentElement); + } + + // if we have consecutive list sections of different types (ul, ol) then + // ensure we close the current section and start a new one + var isNewListSection = lastSection && lastSection.isListSection && this.state.section.isListItem && isListSection && tagName !== lastSection.tagName; + + if (isNewListSection || isListSection && !isNestedListSection || isMarkupSection || isListItem) { + // don't break out of the list for list items that contain a single

. + // deals with typical case of

  • Text

  • Text

  • + if (this.state.section.isListItem && tagName === 'p' && !node.nextSibling && (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.parentElement.tagName))) { + this.parseElementNode(node); + return; + } + + // avoid creating empty paragraphs due to wrapper elements around + // section-creating elements + if (this.state.section.isMarkerable && !this.state.text && this.state.section.markers.length === 0) { + this.state.section = null; + } else { + this._closeCurrentSection(); + } + + this._updateStateFromElement(node); + } + + if (this.state.section.isListSection) { + // ensure the list section is closed and added to the sections list. + // _closeCurrentSection handles pushing list items onto the list section + this._closeCurrentSection(); + + (0, _mobiledocKitUtilsArrayUtils.forEach)(node.childNodes, function (node) { + _this3.parseNode(node); + }); + return; + } + } + switch (node.nodeType) { case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT: this.parseTextNode(node); @@ -9387,7 +10153,7 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup var state = this.state; var markups = this._markupsFromElement(element); - if (markups.length && state.text.length) { + if (markups.length && state.text.length && state.section.isMarkerable) { this._createMarker(); } (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups)); @@ -9396,7 +10162,7 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup _this4.parseNode(node); }); - if (markups.length && state.text.length) { + if (markups.length && state.text.length && state.section.isMarkerable) { // create the marker started for this node this._createMarker(); } @@ -9426,17 +10192,41 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup var sections = this.sections; var state = this.state; + var lastSection = sections[sections.length - 1]; + if (!state.section) { return; } // close a trailing text node if it exists - if (state.text.length) { + if (state.text.length && state.section.isMarkerable) { this._createMarker(); } - sections.push(state.section); + // push listItems onto the listSection or add a new section + if (state.section.isListItem && lastSection && lastSection.isListSection) { + (0, _mobiledocKitParsersDom.trimSectionText)(state.section); + lastSection.items.append(state.section); + } else { + // avoid creating empty markup sections, especially useful for indented source + if (state.section.isMarkerable && !state.section.text.trim() && !(0, _mobiledocKitUtilsArrayUtils.any)(state.section.markers, function (marker) { + return marker.isAtom; + })) { + state.section = null; + state.text = ''; + return; + } + + // remove empty list sections before creating a new section + if (lastSection && lastSection.isListSection && lastSection.items.length === 0) { + sections.pop(); + } + + sections.push(state.section); + } + state.section = null; + state.text = ''; } }, { key: '_markupsFromElement', @@ -9640,10 +10430,12 @@ define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', ' switch (type) { case _mobiledocKitModelsTypes.LIST_SECTION_TYPE: - var item = this.builder.createListItem(markers); - var list = this.builder.createListSection(tagName, [item]); - section = list; - break; + { + var item = this.builder.createListItem(markers); + var list = this.builder.createListSection(tagName, [item]); + section = list; + break; + } case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE: section = this.builder.createMarkupSection(tagName, markers); break; @@ -9753,6 +10545,12 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c return element; } + function setSectionAttributesOnElement(section, element) { + section.eachAttribute(function (key, value) { + element.setAttribute(key, value); + }); + } + function renderMarkupSection(section) { var element = undefined; if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) { @@ -9762,11 +10560,17 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName); } + setSectionAttributesOnElement(section, element); + return element; } function renderListSection(section) { - return document.createElement(section.tagName); + var element = document.createElement(section.tagName); + + setSectionAttributesOnElement(section, element); + + return element; } function renderListItem() { @@ -10296,7 +11100,6 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c method = postNode.type; (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]); - // jshint -W083 this.visitor[method](renderNode, postNode, function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; @@ -10304,7 +11107,6 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c return _this2.visit.apply(_this2, [renderTree].concat(args)); }); - // jshint +W083 renderNode.markClean(); renderNode = this.nodes.shift(); } @@ -10575,6 +11377,150 @@ define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/uti } }; }); +define('mobiledoc-kit/renderers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { + 'use strict'; + + var _visitor; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + var MOBILEDOC_VERSION = '0.3.2'; + exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; + var MOBILEDOC_MARKUP_SECTION_TYPE = 1; + exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE; + var MOBILEDOC_IMAGE_SECTION_TYPE = 2; + exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE; + var MOBILEDOC_LIST_SECTION_TYPE = 3; + exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE; + var MOBILEDOC_CARD_SECTION_TYPE = 10; + + exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE; + var MOBILEDOC_MARKUP_MARKER_TYPE = 0; + exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE; + var MOBILEDOC_ATOM_MARKER_TYPE = 1; + + exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE; + var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) { + opcodes.push(['openPost']); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openMarkupSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openListSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) { + opcodes.push(['openListItem']); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openImageSection', node.src]); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) { + opcodes.push(['openCardSection', node.name, node.payload]); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) { + opcodes.push(['openMarker', node.closedMarkups.length, node.value]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) { + opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) { + opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes); + }), _visitor); + + var postOpcodeCompiler = { + openMarker: function openMarker(closeCount, value) { + this.markupMarkerIds = []; + this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']); + }, + openMarkupSection: function openMarkupSection(tagName, attributes) { + this.markers = []; + this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]); + }, + openListSection: function openListSection(tagName, attributes) { + this.items = []; + this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]); + }, + openListItem: function openListItem() { + this.markers = []; + this.items.push(this.markers); + }, + openImageSection: function openImageSection(url) { + this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]); + }, + openCardSection: function openCardSection(name, payload) { + var index = this._addCardTypeIndex(name, payload); + this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]); + }, + openAtom: function openAtom(closeCount, name, value, payload) { + var index = this._addAtomTypeIndex(name, value, payload); + this.markupMarkerIds = []; + this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]); + }, + openPost: function openPost() { + this.atomTypes = []; + this.cardTypes = []; + this.markerTypes = []; + this.sections = []; + this.result = { + version: MOBILEDOC_VERSION, + atoms: this.atomTypes, + cards: this.cardTypes, + markups: this.markerTypes, + sections: this.sections + }; + }, + openMarkup: function openMarkup(tagName, attributes) { + var index = this._findOrAddMarkerTypeIndex(tagName, attributes); + this.markupMarkerIds.push(index); + }, + _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) { + var cardType = [cardName, payload]; + this.cardTypes.push(cardType); + return this.cardTypes.length - 1; + }, + _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) { + var atomType = [atomName, atomValue, payload]; + this.atomTypes.push(atomType); + return this.atomTypes.length - 1; + }, + _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) { + if (!this._markerTypeCache) { + this._markerTypeCache = {}; + } + var key = tagName + '-' + attributesArray.join('-'); + + var index = this._markerTypeCache[key]; + if (index === undefined) { + var markerType = [tagName]; + if (attributesArray.length) { + markerType.push(attributesArray); + } + this.markerTypes.push(markerType); + + index = this.markerTypes.length - 1; + this._markerTypeCache[key] = index; + } + + return index; + } + }; + + /** + * Render from post -> mobiledoc + */ + exports['default'] = { + /** + * @param {Post} + * @return {Mobiledoc} + */ + render: function render(post) { + var opcodes = []; + (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes); + var compiler = Object.create(postOpcodeCompiler); + (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes); + return compiler.result; + } + }; +}); define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { 'use strict'; @@ -10719,10 +11665,10 @@ define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils } }; }); -define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) { 'use strict'; - var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION; + var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION; exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; exports['default'] = { @@ -10732,10 +11678,12 @@ define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers return _mobiledocKitRenderersMobiledoc02['default'].render(post); case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION: return _mobiledocKitRenderersMobiledoc03['default'].render(post); - case undefined: - case null: case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION: return _mobiledocKitRenderersMobiledoc031['default'].render(post); + case undefined: + case null: + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION: + return _mobiledocKitRenderersMobiledoc032['default'].render(post); default: (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false); } @@ -11285,7 +12233,9 @@ define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/d var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD; var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD; - var WORD_CHAR_REGEX = /\w|_|:/; + // generated via http://xregexp.com/ to cover chars that \w misses + // (new XRegExp('\\p{Alphabetic}|[0-9]|_|:')).toString() + var WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]|[0-9]|_|:/; function findParentSectionFromNode(renderTree, node) { var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) { @@ -11743,6 +12693,12 @@ define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/d sectionOffset += postNode.length; } position = new Position(section, sectionOffset); + } else if (offset >= elementNode.childNodes.length) { + + // This is to deal with how Firefox handles triple-click selections. + // See https://stackoverflow.com/a/21234837/1269194 for an + // explanation. + position = section.tailPosition(); } else { // The offset is 0 if the cursor is on a non-atom-wrapper element node // (e.g., a
    tag in a blank markup section) @@ -11934,8 +12890,10 @@ define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/curs case _mobiledocKitUtilsKey.DIRECTION.BACKWARD: return new Range(head.move(units), tail, currentDirection); default: - var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD; - return new Range(head, tail, newDirection).extend(units); + { + var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD; + return new Range(head, tail, newDirection).extend(units); + } } } @@ -11987,12 +12945,20 @@ define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/curs return !detectMarker(i); }; - var headMarker = head.section.markers.detect(firstNotMatchingDetect, head.marker, true); - headMarker = headMarker && headMarker.next || head.marker; + var headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true); + if (!headMarker && detectMarker(headSection.markers.head)) { + headMarker = headSection.markers.head; + } else { + headMarker = headMarker.next || head.marker; + } var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker)); var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker); - tailMarker = tailMarker && tailMarker.prev || tail.marker; + if (!tailMarker && detectMarker(headSection.markers.tail)) { + tailMarker = headSection.markers.tail; + } else { + tailMarker = tailMarker.prev || tail.marker; + } var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length); return headPosition.toRange(tailPosition, direction); @@ -12104,7 +13070,8 @@ define("mobiledoc-kit/utils/deprecate", ["exports"], function (exports) { var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; if (!conditional) { - console.log("[mobiledoc-kit] [DEPRECATED]: " + message); // jshint ignore:line + // eslint-disable-next-line no-console + console.log("[mobiledoc-kit] [DEPRECATED]: " + message); } } }); @@ -12353,6 +13320,24 @@ define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/str } } + function whenElementIsNotInDOM(element, callback) { + var isCanceled = false; + var observerFn = function observerFn() { + if (isCanceled) { + return; + } + if (!element.parentNode) { + callback(); + } else { + window.requestAnimationFrame(observerFn); + } + }; + observerFn(); + return { cancel: function cancel() { + return isCanceled = true; + } }; + } + exports.setData = setData; exports.getEventTargetMatchingTag = getEventTargetMatchingTag; exports.getElementRelativeOffset = getElementRelativeOffset; @@ -12360,6 +13345,7 @@ define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/str exports.positionElementToRect = positionElementToRect; exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect; exports.positionElementCenteredBelow = positionElementCenteredBelow; + exports.whenElementIsNotInDOM = whenElementIsNotInDOM; }); define('mobiledoc-kit/utils/environment', ['exports'], function (exports) { 'use strict'; @@ -12422,12 +13408,13 @@ define("mobiledoc-kit/utils/fixed-queue", ["exports"], function (exports) { exports["default"] = FixedQueue; }); -define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/keys', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKeys, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) { 'use strict'; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); exports.modifierMask = modifierMask; + exports.specialCharacterToCode = specialCharacterToCode; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -12481,7 +13468,10 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm DEL: _mobiledocKitUtilsKeycodes['default'].DELETE }; - exports.SPECIAL_KEYS = SPECIAL_KEYS; + function specialCharacterToCode(specialCharacter) { + return SPECIAL_KEYS[specialCharacter]; + } + // heuristic for determining if `event` is a key event function isKeyEvent(event) { return (/^key/.test(event.type) @@ -12497,6 +13487,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm function Key(event) { _classCallCheck(this, Key); + this.key = event.key; this.keyCode = event.keyCode; this.charCode = event.charCode; this.event = event; @@ -12511,20 +13502,38 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm } return String.fromCharCode(this.charCode); } + + // See https://caniuse.com/#feat=keyboardevent-key for browser support. + }, { + key: 'isKeySupported', + value: function isKeySupported() { + return this.key; + } + }, { + key: 'isKey', + value: function isKey(identifier) { + if (this.isKeySupported()) { + (0, _mobiledocKitUtilsAssert['default'])('Must define Keys.' + identifier + '.', _mobiledocKitUtilsKeys['default'][identifier]); + return this.key === _mobiledocKitUtilsKeys['default'][identifier]; + } else { + (0, _mobiledocKitUtilsAssert['default'])('Must define Keycodes.' + identifier + '.', _mobiledocKitUtilsKeycodes['default'][identifier]); + return this.keyCode === _mobiledocKitUtilsKeycodes['default'][identifier]; + } + } }, { key: 'isEscape', value: function isEscape() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ESC; + return this.isKey('ESC'); } }, { key: 'isDelete', value: function isDelete() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].BACKSPACE || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE; + return this.isKey('BACKSPACE') || this.isForwardDelete(); } }, { key: 'isForwardDelete', value: function isForwardDelete() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE; + return this.isKey('DELETE'); } }, { key: 'isArrow', @@ -12534,7 +13543,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isHorizontalArrow', value: function isHorizontalArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT || this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT; + return this.isLeftArrow() || this.isRightArrow(); } }, { key: 'isHorizontalArrowWithoutModifiersOtherThanShift', @@ -12544,56 +13553,75 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isVerticalArrow', value: function isVerticalArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].UP || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DOWN; + return this.isKey('UP') || this.isKey('DOWN'); } }, { key: 'isLeftArrow', value: function isLeftArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT; + return this.isKey('LEFT'); } }, { key: 'isRightArrow', value: function isRightArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT; + return this.isKey('RIGHT'); } }, { key: 'isHome', value: function isHome() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].HOME; + return this.isKey('HOME'); } }, { key: 'isEnd', value: function isEnd() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].END; + return this.isKey('END'); + } + }, { + key: 'isPageUp', + value: function isPageUp() { + return this.isKey('PAGEUP'); + } + }, { + key: 'isPageDown', + value: function isPageDown() { + return this.isKey('PAGEDOWN'); + } + }, { + key: 'isInsert', + value: function isInsert() { + return this.isKey('INS'); + } + }, { + key: 'isClear', + value: function isClear() { + return this.isKey('CLEAR'); + } + }, { + key: 'isPause', + value: function isPause() { + return this.isKey('PAUSE'); } }, { key: 'isSpace', value: function isSpace() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SPACE; + return this.isKey('SPACE'); } + + // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but + // it will also fire a keydown event for the tab+modifier (ctrl). This causes + // Mobiledoc to erroneously insert a tab character before FF switches to the + // new browser tab. Chrome doesn't fire this event so the issue doesn't + // arise there. Fix this by returning false when the TAB key event includes a + // modifier. + // See: https://github.com/bustle/mobiledoc-kit/issues/565 }, { key: 'isTab', value: function isTab() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].TAB; + return !this.hasAnyModifier() && this.isKey('TAB'); } }, { key: 'isEnter', value: function isEnter() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ENTER; - } - - /** - * If the shift key is depressed. - * For example, while holding down meta+shift, pressing the "v" - * key would result in an event whose `Key` had `isShift()` with a truthy value, - * because the shift key is down when pressing the "v". - * @see {isShiftKey} which checks if the key is actually the shift key itself. - * @return {bool} - */ - }, { - key: 'isShift', - value: function isShift() { - return this.shiftKey; + return this.isKey('ENTER'); } /* @@ -12605,7 +13633,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isShiftKey', value: function isShiftKey() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SHIFT; + return this.isKey('SHIFT'); } /* @@ -12616,7 +13644,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isAltKey', value: function isAltKey() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ALT; + return this.isKey('ALT'); } /* @@ -12627,7 +13655,28 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isCtrlKey', value: function isCtrlKey() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].CTRL; + return this.isKey('CTRL'); + } + }, { + key: 'isIME', + value: function isIME() { + // FIXME the IME action seems to get lost when we issue an + // `editor.deleteSelection` before it (in Chrome) + return this.keyCode === _mobiledocKitUtilsKeycodes['default'].IME; + } + }, { + key: 'isShift', + + /** + * If the shift key is depressed. + * For example, while holding down meta+shift, pressing the "v" + * key would result in an event whose `Key` had `isShift()` with a truthy value, + * because the shift key is down when pressing the "v". + * @see {isShiftKey} which checks if the key is actually the shift key itself. + * @return {bool} + */ + value: function isShift() { + return this.shiftKey; } }, { key: 'hasModifier', @@ -12640,33 +13689,60 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm return !!this.modifierMask; } }, { - key: 'isPrintable', + key: 'isPrintableKey', + value: function isPrintableKey() { + return !(this.isArrow() || this.isHome() || this.isEnd() || this.isPageUp() || this.isPageDown() || this.isInsert() || this.isClear() || this.isPause() || this.isEscape()); + } + }, { + key: 'isNumberKey', + value: function isNumberKey() { + if (this.isKeySupported()) { + return this.key >= '0' && this.key <= '9'; + } else { + var code = this.keyCode; + return code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9; // numpad keys + } + } + }, { + key: 'isLetterKey', + value: function isLetterKey() { + if (this.isKeySupported()) { + var key = this.key; + return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z'; + } else { + var code = this.keyCode; + return code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z; + } + } + }, { + key: 'isPunctuation', + value: function isPunctuation() { + if (this.isKeySupported()) { + var key = this.key; + return key >= ';' && key <= '`' || key >= '[' && key <= '"'; + } else { + var code = this.keyCode; + return code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['"']; + } + } /** * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position * and http://stackoverflow.com/a/12467610/137784 */ + }, { + key: 'isPrintable', value: function isPrintable() { if (this.ctrlKey || this.metaKey) { return false; } - var code = this.keyCode; - - // Firefox calls keypress events for arrow keys, but they should not be - // considered printable - if (this.isArrow()) { + // Firefox calls keypress events for some keys that should not be printable + if (!this.isPrintableKey()) { return false; } - return code !== 0 || this.toString().length > 0 || code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || // number keys - this.isSpace() || this.isTab() || this.isEnter() || code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || // letter keys - code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9 || // numpad keys - code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || // punctuation - code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['"'] || - // FIXME the IME action seems to get lost when we issue an `editor.deleteSelection` - // before it (in Chrome) - code === _mobiledocKitUtilsKeycodes['default'].IME; + return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME(); } }, { key: 'direction', @@ -12742,6 +13818,8 @@ define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) { IME: 229, TAB: 9, + CLEAR: 12, + PAUSE: 19, PAGEUP: 33, PAGEDOWN: 34, END: 35, @@ -12756,6 +13834,33 @@ define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) { CTRL: 17 }; }); +define('mobiledoc-kit/utils/keys', ['exports'], function (exports) { + 'use strict'; + + exports['default'] = { + BACKSPACE: 'Backspace', + SPACE: ' ', + ENTER: 'Enter', + SHIFT: 'Shift', + ESC: 'Escape', + DELETE: 'Delete', + INS: 'Insert', + HOME: 'Home', + END: 'End', + PAGEUP: 'PageUp', + PAGEDOWN: 'PageDown', + CLEAR: 'Clear', + PAUSE: 'Pause', + TAB: 'Tab', + ALT: 'Alt', + CTRL: 'Control', + + LEFT: 'ArrowLeft', + RIGHT: 'ArrowRight', + UP: 'ArrowUp', + DOWN: 'ArrowDown' + }; +}); define("mobiledoc-kit/utils/linked-item", ["exports"], function (exports) { "use strict"; @@ -12860,25 +13965,29 @@ define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/asser break; case 'middle': - var prevItem = nextItem.prev; - item.next = nextItem; - item.prev = prevItem; - nextItem.prev = item; - prevItem.next = item; + { + var prevItem = nextItem.prev; + item.next = nextItem; + item.prev = prevItem; + nextItem.prev = item; + prevItem.next = item; - break; + break; + } case 'end': - var tail = this.tail; - item.prev = tail; + { + var tail = this.tail; + item.prev = tail; - if (tail) { - tail.next = item; - } else { - this.head = item; - } - this.tail = item; + if (tail) { + tail.next = item; + } else { + this.head = item; + } + this.tail = item; - break; + break; + } } } }, { @@ -13310,6 +14419,23 @@ define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) { exports['default'] = MobiledocError; }); +define("mobiledoc-kit/utils/object-utils", ["exports"], function (exports) { + "use strict"; + + exports.entries = entries; + + function entries(obj) { + var ownProps = Object.keys(obj); + var i = ownProps.length; + var resArray = new Array(i); + + while (i--) { + resArray[i] = [ownProps[i], obj[ownProps[i]]]; + } + + return resArray; + } +}); define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) { /* global JSON */ 'use strict'; @@ -13530,6 +14656,7 @@ define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/k * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js * @return {Object} {node, offset} */ + /* eslint-disable complexity */ function findOffsetInNode(_x, _x2) { var _again = true; @@ -13587,6 +14714,7 @@ define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/k return { node: node, offset: offset }; } } + /* eslint-enable complexity */ function constrainNodeTo(node, parentNode, existingOffset) { var compare = parentNode.compareDocumentPosition(node); @@ -13840,7 +14968,7 @@ define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/r define('mobiledoc-kit/version', ['exports'], function (exports) { 'use strict'; - exports['default'] = '0.10.16'; + exports['default'] = '0.12.2'; }); define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) { 'use strict'; @@ -13880,6 +15008,9 @@ define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'm this.addEventListener(rootElement, 'mouseout', function (e) { clearTimeout(timeout); + if (_this.elementObserver) { + _this.elementObserver.cancel(); + } var toElement = e.toElement || e.relatedTarget; if (toElement && toElement.className !== _this.element.className) { _this.hide(); @@ -13898,8 +15029,13 @@ define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'm }, { key: 'showLink', value: function showLink(link, element) { + var _this2 = this; + var message = '' + link + ''; this.showMessage(message, element); + this.elementObserver = (0, _mobiledocKitUtilsElementUtils.whenElementIsNotInDOM)(element, function () { + return _this2.hide(); + }); } }]); @@ -14089,6 +15225,7 @@ define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-r case null: case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3: case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1: + case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_2: return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render(); default: throw new Error('Unexpected Mobiledoc version "' + version + '"'); @@ -14356,11 +15493,11 @@ define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-rend exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3; var MOBILEDOC_VERSION_0_3_1 = '0.3.1'; exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1; - var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_1; + var MOBILEDOC_VERSION_0_3_2 = '0.3.2'; - exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; + exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2; function validateVersion(version) { - if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1) { + if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1 && version !== MOBILEDOC_VERSION_0_3_2) { throw new Error('Unexpected Mobiledoc version "' + version + '"'); } } diff --git a/website/amd/mobiledoc-kit.map b/website/amd/mobiledoc-kit.map index b02184c16..85541c222 100644 --- a/website/amd/mobiledoc-kit.map +++ b/website/amd/mobiledoc-kit.map @@ -1 +1 @@ -{"version":3,"sources":["mobiledoc-dom-renderer/cards/image.js","mobiledoc-dom-renderer/index.js","mobiledoc-dom-renderer/renderer-factory.js","mobiledoc-dom-renderer/renderers/0-2.js","mobiledoc-dom-renderer/renderers/0-3.js","mobiledoc-dom-renderer/utils/array-utils.js","mobiledoc-dom-renderer/utils/dom.js","mobiledoc-dom-renderer/utils/marker-types.js","mobiledoc-dom-renderer/utils/render-type.js","mobiledoc-dom-renderer/utils/render-utils.js","mobiledoc-dom-renderer/utils/sanitization-utils.js","mobiledoc-dom-renderer/utils/section-types.js","mobiledoc-dom-renderer/utils/tag-names.js","mobiledoc-kit/cards/image.js","mobiledoc-kit/editor/edit-history.js","mobiledoc-kit/editor/edit-state.js","mobiledoc-kit/editor/editor.js","mobiledoc-kit/editor/event-manager.js","mobiledoc-kit/editor/key-commands.js","mobiledoc-kit/editor/mutation-handler.js","mobiledoc-kit/editor/post.js","mobiledoc-kit/editor/post/post-inserter.js","mobiledoc-kit/editor/selection-change-observer.js","mobiledoc-kit/editor/selection-manager.js","mobiledoc-kit/editor/text-input-handler.js","mobiledoc-kit/editor/text-input-handlers.js","mobiledoc-kit/editor/ui.js","mobiledoc-kit/index.js","mobiledoc-kit/models/_markerable.js","mobiledoc-kit/models/_section.js","mobiledoc-kit/models/atom-node.js","mobiledoc-kit/models/atom.js","mobiledoc-kit/models/card-node.js","mobiledoc-kit/models/card.js","mobiledoc-kit/models/image.js","mobiledoc-kit/models/lifecycle-callbacks.js","mobiledoc-kit/models/list-item.js","mobiledoc-kit/models/list-section.js","mobiledoc-kit/models/marker.js","mobiledoc-kit/models/markup-section.js","mobiledoc-kit/models/markup.js","mobiledoc-kit/models/post-node-builder.js","mobiledoc-kit/models/post.js","mobiledoc-kit/models/render-node.js","mobiledoc-kit/models/render-tree.js","mobiledoc-kit/models/types.js","mobiledoc-kit/parsers/dom.js","mobiledoc-kit/parsers/html.js","mobiledoc-kit/parsers/mobiledoc/0-2.js","mobiledoc-kit/parsers/mobiledoc/0-3-1.js","mobiledoc-kit/parsers/mobiledoc/0-3.js","mobiledoc-kit/parsers/mobiledoc/index.js","mobiledoc-kit/parsers/section.js","mobiledoc-kit/parsers/text.js","mobiledoc-kit/renderers/editor-dom.js","mobiledoc-kit/renderers/mobiledoc/0-2.js","mobiledoc-kit/renderers/mobiledoc/0-3-1.js","mobiledoc-kit/renderers/mobiledoc/0-3.js","mobiledoc-kit/renderers/mobiledoc/index.js","mobiledoc-kit/utils/array-utils.js","mobiledoc-kit/utils/assert.js","mobiledoc-kit/utils/browser.js","mobiledoc-kit/utils/characters.js","mobiledoc-kit/utils/compiler.js","mobiledoc-kit/utils/copy.js","mobiledoc-kit/utils/cursor.js","mobiledoc-kit/utils/cursor/position.js","mobiledoc-kit/utils/cursor/range.js","mobiledoc-kit/utils/deprecate.js","mobiledoc-kit/utils/dom-utils.js","mobiledoc-kit/utils/element-map.js","mobiledoc-kit/utils/element-utils.js","mobiledoc-kit/utils/environment.js","mobiledoc-kit/utils/fixed-queue.js","mobiledoc-kit/utils/key.js","mobiledoc-kit/utils/keycodes.js","mobiledoc-kit/utils/linked-item.js","mobiledoc-kit/utils/linked-list.js","mobiledoc-kit/utils/log-manager.js","mobiledoc-kit/utils/markuperable.js","mobiledoc-kit/utils/merge.js","mobiledoc-kit/utils/mixin.js","mobiledoc-kit/utils/mobiledoc-error.js","mobiledoc-kit/utils/parse-utils.js","mobiledoc-kit/utils/placeholder-image-src.js","mobiledoc-kit/utils/selection-utils.js","mobiledoc-kit/utils/set.js","mobiledoc-kit/utils/string-utils.js","mobiledoc-kit/utils/to-range.js","mobiledoc-kit/version.js","mobiledoc-kit/views/tooltip.js","mobiledoc-kit/views/view.js","mobiledoc-text-renderer/cards/image.js","mobiledoc-text-renderer/index.js","mobiledoc-text-renderer/renderer-factory.js","mobiledoc-text-renderer/renderers/0-2.js","mobiledoc-text-renderer/renderers/0-3.js","mobiledoc-text-renderer/utils/marker-types.js","mobiledoc-text-renderer/utils/render-type.js","mobiledoc-text-renderer/utils/section-types.js"],"sourcesContent":["define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: function render(_ref) {\n var payload = _ref.payload;\n var dom = _ref.env.dom;\n\n var img = dom.createElement('img');\n img.src = payload.src;\n return img;\n }\n };\n});","define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];\n\n function registerGlobal(window) {\n window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];\n }\n\n exports['default'] = _mobiledocDomRendererRendererFactory['default'];\n});","define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderers/0-2', 'mobiledoc-dom-renderer/renderers/0-3', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderers02, _mobiledocDomRendererRenderers03, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime DOM renderer\n * renders a mobiledoc to DOM\n *\n * input: mobiledoc\n * output: DOM\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be of type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var _ref$cards = _ref.cards;\n var cards = _ref$cards === undefined ? [] : _ref$cards;\n var _ref$atoms = _ref.atoms;\n var atoms = _ref$atoms === undefined ? [] : _ref$atoms;\n var _ref$cardOptions = _ref.cardOptions;\n var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n var _ref$markupElementRenderer = _ref.markupElementRenderer;\n var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer;\n var _ref$sectionElementRenderer = _ref.sectionElementRenderer;\n var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer;\n var dom = _ref.dom;\n var _ref$markupSanitizer = _ref.markupSanitizer;\n var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer;\n\n _classCallCheck(this, RendererFactory);\n\n validateCards(cards);\n validateAtoms(atoms);\n\n if (!dom) {\n if (typeof window === 'undefined') {\n throw new Error('A `dom` option must be provided to the renderer when running without window.document');\n }\n dom = window.document;\n }\n\n this.options = {\n cards: cards,\n atoms: atoms,\n cardOptions: cardOptions,\n unknownCardHandler: unknownCardHandler,\n unknownAtomHandler: unknownAtomHandler,\n markupElementRenderer: markupElementRenderer,\n sectionElementRenderer: sectionElementRenderer,\n dom: dom,\n markupSanitizer: markupSanitizer\n };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocDomRendererRenderers02.MOBILEDOC_VERSION:\n case undefined:\n case null:\n return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render();\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-dom-renderer/renderers/0-2', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, options) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = options.cards;\n var cardOptions = options.cardOptions;\n var unknownCardHandler = options.unknownCardHandler;\n var markupElementRenderer = options.markupElementRenderer;\n var sectionElementRenderer = options.sectionElementRenderer;\n var dom = options.dom;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var markerTypes = _sectionData[0];\n var sections = _sectionData[1];\n\n this.dom = dom;\n this.root = dom.createDocumentFragment();\n this.markerTypes = markerTypes;\n this.sections = sections;\n this.cards = cards;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n this._renderedChildNodes = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = [];\n var node = this.root.firstChild;\n while (node) {\n this._renderedChildNodes.push(node);\n node = node.nextSibling;\n }\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 3);\n\n var openTypes = _marker[0];\n var closeCount = _marker[1];\n var text = _marker[2];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, text));\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var name = _ref42[1];\n var payload = _ref42[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils', 'mobiledoc-dom-renderer/utils/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils, _mobiledocDomRendererUtilsMarkerTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION_0_3_0 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_0;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n switch (version) {\n case MOBILEDOC_VERSION_0_3_0:\n case MOBILEDOC_VERSION_0_3_1:\n return;\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var markupElementRenderer = state.markupElementRenderer;\n var sectionElementRenderer = state.sectionElementRenderer;\n var dom = state.dom;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n var markerTypes = mobiledoc.markups;\n\n validateVersion(version);\n\n this.dom = dom;\n this.root = this.dom.createDocumentFragment();\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.markerTypes = markerTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 4);\n\n var type = _marker[0];\n var openTypes = _marker[1];\n var closeCount = _marker[2];\n var value = _marker[3];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n switch (type) {\n case _mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, value));\n break;\n case _mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n currentElement.appendChild(this._renderAtom(value));\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var index = _ref42[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this5 = this;\n\n var env = {\n name: atom.name,\n isInEditor: false,\n dom: this.dom,\n onTeardown: function onTeardown(callback) {\n return _this5._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || (0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, '');\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref7) {\n var name = _ref7.env.name;\n\n throw new Error('Atom \"' + name + '\" not found but no unknownAtomHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-dom-renderer/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.includes = includes;\n\n function includes(array, detectValue) {\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n if (value === detectValue) {\n return true;\n }\n }\n return false;\n }\n});","define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) {\n 'use strict';\n\n exports.createTextNode = createTextNode;\n exports.normalizeTagName = normalizeTagName;\n function addHTMLSpaces(text) {\n var nbsp = ' ';\n return text.replace(/ /g, ' ' + nbsp);\n }\n\n function createTextNode(dom, text) {\n return dom.createTextNode(addHTMLSpaces(text));\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n});","define(\"mobiledoc-dom-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'dom';\n});","define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) {\n 'use strict';\n\n exports.defaultSectionElementRenderer = defaultSectionElementRenderer;\n exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer;\n\n function defaultSectionElementRenderer(tagName, dom) {\n var element = undefined;\n if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) {\n element = dom.createElement(tagName);\n } else {\n element = dom.createElement('div');\n element.setAttribute('class', tagName);\n }\n\n return element;\n }\n\n function sanitizeAttribute(tagName, attrName, attrValue) {\n if (tagName === 'a' && attrName === 'href') {\n return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attrValue);\n } else {\n return attrValue;\n }\n }\n\n function defaultMarkupElementRenderer(tagName, dom, attrsObj) {\n var element = dom.createElement(tagName);\n Object.keys(attrsObj).forEach(function (attrName) {\n var attrValue = attrsObj[attrName];\n attrValue = sanitizeAttribute(tagName, attrName, attrValue);\n element.setAttribute(attrName, attrValue);\n });\n return element;\n }\n});","define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {\n 'use strict';\n\n exports.sanitizeHref = sanitizeHref;\n exports.reduceAttributes = reduceAttributes;\n\n var PROTOCOL_REGEXP = /^([a-z0-9.+-]+:)/i;\n\n var badProtocols = ['javascript:', // jshint ignore:line\n 'vbscript:' // jshint ignore:line\n ];\n\n function getProtocol(url) {\n var matches = url && url.match(PROTOCOL_REGEXP);\n var protocol = matches && matches[0] || ':';\n return protocol;\n }\n\n function sanitizeHref(url) {\n var protocol = getProtocol(url);\n if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) {\n return 'unsafe:' + url;\n }\n return url;\n }\n\n /**\n * @param attributes array\n * @return obj with normalized attribute names (lowercased)\n */\n\n function reduceAttributes(attributes) {\n var obj = {};\n for (var i = 0; i < attributes.length; i += 2) {\n var key = attributes[i];\n var val = attributes[i + 1];\n obj[key.toLowerCase()] = val;\n }\n return obj;\n }\n});","define(\"mobiledoc-dom-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});","define('mobiledoc-dom-renderer/utils/tag-names', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsDom) {\n 'use strict';\n\n exports.isValidSectionTagName = isValidSectionTagName;\n exports.isMarkupSectionElementName = isMarkupSectionElementName;\n exports.isValidMarkerType = isValidMarkerType;\n\n var MARKUP_SECTION_TAG_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pull-quote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_SECTION_ELEMENT_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var LIST_SECTION_TAG_NAMES = ['ul', 'ol'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_TYPES = ['b', 'i', 'strong', 'em', 'a', 'u', 'sub', 'sup', 's', 'code'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function isValidSectionTagName(tagName, sectionType) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n\n switch (sectionType) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return contains(MARKUP_SECTION_TAG_NAMES, tagName);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return contains(LIST_SECTION_TAG_NAMES, tagName);\n default:\n throw new Error('Cannot validate tagName for unknown section type \"' + sectionType + '\"');\n }\n }\n\n function isMarkupSectionElementName(tagName) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n return contains(MARKUP_SECTION_ELEMENT_NAMES, tagName);\n }\n\n function isValidMarkerType(type) {\n type = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(type);\n return contains(MARKUP_TYPES, type);\n }\n});","define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder-image-src'], function (exports, _mobiledocKitUtilsPlaceholderImageSrc) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: 'dom',\n\n render: function render(_ref) {\n var env = _ref.env;\n var options = _ref.options;\n var payload = _ref.payload;\n\n var img = document.createElement('img');\n img.src = payload.src || _mobiledocKitUtilsPlaceholderImageSrc['default'];\n return img;\n }\n };\n});","define('mobiledoc-kit/editor/edit-history', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/utils/fixed-queue'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitUtilsFixedQueue) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function findLeafSectionAtIndex(post, index) {\n var section = undefined;\n post.walkAllLeafSections(function (_section, _index) {\n if (index === _index) {\n section = _section;\n }\n });\n return section;\n }\n\n var Snapshot = (function () {\n function Snapshot(takenAt, editor) {\n var editAction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n _classCallCheck(this, Snapshot);\n\n this.mobiledoc = editor.serialize();\n this.editor = editor;\n this.editAction = editAction;\n this.takenAt = takenAt;\n\n this.snapshotRange();\n }\n\n _createClass(Snapshot, [{\n key: 'snapshotRange',\n value: function snapshotRange() {\n var _editor = this.editor;\n var range = _editor.range;\n var cursor = _editor.cursor;\n\n if (cursor.hasCursor() && !range.isBlank) {\n var head = range.head;\n var tail = range.tail;\n\n this.range = {\n head: [head.leafSectionIndex, head.offset],\n tail: [tail.leafSectionIndex, tail.offset]\n };\n }\n }\n }, {\n key: 'getRange',\n value: function getRange(post) {\n if (this.range) {\n var _range = this.range;\n var head = _range.head;\n var tail = _range.tail;\n var _head = head;\n\n var _head2 = _slicedToArray(_head, 2);\n\n var headLeafSectionIndex = _head2[0];\n var headOffset = _head2[1];\n var _tail = tail;\n\n var _tail2 = _slicedToArray(_tail, 2);\n\n var tailLeafSectionIndex = _tail2[0];\n var tailOffset = _tail2[1];\n\n var headSection = findLeafSectionAtIndex(post, headLeafSectionIndex);\n var tailSection = findLeafSectionAtIndex(post, tailLeafSectionIndex);\n\n head = headSection.toPosition(headOffset);\n tail = tailSection.toPosition(tailOffset);\n\n return head.toRange(tail);\n }\n }\n }, {\n key: 'groupsWith',\n value: function groupsWith(groupingTimeout, editAction, takenAt) {\n return editAction !== null && this.editAction === editAction && this.takenAt + groupingTimeout > takenAt;\n }\n }]);\n\n return Snapshot;\n })();\n\n exports.Snapshot = Snapshot;\n\n var EditHistory = (function () {\n function EditHistory(editor, queueLength, groupingTimeout) {\n _classCallCheck(this, EditHistory);\n\n this.editor = editor;\n this._undoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n this._redoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n\n this._pendingSnapshot = null;\n this._groupingTimeout = groupingTimeout;\n }\n\n _createClass(EditHistory, [{\n key: 'snapshot',\n value: function snapshot() {\n // update the current snapshot with the range read from DOM\n if (this._pendingSnapshot) {\n this._pendingSnapshot.snapshotRange();\n }\n }\n }, {\n key: 'storeSnapshot',\n value: function storeSnapshot() {\n var editAction = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];\n\n var now = Date.now();\n // store pending snapshot\n var pendingSnapshot = this._pendingSnapshot;\n if (pendingSnapshot) {\n if (!pendingSnapshot.groupsWith(this._groupingTimeout, editAction, now)) {\n this._undoStack.push(pendingSnapshot);\n }\n this._redoStack.clear();\n }\n\n // take new pending snapshot to store next time `storeSnapshot` is called\n this._pendingSnapshot = new Snapshot(now, this.editor, editAction);\n }\n }, {\n key: 'stepBackward',\n value: function stepBackward(postEditor) {\n // Throw away the pending snapshot\n this._pendingSnapshot = null;\n\n var snapshot = this._undoStack.pop();\n if (snapshot) {\n this._redoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n }\n }, {\n key: 'stepForward',\n value: function stepForward(postEditor) {\n var snapshot = this._redoStack.pop();\n if (snapshot) {\n this._undoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n postEditor.cancelSnapshot();\n }\n }, {\n key: '_restoreFromSnapshot',\n value: function _restoreFromSnapshot(snapshot, postEditor) {\n var mobiledoc = snapshot.mobiledoc;\n var editor = this.editor;\n var builder = editor.builder;\n var post = editor.post;\n\n var restoredPost = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(restoredPost);\n\n // resurrect snapshotted range if it exists\n var newRange = snapshot.getRange(post);\n if (newRange) {\n postEditor.setRange(newRange);\n }\n }\n }]);\n\n return EditHistory;\n })();\n\n exports['default'] = EditHistory;\n});","define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * Used by {@link Editor} to manage its current state (cursor, active markups\n * and active sections).\n * @private\n */\n\n var EditState = (function () {\n function EditState(editor) {\n _classCallCheck(this, EditState);\n\n this.editor = editor;\n\n var defaultState = {\n range: _mobiledocKitUtilsCursorRange['default'].blankRange(),\n activeMarkups: [],\n activeSections: [],\n activeSectionTagNames: []\n };\n\n this.prevState = this.state = defaultState;\n }\n\n _createClass(EditState, [{\n key: 'updateRange',\n value: function updateRange(newRange) {\n this.prevState = this.state;\n this.state = this._readState(newRange);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.editor = null;\n this.prevState = this.state = null;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'rangeDidChange',\n value: function rangeDidChange() {\n var range = this.state.range;\n var prevRange = this.prevState.range;\n\n return !prevRange.isEqual(range);\n }\n\n /**\n * @return {Boolean} Whether the input mode (active markups or active section tag names)\n * has changed.\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange() {\n var state = this.state;\n var prevState = this.prevState;\n\n return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames);\n }\n\n /**\n * @return {Range}\n */\n }, {\n key: 'toggleMarkupState',\n\n /**\n * Update the editor's markup state. This is used when, e.g.,\n * a user types meta+B when the editor has a cursor but no selected text;\n * in this case the editor needs to track that it has an active \"b\" markup\n * and apply it to the next text the user types.\n */\n value: function toggleMarkupState(markup) {\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(this.activeMarkups, markup)) {\n this._removeActiveMarkup(markup);\n } else {\n this._addActiveMarkup(markup);\n }\n }\n }, {\n key: '_readState',\n value: function _readState(range) {\n var state = {\n range: range,\n activeMarkups: this._readActiveMarkups(range),\n activeSections: this._readActiveSections(range)\n };\n // Section objects are 'live', so to check that they changed, we\n // need to map their tagNames now (and compare to mapped tagNames later).\n // In addition, to catch changes from ul -> ol, we keep track of the\n // un-nested tag names (otherwise we'd only see li -> li change)\n state.activeSectionTagNames = state.activeSections.map(function (s) {\n return s.isNested ? s.parent.tagName : s.tagName;\n });\n return state;\n }\n }, {\n key: '_readActiveSections',\n value: function _readActiveSections(range) {\n var head = range.head;\n var tail = range.tail;\n var post = this.editor.post;\n\n if (range.isBlank) {\n return [];\n } else {\n return post.sections.readRange(head.section, tail.section);\n }\n }\n }, {\n key: '_readActiveMarkups',\n value: function _readActiveMarkups(range) {\n var post = this.editor.post;\n\n return post.markupsInRange(range);\n }\n }, {\n key: '_removeActiveMarkup',\n value: function _removeActiveMarkup(markup) {\n var index = this.state.activeMarkups.indexOf(markup);\n this.state.activeMarkups.splice(index, 1);\n }\n }, {\n key: '_addActiveMarkup',\n value: function _addActiveMarkup(markup) {\n this.state.activeMarkups.push(markup);\n }\n }, {\n key: 'range',\n get: function get() {\n return this.state.range;\n }\n\n /**\n * @return {Section[]}\n */\n }, {\n key: 'activeSections',\n get: function get() {\n return this.state.activeSections;\n }\n\n /**\n * @return {Markup[]}\n */\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this.state.activeMarkups;\n }\n }]);\n\n return EditState;\n })();\n\n exports['default'] = EditState;\n});","define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/element-utils', 'mobiledoc-kit/utils/cursor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/environment', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/text-input-handlers', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/editor/mutation-handler', 'mobiledoc-kit/editor/edit-history', 'mobiledoc-kit/editor/event-manager', 'mobiledoc-kit/editor/edit-state', 'mobiledoc-dom-renderer', 'mobiledoc-text-renderer', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/log-manager', 'mobiledoc-kit/utils/to-range', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitViewsTooltip, _mobiledocKitEditorPost, _mobiledocKitCardsImage, _mobiledocKitUtilsKey, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersDom, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree, _mobiledocKitRenderersMobiledoc, _mobiledocKitUtilsMerge, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsElementUtils, _mobiledocKitUtilsCursor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsEnvironment, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorTextInputHandlers, _mobiledocKitEditorKeyCommands, _mobiledocKitModelsCard, _mobiledocKitUtilsAssert, _mobiledocKitEditorMutationHandler, _mobiledocKitEditorEditHistory, _mobiledocKitEditorEventManager, _mobiledocKitEditorEditState, _mobiledocDomRenderer, _mobiledocTextRenderer, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsLogManager, _mobiledocKitUtilsToRange, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // This export may later be deprecated, but re-export it from the renderer here\n // for consumers that may depend on it.\n Object.defineProperty(exports, 'EDITOR_ELEMENT_CLASS_NAME', {\n enumerable: true,\n get: function get() {\n return _mobiledocKitRenderersEditorDom.EDITOR_ELEMENT_CLASS_NAME;\n }\n });\n\n var defaults = {\n placeholder: 'Write here...',\n spellcheck: true,\n autofocus: true,\n undoDepth: 5,\n undoBlockTimeout: 5000, // ms for an undo event\n cards: [],\n atoms: [],\n cardOptions: {},\n unknownCardHandler: function unknownCardHandler(_ref) {\n var env = _ref.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown card encountered: ' + env.name);\n },\n unknownAtomHandler: function unknownAtomHandler(_ref2) {\n var env = _ref2.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown atom encountered: ' + env.name);\n },\n mobiledoc: null,\n html: null\n };\n\n var CALLBACK_QUEUES = {\n DID_UPDATE: 'didUpdate',\n WILL_RENDER: 'willRender',\n DID_RENDER: 'didRender',\n WILL_DELETE: 'willDelete',\n DID_DELETE: 'didDelete',\n WILL_HANDLE_NEWLINE: 'willHandleNewline',\n CURSOR_DID_CHANGE: 'cursorDidChange',\n DID_REPARSE: 'didReparse',\n POST_DID_CHANGE: 'postDidChange',\n INPUT_MODE_DID_CHANGE: 'inputModeDidChange'\n };\n\n /**\n * The Editor is a core component of mobiledoc-kit. After instantiating\n * an editor, use {@link Editor#render} to display the editor on the web page.\n *\n * An editor uses a {@link Post} internally to represent the displayed document.\n * The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc\n * is the transportable \"over-the-wire\" format (JSON) that is suited for persisting\n * and sharing between editors and renderers (for display, e.g.), whereas the Post\n * model is better suited for programmatic editing.\n *\n * The editor will call registered callbacks for certain state changes. These are:\n * * {@link Editor#cursorDidChange} -- The cursor position or selection changed.\n * * {@link Editor#postDidChange} -- The contents of the post changed due to user input or\n * programmatic editing. This hook can be used with {@link Editor#serialize}\n * to auto-save a post as it is being edited.\n * * {@link Editor#inputModeDidChange} -- The active section(s) or markup(s) at the current cursor\n * position or selection have changed. This hook can be used with\n * {@link Editor#activeMarkups} and {@link Editor#activeSections} to implement\n * a custom toolbar.\n * * {@link Editor#onTextInput} -- Register callbacks when the user enters text\n * that matches a given string or regex.\n */\n\n var Editor = (function () {\n /**\n * @param {Object} [options]\n * @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.\n * Supersedes `options.html`.\n * @param {String|DOM} [options.html] The html (as a string or DOM fragment)\n * to parse and load into the editor.\n * Will be ignored if `options.mobiledoc` is also passed.\n * @param {Array} [options.parserPlugins=[]]\n * @param {Array} [options.cards=[]] The cards that the editor may render.\n * @param {Array} [options.atoms=[]] The atoms that the editor may render.\n * @param {Function} [options.unknownCardHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown card.\n * @param {Function} [options.unknownAtomHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown atom.\n * @param {String} [options.placeholder] Default text to show before user starts typing.\n * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck\n * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered.\n * @param {number} [options.undoDepth=5] How many undo levels will be available.\n * Set to 0 to disable undo/redo functionality.\n * @return {Editor}\n * @public\n */\n\n function Editor() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, Editor);\n\n (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType);\n this._views = [];\n this.isEditable = null;\n this._parserPlugins = options.parserPlugins || [];\n\n // FIXME: This should merge onto this.options\n (0, _mobiledocKitUtilsMerge.mergeWithOptions)(this, defaults, options);\n this.cards.push(_mobiledocKitCardsImage['default']);\n\n _mobiledocKitEditorKeyCommands.DEFAULT_KEY_COMMANDS.forEach(function (kc) {\n return _this.registerKeyCommand(kc);\n });\n\n this._logManager = new _mobiledocKitUtilsLogManager['default']();\n this._parser = new _mobiledocKitParsersDom['default'](this.builder);\n var cards = this.cards;\n var atoms = this.atoms;\n var unknownCardHandler = this.unknownCardHandler;\n var unknownAtomHandler = this.unknownAtomHandler;\n var cardOptions = this.cardOptions;\n\n this._renderer = new _mobiledocKitRenderersEditorDom['default'](this, cards, atoms, unknownCardHandler, unknownAtomHandler, cardOptions);\n\n this.post = this.loadPost();\n this._renderTree = new _mobiledocKitModelsRenderTree['default'](this.post);\n\n this._editHistory = new _mobiledocKitEditorEditHistory['default'](this, this.undoDepth, this.undoBlockTimeout);\n this._eventManager = new _mobiledocKitEditorEventManager['default'](this);\n this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this);\n this._editState = new _mobiledocKitEditorEditState['default'](this);\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) {\n return _this.onTextInput(handler);\n });\n\n this.hasRendered = false;\n }\n\n /**\n * Turns on verbose logging for the editor.\n * @param {Array} [logTypes=[]] If present, only the given log types will be logged.\n * @public\n */\n\n _createClass(Editor, [{\n key: 'enableLogging',\n value: function enableLogging() {\n var logTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n if (logTypes.length === 0) {\n this._logManager.enableAll();\n } else {\n this._logManager.enableTypes(logTypes);\n }\n }\n\n /**\n * Disable all logging\n * @public\n */\n }, {\n key: 'disableLogging',\n value: function disableLogging() {\n this._logManager.disable();\n }\n\n /**\n * @private\n */\n }, {\n key: 'loggerFor',\n value: function loggerFor(type) {\n return this._logManager['for'](type);\n }\n\n /**\n * The editor's instance of a post node builder.\n * @type {PostNodeBuilder}\n */\n }, {\n key: 'loadPost',\n value: function loadPost() {\n var mobiledoc = this.mobiledoc;\n var html = this.html;\n\n if (mobiledoc) {\n return _mobiledocKitParsersMobiledoc['default'].parse(this.builder, mobiledoc);\n } else if (html) {\n if (typeof html === 'string') {\n var options = { plugins: this._parserPlugins };\n return new _mobiledocKitParsersHtml['default'](this.builder, options).parse(this.html);\n } else {\n var dom = html;\n return this._parser.parse(dom);\n }\n } else {\n return this.builder.createPost();\n }\n }\n }, {\n key: 'rerender',\n value: function rerender() {\n var _this2 = this;\n\n var postRenderNode = this.post.renderNode;\n\n // if we haven't rendered this post's renderNode before, mark it dirty\n if (!postRenderNode.element) {\n (0, _mobiledocKitUtilsAssert['default'])('Must call `render` before `rerender` can be called', this.hasRendered);\n postRenderNode.element = this.element;\n postRenderNode.markDirty();\n }\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_RENDER);\n this._mutationHandler.suspendObservation(function () {\n _this2._renderer.render(_this2._renderTree);\n });\n this.runCallbacks(CALLBACK_QUEUES.DID_RENDER);\n }\n\n /**\n * @param {Element} element The DOM element to render into.\n * Its contents will be replaced by the editor's rendered post.\n * @public\n */\n }, {\n key: 'render',\n value: function render(element) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot render an editor twice. Use `rerender` to update the ' + 'rendering of an existing editor instance.', !this.hasRendered);\n\n element.spellcheck = this.spellcheck;\n\n (0, _mobiledocKitUtilsDomUtils.clearChildNodes)(element);\n\n this.element = element;\n\n if (this.isEditable === null) {\n this.enableEditing();\n }\n\n this._addTooltip();\n\n // A call to `run` will trigger the didUpdatePostCallbacks hooks with a\n // postEditor.\n this.run(function () {});\n\n // Only set `hasRendered` to true after calling `run` to ensure that\n // no cursorDidChange or other callbacks get fired before the editor is\n // done rendering\n this.hasRendered = true;\n this.rerender();\n\n this._mutationHandler.init();\n this._eventManager.init();\n\n if (this.autofocus) {\n this.selectRange(this.post.headPosition());\n }\n }\n }, {\n key: '_addTooltip',\n value: function _addTooltip() {\n this.addView(new _mobiledocKitViewsTooltip['default']({\n rootElement: this.element,\n showForTag: 'a'\n }));\n }\n }, {\n key: 'registerKeyCommand',\n\n /**\n * @param {Object} keyCommand The key command to register. It must specify a\n * modifier key (meta, ctrl, etc), a string representing the ascii key, and\n * a `run` method that will be passed the editor instance when the key command\n * is invoked\n * @public\n */\n value: function registerKeyCommand(rawKeyCommand) {\n var keyCommand = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)(rawKeyCommand);\n (0, _mobiledocKitUtilsAssert['default'])('Key Command is not valid', (0, _mobiledocKitEditorKeyCommands.validateKeyCommand)(keyCommand));\n this.keyCommands.unshift(keyCommand);\n }\n\n /**\n * @param {String} name If the keyCommand event has a name attribute it can be removed.\n * @public\n */\n }, {\n key: 'unregisterKeyCommands',\n value: function unregisterKeyCommands(name) {\n for (var i = this.keyCommands.length - 1; i > -1; i--) {\n var keyCommand = this.keyCommands[i];\n\n if (keyCommand.name === name) {\n this.keyCommands.splice(i, 1);\n }\n }\n }\n\n /**\n * Convenience for {@link PostEditor#deleteAtPosition}. Deletes and puts the\n * cursor in the new position.\n * @public\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position, direction, _ref3) {\n var unit = _ref3.unit;\n\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteAtPosition(position, direction, { unit: unit });\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * Convenience for {@link PostEditor#deleteRange}. Deletes and puts the\n * cursor in the new position.\n * @param {Range} range\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * @private\n */\n }, {\n key: 'performDelete',\n value: function performDelete() {\n var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? { direction: _mobiledocKitUtilsKey.DIRECTION.BACKWARD, unit: 'char' } : arguments[0];\n\n var direction = _ref4.direction;\n var unit = _ref4.unit;\n var range = this.range;\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_DELETE, [range, direction, unit]);\n if (range.isCollapsed) {\n this.deleteAtPosition(range.head, direction, { unit: unit });\n } else {\n this.deleteRange(range);\n }\n this.runCallbacks(CALLBACK_QUEUES.DID_DELETE, [range, direction, unit]);\n }\n }, {\n key: 'handleNewline',\n value: function handleNewline(event) {\n var _this3 = this;\n\n if (!this.hasCursor()) {\n return;\n }\n\n event.preventDefault();\n\n var range = this.range;\n\n this.run(function (postEditor) {\n var cursorSection = undefined;\n if (!range.isCollapsed) {\n var nextPosition = postEditor.deleteRange(range);\n cursorSection = nextPosition.section;\n if (cursorSection && cursorSection.isBlank) {\n postEditor.setRange(cursorSection.headPosition());\n return;\n }\n }\n\n // Above logic might delete redundant range, so callback must run after it.\n var defaultPrevented = false;\n var event = { preventDefault: function preventDefault() {\n defaultPrevented = true;\n } };\n _this3.runCallbacks(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, [event]);\n if (defaultPrevented) {\n return;\n }\n\n cursorSection = postEditor.splitSection(range.head)[1];\n postEditor.setRange(cursorSection.headPosition());\n });\n }\n\n /**\n * Notify the editor that the post did change, and run associated\n * callbacks.\n * @private\n */\n }, {\n key: '_postDidChange',\n value: function _postDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.POST_DID_CHANGE);\n }\n\n /**\n * Selects the given range or position. If given a collapsed range or a position, this positions the cursor\n * at the range's position. Otherwise a selection is created in the editor\n * surface encompassing the range.\n * @param {Range|Position} range\n */\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n this.cursor.selectRange(range);\n this.range = range;\n }\n }, {\n key: '_readRangeFromDOM',\n value: function _readRangeFromDOM() {\n this.range = this.cursor.offsets;\n }\n }, {\n key: 'setPlaceholder',\n value: function setPlaceholder(placeholder) {\n (0, _mobiledocKitUtilsElementUtils.setData)(this.element, 'placeholder', placeholder);\n }\n }, {\n key: '_reparsePost',\n value: function _reparsePost() {\n var post = this._parser.parse(this.element);\n this.run(function (postEditor) {\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(post);\n postEditor.setRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n });\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n }, {\n key: '_reparseSections',\n value: function _reparseSections() {\n var _this4 = this;\n\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var currentRange = undefined;\n sections.forEach(function (section) {\n _this4._parser.reparseSection(section, _this4._renderTree);\n });\n this._removeDetachedSections();\n\n if (this._renderTree.isDirty) {\n currentRange = this.range;\n }\n\n // force the current snapshot's range to remain the same rather than\n // rereading it from DOM after the new character is applied and the browser\n // updates the cursor position\n var range = this._editHistory._pendingSnapshot.range;\n this.run(function () {\n _this4._editHistory._pendingSnapshot.range = range;\n });\n this.rerender();\n if (currentRange) {\n this.selectRange(currentRange);\n }\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n\n // FIXME this should be able to be removed now -- if any sections are detached,\n // it's due to a bug in the code.\n }, {\n key: '_removeDetachedSections',\n value: function _removeDetachedSections() {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.post.sections, function (s) {\n return !s.renderNode.isAttached();\n }), function (s) {\n return s.renderNode.scheduleForRemoval();\n });\n }\n\n /**\n * The sections from the cursor's selection start to the selection end\n * @type {Section[]}\n */\n }, {\n key: 'detectMarkupInRange',\n value: function detectMarkupInRange(range, markupTagName) {\n var markups = this.post.markupsInRange(range);\n return (0, _mobiledocKitUtilsArrayUtils.detect)(markups, function (markup) {\n return markup.hasTag(markupTagName);\n });\n }\n\n /**\n * @type {Markup[]}\n * @public\n */\n }, {\n key: 'hasActiveMarkup',\n\n /**\n * @param {Markup|String} markup A markup instance, or a string (e.g. \"b\")\n * @return {boolean}\n */\n value: function hasActiveMarkup(markup) {\n var matchesFn = undefined;\n if (typeof markup === 'string') {\n (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(markup);\n matchesFn = function (m) {\n return m.tagName === tagName;\n };\n })();\n } else {\n matchesFn = function (m) {\n return m === markup;\n };\n }\n\n return !!(0, _mobiledocKitUtilsArrayUtils.detect)(this.activeMarkups, matchesFn);\n }\n\n /**\n * @param {String} version The mobiledoc version to serialize to.\n * @return {Mobiledoc} Serialized mobiledoc\n * @public\n */\n }, {\n key: 'serialize',\n value: function serialize() {\n var version = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION : arguments[0];\n\n return this.serializePost(this.post, 'mobiledoc', { version: version });\n }\n\n /**\n * Serialize the editor's post to the requested format.\n * Note that only mobiledoc format is lossless. If cards or atoms are present\n * in the post, the html and text formats will omit them in output because\n * the editor does not have access to the html and text versions of the\n * cards/atoms.\n * @param {string} format The format to serialize ('mobiledoc', 'text', 'html')\n * @return {Object|String} The editor's post, serialized to {format}\n * @public\n */\n }, {\n key: 'serializeTo',\n value: function serializeTo(format) {\n var post = this.post;\n return this.serializePost(post, format);\n }\n\n /**\n * @param {Post}\n * @param {String} format Same as {serializeTo}\n * @param {Object} [options]\n * @param {String} [options.version=MOBILEDOC_VERSION] version to serialize to\n * @return {Object|String}\n * @private\n */\n }, {\n key: 'serializePost',\n value: function serializePost(post, format) {\n var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var validFormats = ['mobiledoc', 'html', 'text'];\n (0, _mobiledocKitUtilsAssert['default'])('Unrecognized serialization format ' + format, (0, _mobiledocKitUtilsArrayUtils.contains)(validFormats, format));\n\n if (format === 'mobiledoc') {\n var version = options.version || _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n return _mobiledocKitRenderersMobiledoc['default'].render(post, version);\n } else {\n var rendered = undefined;\n var mobiledoc = this.serializePost(post, 'mobiledoc');\n var unknownCardHandler = function unknownCardHandler() {};\n var unknownAtomHandler = function unknownAtomHandler() {};\n var rendererOptions = { unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n\n switch (format) {\n case 'html':\n var result = undefined;\n if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) {\n rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc);\n result = '
    ' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
    ';\n } else {\n // Fallback to text serialization\n result = this.serializePost(post, 'text', options);\n }\n return result;\n case 'text':\n rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc);\n return rendered.result;\n }\n }\n }\n }, {\n key: 'addView',\n value: function addView(view) {\n this._views.push(view);\n }\n }, {\n key: 'removeAllViews',\n value: function removeAllViews() {\n this._views.forEach(function (v) {\n return v.destroy();\n });\n this._views = [];\n }\n\n /**\n * Whether the editor has a cursor (or a selected range).\n * It is possible for the editor to be focused but not have a selection.\n * In this case, key events will fire but the editor will not be able to\n * determine a cursor position, so they will be ignored.\n * @return {boolean}\n * @public\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.cursor.hasCursor();\n }\n\n /**\n * Tears down the editor's attached event listeners and views.\n * @public\n */\n }, {\n key: 'destroy',\n value: function destroy() {\n this.isDestroyed = true;\n if (this._hasSelection()) {\n this.cursor.clearSelection();\n }\n if (this._hasFocus()) {\n this.element.blur(); // FIXME This doesn't blur the element on IE11\n }\n this._mutationHandler.destroy();\n this._eventManager.destroy();\n this.removeAllViews();\n this._renderer.destroy();\n this._editState.destroy();\n }\n\n /**\n * Keep the user from directly editing the post using the keyboard and mouse.\n * Modification via the programmatic API is still permitted.\n * @see Editor#enableEditing\n * @public\n */\n }, {\n key: 'disableEditing',\n value: function disableEditing() {\n if (this.isEditable === false) {\n return;\n }\n\n this.isEditable = false;\n if (this.hasRendered) {\n this.element.setAttribute('contentEditable', false);\n this.setPlaceholder('');\n this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n }\n }\n\n /**\n * Allow the user to directly interact with editing a post via keyboard and mouse input.\n * Editor instances are editable by default. Use this method to re-enable\n * editing after disabling it.\n * @see Editor#disableEditing\n * @public\n */\n }, {\n key: 'enableEditing',\n value: function enableEditing() {\n this.isEditable = true;\n if (this.element) {\n this.element.setAttribute('contentEditable', true);\n this.setPlaceholder(this.placeholder);\n }\n }\n\n /**\n * Change a cardSection into edit mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in edit mode when it gets rendered.\n * @param {CardSection} cardSection\n * @public\n */\n }, {\n key: 'editCard',\n value: function editCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.EDIT);\n }\n\n /**\n * Change a cardSection into display mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in display mode when it gets rendered.\n * @param {CardSection} cardSection\n * @return undefined\n * @public\n */\n }, {\n key: 'displayCard',\n value: function displayCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.DISPLAY);\n }\n\n /**\n * Run a new post editing session. Yields a block with a new {@link PostEditor}\n * instance. This instance can be used to interact with the post abstract.\n * Rendering will be deferred until after the callback is completed.\n *\n * Usage:\n * ```\n * let markerRange = this.range;\n * editor.run((postEditor) => {\n * postEditor.deleteRange(markerRange);\n * // editing surface not updated yet\n * postEditor.schedule(() => {\n * console.log('logs during rerender flush');\n * });\n * // logging not yet flushed\n * });\n * // editing surface now updated.\n * // logging now flushed\n * ```\n *\n * @param {Function} callback Called with an instance of\n * {@link PostEditor} as its argument.\n * @return {Mixed} The return value of `callback`.\n * @public\n */\n }, {\n key: 'run',\n value: function run(callback) {\n var postEditor = new _mobiledocKitEditorPost['default'](this);\n postEditor.begin();\n this._editHistory.snapshot();\n var result = callback(postEditor);\n this.runCallbacks(CALLBACK_QUEUES.DID_UPDATE, [postEditor]);\n postEditor.complete();\n this._readRangeFromDOM();\n\n if (postEditor._shouldCancelSnapshot) {\n this._editHistory._pendingSnapshot = null;\n }\n this._editHistory.storeSnapshot(postEditor.editActionTaken);\n\n return result;\n }\n\n /**\n * @param {Function} callback Called with `postEditor` as its argument.\n * @public\n */\n }, {\n key: 'didUpdatePost',\n value: function didUpdatePost(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_UPDATE, callback);\n }\n\n /**\n * @param {Function} callback Called when the post has changed, either via\n * user input or programmatically. Use with {@link Editor#serialize} to\n * retrieve the post in portable mobiledoc format.\n */\n }, {\n key: 'postDidChange',\n value: function postDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.POST_DID_CHANGE, callback);\n }\n\n /**\n * Register a handler that will be invoked by the editor after the user enters\n * matching text.\n * @param {Object} inputHandler\n * @param {String} inputHandler.name Required. Used by identifying handlers.\n * @param {String} [inputHandler.text] Required if `match` is not provided\n * @param {RegExp} [inputHandler.match] Required if `text` is not provided\n * @param {Function} inputHandler.run This callback is invoked with the {@link Editor}\n * instance and an array of matches. If `text` was provided,\n * the matches array will equal [`text`], and if a `match`\n * regex was provided the matches array will be the result of\n * `match.exec` on the matching text. The callback is called\n * after the matching text has been inserted.\n * @public\n */\n }, {\n key: 'onTextInput',\n value: function onTextInput(inputHandler) {\n this._eventManager.registerInputHandler(inputHandler);\n }\n\n /**\n * Unregister all text input handlers\n *\n * @public\n */\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._eventManager.unregisterAllTextInputHandlers();\n }\n\n /**\n * Unregister text input handler by name\n * @param {String} name The name of handler to be removed\n *\n * @public\n */\n }, {\n key: 'unregisterTextInputHandler',\n value: function unregisterTextInputHandler(name) {\n this._eventManager.unregisterInputHandler(name);\n }\n\n /**\n * @param {Function} callback Called when the editor's state (active markups or\n * active sections) has changed, either via user input or programmatically\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'willRender',\n value: function willRender(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'didRender',\n value: function didRender(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before deleting.\n * @public\n */\n }, {\n key: 'willDelete',\n value: function willDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after deleting.\n * @public\n */\n }, {\n key: 'didDelete',\n value: function didDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before handling new line.\n * @public\n */\n }, {\n key: 'willHandleNewline',\n value: function willHandleNewline(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called every time the cursor\n * position (or selection) changes.\n * @public\n */\n }, {\n key: 'cursorDidChange',\n value: function cursorDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.CURSOR_DID_CHANGE, callback);\n }\n }, {\n key: '_rangeDidChange',\n value: function _rangeDidChange() {\n if (this.hasRendered) {\n this.runCallbacks(CALLBACK_QUEUES.CURSOR_DID_CHANGE);\n }\n }\n }, {\n key: '_inputModeDidChange',\n value: function _inputModeDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE);\n }\n }, {\n key: '_insertEmptyMarkupSectionAtCursor',\n value: function _insertEmptyMarkupSectionAtCursor() {\n var _this5 = this;\n\n this.run(function (postEditor) {\n var section = postEditor.builder.createMarkupSection('p');\n postEditor.insertSectionBefore(_this5.post.sections, section);\n postEditor.setRange(section.toRange());\n });\n }\n\n /**\n * Toggles the given markup at the editor's current {@link Range}.\n * If the range is collapsed this changes the editor's state so that the\n * next characters typed will be affected. If there is text selected\n * (aka a non-collapsed range), the selections' markup will be toggled.\n * If the editor is not focused and has no active range, nothing happens.\n * @param {String} markup E.g. \"b\", \"em\", \"a\"\n * @public\n * @see PostEditor#toggleMarkup\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markup) {\n markup = this.builder.createMarkup(markup);\n var range = this.range;\n\n if (range.isCollapsed) {\n this._editState.toggleMarkupState(markup);\n this._inputModeDidChange();\n\n // when clicking a button to toggle markup, the button can end up being focused,\n // so ensure the editor is focused\n this._ensureFocus();\n } else {\n this.run(function (postEditor) {\n return postEditor.toggleMarkup(markup, range);\n });\n }\n }\n\n // If the editor has a selection but is not focused, focus it\n }, {\n key: '_ensureFocus',\n value: function _ensureFocus() {\n if (this._hasSelection() && !this._hasFocus()) {\n this.focus();\n }\n }\n }, {\n key: 'focus',\n value: function focus() {\n this.element.focus();\n }\n\n /**\n * Whether there is a selection inside the editor's element.\n * It's possible to have a selection but not have focus.\n * @see #_hasFocus\n * @return {Boolean}\n */\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var cursor = this.cursor;\n\n return this.hasRendered && (cursor._hasCollapsedSelection() || cursor._hasSelection());\n }\n\n /**\n * Whether the editor's element is focused\n * It's possible to be focused but have no selection\n * @see #_hasSelection\n * @return {Boolean}\n */\n }, {\n key: '_hasFocus',\n value: function _hasFocus() {\n return document.activeElement === this.element;\n }\n\n /**\n * Toggles the tagName for the current active section(s). This will skip\n * non-markerable sections. E.g. if the editor's range includes a \"P\" MarkupSection\n * and a CardSection, only the MarkupSection will be toggled.\n * @param {String} tagName The new tagname to change to.\n * @public\n * @see PostEditor#toggleSection\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(tagName) {\n var _this6 = this;\n\n this.run(function (postEditor) {\n return postEditor.toggleSection(tagName, _this6.range);\n });\n }\n\n /**\n * Finds and runs the first matching key command for the event\n *\n * If multiple commands are bound to a key combination, the\n * first matching one is run.\n *\n * If a command returns `false` then the next matching command\n * is run instead.\n *\n * @param {Event} event The keyboard event triggered by the user\n * @return {Boolean} true when a command was successfully run\n * @private\n */\n }, {\n key: 'handleKeyCommand',\n value: function handleKeyCommand(event) {\n var keyCommands = (0, _mobiledocKitEditorKeyCommands.findKeyCommands)(this.keyCommands, event);\n for (var i = 0; i < keyCommands.length; i++) {\n var keyCommand = keyCommands[i];\n if (keyCommand.run(this) !== false) {\n event.preventDefault();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Inserts the text at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n *\n * @param {String} text\n * @public\n */\n }, {\n key: 'insertText',\n value: function insertText(text) {\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n var activeMarkups = this.activeMarkups;\n var range = this.range;\n var position = this.range.head;\n\n this.run(function (postEditor) {\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertTextWithMarkup(position, text, activeMarkups);\n });\n }\n\n /**\n * Inserts an atom at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n * @param {String} atomName\n * @param {String} [atomText='']\n * @param {Object} [atomPayload={}]\n * @return {Atom} The inserted atom.\n * @public\n */\n }, {\n key: 'insertAtom',\n value: function insertAtom(atomName) {\n var atomText = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var atomPayload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var atom = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.head;\n\n atom = postEditor.builder.createAtom(atomName, atomText, atomPayload);\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertMarkers(position, [atom]);\n });\n return atom;\n }\n\n /**\n * Inserts a card at the section after the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion. If the cursor is in\n * a blank section, it will be replaced with a card section.\n * The editor's cursor will be placed at the end of the inserted card.\n * @param {String} cardName\n * @param {Object} [cardPayload={}]\n * @param {Boolean} [inEditMode=false] Whether the card should be inserted in edit mode.\n * @return {Card} The inserted Card section.\n * @public\n */\n }, {\n key: 'insertCard',\n value: function insertCard(cardName) {\n var _this7 = this;\n\n var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var card = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.tail;\n card = postEditor.builder.createCardSection(cardName, cardPayload);\n if (inEditMode) {\n _this7.editCard(card);\n }\n\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n var section = position.section;\n if (section.isNested) {\n section = section.parent;\n }\n\n if (section.isBlank) {\n postEditor.replaceSection(section, card);\n } else {\n var collection = _this7.post.sections;\n postEditor.insertSectionBefore(collection, card, section.next);\n }\n\n // It is important to explicitly set the range to the end of the card.\n // Otherwise it is possible to create an inconsistent state in the\n // browser. For instance, if the user clicked a button that\n // called `editor.insertCard`, the editor surface may retain\n // the selection but lose focus, and the next keystroke by the user\n // will cause an unexpected DOM mutation (which can wipe out the\n // card).\n // See: https://github.com/bustle/mobiledoc-kit/issues/286\n postEditor.setRange(card.tailPosition());\n });\n return card;\n }\n\n /**\n * @param {integer} x x-position in viewport\n * @param {integer} y y-position in viewport\n * @return {Position|null}\n */\n }, {\n key: 'positionAtPoint',\n value: function positionAtPoint(x, y) {\n return _mobiledocKitUtilsCursorPosition['default'].atPoint(x, y, this);\n }\n\n /**\n * @private\n */\n }, {\n key: '_setCardMode',\n value: function _setCardMode(cardSection, mode) {\n var renderNode = cardSection.renderNode;\n if (renderNode && renderNode.isRendered) {\n var cardNode = renderNode.cardNode;\n cardNode[mode]();\n } else {\n cardSection.setInitialMode(mode);\n }\n }\n }, {\n key: 'triggerEvent',\n value: function triggerEvent(context, eventName, event) {\n this._eventManager._trigger(context, eventName, event);\n }\n }, {\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n if (this.isDestroyed) {\n // TODO warn that callback attempted after editor was destroyed\n return;\n }\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n }, {\n key: 'builder',\n get: function get() {\n if (!this._builder) {\n this._builder = new _mobiledocKitModelsPostNodeBuilder['default']();\n }\n return this._builder;\n }\n }, {\n key: 'keyCommands',\n get: function get() {\n if (!this._keyCommands) {\n this._keyCommands = [];\n }\n return this._keyCommands;\n }\n }, {\n key: 'cursor',\n get: function get() {\n return new _mobiledocKitUtilsCursor['default'](this);\n }\n\n /**\n * Return the current range for the editor (may be cached).\n * @return {Range}\n */\n }, {\n key: 'range',\n get: function get() {\n return this._editState.range;\n },\n set: function set(newRange) {\n this._editState.updateRange(newRange);\n\n if (this._editState.rangeDidChange()) {\n this._rangeDidChange();\n }\n\n if (this._editState.inputModeDidChange()) {\n this._inputModeDidChange();\n }\n }\n }, {\n key: 'activeSections',\n get: function get() {\n return this._editState.activeSections;\n }\n }, {\n key: 'activeSection',\n get: function get() {\n var activeSections = this.activeSections;\n\n return activeSections[activeSections.length - 1];\n }\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this._editState.activeMarkups;\n }\n }]);\n\n return Editor;\n })();\n\n exports['default'] = Editor;\n});","define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/parse-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/editor/text-input-handler', 'mobiledoc-kit/editor/selection-manager', 'mobiledoc-kit/utils/browser'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitUtilsParseUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitEditorTextInputHandler, _mobiledocKitEditorSelectionManager, _mobiledocKitUtilsBrowser) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var ELEMENT_EVENT_TYPES = ['keydown', 'keyup', 'cut', 'copy', 'paste', 'keypress', 'drop'];\n\n var EventManager = (function () {\n function EventManager(editor) {\n _classCallCheck(this, EventManager);\n\n this.editor = editor;\n this.logger = editor.loggerFor('event-manager');\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor);\n this._listeners = [];\n this.modifierKeys = {\n shift: false,\n alt: false,\n ctrl: false\n };\n\n this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this));\n }\n\n _createClass(EventManager, [{\n key: 'init',\n value: function init() {\n var _this = this;\n\n var element = this.editor.element;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot init EventManager without element', !!element);\n\n ELEMENT_EVENT_TYPES.forEach(function (type) {\n _this._addListener(element, type);\n });\n\n this._selectionManager.start();\n }\n }, {\n key: 'registerInputHandler',\n value: function registerInputHandler(inputHandler) {\n this._textInputHandler.register(inputHandler);\n }\n }, {\n key: 'unregisterInputHandler',\n value: function unregisterInputHandler(name) {\n this._textInputHandler.unregister(name);\n }\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._textInputHandler.destroy();\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](this.editor);\n }\n }, {\n key: '_addListener',\n value: function _addListener(context, type) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Missing listener for ' + type, !!this[type]);\n\n var listener = function listener(event) {\n return _this2._handleEvent(type, event);\n };\n context.addEventListener(type, listener);\n this._listeners.push([context, type, listener]);\n }\n }, {\n key: '_removeListeners',\n value: function _removeListeners() {\n this._listeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var context = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n context.removeEventListener(type, listener);\n });\n this._listeners = [];\n }\n\n // This is primarily useful for programmatically simulating events on the\n // editor from the tests.\n }, {\n key: '_trigger',\n value: function _trigger(context, type, event) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this._listeners, function (_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var _context = _ref32[0];\n var _type = _ref32[1];\n\n return _context === context && _type === type;\n }), function (_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var context = _ref42[0];\n var type = _ref42[1];\n var listener = _ref42[2];\n\n listener.call(context, event);\n });\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._textInputHandler.destroy();\n this._selectionManager.destroy();\n this._removeListeners();\n }\n }, {\n key: '_handleEvent',\n value: function _handleEvent(type, event) {\n var element = event.target;\n\n if (!this.isElementAddressable(element)) {\n // abort handling this event\n return true;\n }\n\n this[type](event);\n }\n }, {\n key: 'isElementAddressable',\n value: function isElementAddressable(element) {\n return this.editor.cursor.isAddressable(element);\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange(selection /*, prevSelection */) {\n var shouldNotify = true;\n var anchorNode = selection.anchorNode;\n\n if (!this.isElementAddressable(anchorNode)) {\n if (!this.editor.range.isBlank) {\n // Selection changed from something addressable to something\n // not-addressable -- e.g., blur event, user clicked outside editor,\n // etc\n shouldNotify = true;\n } else {\n // selection changes wholly outside the editor should not trigger\n // change notifications\n shouldNotify = false;\n }\n }\n\n if (shouldNotify) {\n this.editor._readRangeFromDOM();\n }\n }\n }, {\n key: 'keypress',\n value: function keypress(event) {\n var editor = this.editor;\n var _textInputHandler = this._textInputHandler;\n\n if (!editor.hasCursor()) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n if (!key.isPrintable()) {\n return;\n } else {\n event.preventDefault();\n }\n\n _textInputHandler.handle(key.toString());\n }\n }, {\n key: 'keydown',\n value: function keydown(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n if (!editor.isEditable) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: true });\n\n if (editor.handleKeyCommand(event)) {\n return;\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var range = editor.range;\n\n switch (true) {\n // FIXME This should be restricted to only card/atom boundaries\n case key.isHorizontalArrowWithoutModifiersOtherThanShift():\n var newRange = undefined;\n if (key.isShift()) {\n newRange = range.extend(key.direction * 1);\n } else {\n newRange = range.move(key.direction);\n }\n\n editor.selectRange(newRange);\n event.preventDefault();\n break;\n case key.isDelete():\n var direction = key.direction;\n\n var unit = 'char';\n if (this.modifierKeys.alt && _mobiledocKitUtilsBrowser['default'].isMac()) {\n unit = 'word';\n } else if (this.modifierKeys.ctrl && _mobiledocKitUtilsBrowser['default'].isWin()) {\n unit = 'word';\n }\n editor.performDelete({ direction: direction, unit: unit });\n event.preventDefault();\n break;\n case key.isEnter():\n editor.handleNewline(event);\n break;\n case key.isTab():\n // Handle tab here because it does not fire a `keypress` event\n event.preventDefault();\n this._textInputHandler.handle(key.toString());\n break;\n }\n }\n }, {\n key: 'keyup',\n value: function keyup(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: false });\n }\n }, {\n key: 'cut',\n value: function cut(event) {\n event.preventDefault();\n\n this.copy(event);\n this.editor.performDelete();\n }\n }, {\n key: 'copy',\n value: function copy(event) {\n event.preventDefault();\n\n var editor = this.editor;\n var _editor = this.editor;\n var range = _editor.range;\n var post = _editor.post;\n\n post = post.trimTo(range);\n\n var data = {\n html: editor.serializePost(post, 'html'),\n text: editor.serializePost(post, 'text'),\n mobiledoc: editor.serializePost(post, 'mobiledoc')\n };\n\n (0, _mobiledocKitUtilsParseUtils.setClipboardData)(event, data, window);\n }\n }, {\n key: 'paste',\n value: function paste(event) {\n event.preventDefault();\n\n var editor = this.editor;\n\n var range = editor.range;\n\n if (!range.isCollapsed) {\n editor.performDelete();\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var position = editor.range.head;\n var targetFormat = this.modifierKeys.shift ? 'text' : 'html';\n var pastedPost = (0, _mobiledocKitUtilsParseUtils.parsePostFromPaste)(event, editor, { targetFormat: targetFormat });\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, pastedPost);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: 'drop',\n value: function drop(event) {\n event.preventDefault();\n\n var x = event.clientX;\n var y = event.clientY;\n var editor = this.editor;\n\n var position = editor.positionAtPoint(x, y);\n if (!position) {\n this.logger.log('Could not find drop position');\n return;\n }\n\n var post = (0, _mobiledocKitUtilsParseUtils.parsePostFromDrop)(event, editor, { logger: this.logger });\n if (!post) {\n this.logger.log('Could not determine post from drop event');\n return;\n }\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, post);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: '_updateModifiersFromKey',\n value: function _updateModifiersFromKey(key, _ref5) {\n var isDown = _ref5.isDown;\n\n if (key.isShiftKey()) {\n this.modifierKeys.shift = isDown;\n } else if (key.isAltKey()) {\n this.modifierKeys.alt = isDown;\n } else if (key.isCtrlKey()) {\n this.modifierKeys.ctrl = isDown;\n }\n }\n }]);\n\n return EventManager;\n })();\n\n exports['default'] = EventManager;\n});","define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/browser', 'mobiledoc-kit/editor/ui'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsBrowser, _mobiledocKitEditorUi) {\n 'use strict';\n\n exports.buildKeyCommand = buildKeyCommand;\n exports.validateKeyCommand = validateKeyCommand;\n exports.findKeyCommands = findKeyCommands;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function selectAll(editor) {\n var post = editor.post;\n\n editor.selectRange(post.toRange());\n }\n\n function gotoStartOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.headPosition());\n });\n }\n\n function gotoEndOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.tailPosition());\n });\n }\n\n function deleteToEndOfSection(editor) {\n var range = editor.range;\n\n if (range.isCollapsed) {\n var _range = range;\n var head = _range.head;\n var section = _range.head.section;\n\n range = head.toRange(section.tailPosition());\n }\n editor.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n var DEFAULT_KEY_COMMANDS = [{\n str: 'META+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'CTRL+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'META+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'CTRL+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'META+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+K',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return deleteToEndOfSection(editor);\n } else if (_mobiledocKitUtilsBrowser['default'].isWin()) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n }\n }, {\n str: 'CTRL+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoStartOfLine(editor);\n } else {\n selectAll(editor);\n }\n }\n }, {\n str: 'META+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n selectAll(editor);\n }\n }\n }, {\n str: 'CTRL+E',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoEndOfLine(editor);\n }\n }\n }, {\n str: 'META+K',\n run: function run(editor) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n\n }, {\n str: 'META+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.undoLastChange();\n });\n }\n }, {\n str: 'META+SHIFT+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.redoLastChange();\n });\n }\n }, {\n str: 'CTRL+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.undoLastChange();\n });\n }\n }, {\n str: 'CTRL+SHIFT+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.redoLastChange();\n });\n }\n }];\n\n exports.DEFAULT_KEY_COMMANDS = DEFAULT_KEY_COMMANDS;\n function modifierNamesToMask(modiferNames) {\n var defaultVal = 0;\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(modiferNames, function (sum, name) {\n var modifier = _mobiledocKitUtilsKey.MODIFIERS[name.toUpperCase()];\n (0, _mobiledocKitUtilsAssert['default'])('No modifier named \"' + name + '\" found', !!modifier);\n return sum + modifier;\n }, defaultVal);\n }\n\n function characterToCode(character) {\n var upperCharacter = character.toUpperCase();\n var special = _mobiledocKitUtilsKey.SPECIAL_KEYS[upperCharacter];\n if (special) {\n return special;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Only 1 character can be used in a key command str (got \"' + character + '\")', character.length === 1);\n return upperCharacter.charCodeAt(0);\n }\n }\n\n function buildKeyCommand(keyCommand) {\n var str = keyCommand.str;\n\n if (!str) {\n return keyCommand;\n }\n (0, _mobiledocKitUtilsAssert['default'])('[deprecation] Key commands no longer use the `modifier` property', !keyCommand.modifier);\n\n var _str$split$reverse = str.split('+').reverse();\n\n var _str$split$reverse2 = _toArray(_str$split$reverse);\n\n var character = _str$split$reverse2[0];\n\n var modifierNames = _str$split$reverse2.slice(1);\n\n keyCommand.modifierMask = modifierNamesToMask(modifierNames);\n keyCommand.code = characterToCode(character);\n\n return keyCommand;\n }\n\n function validateKeyCommand(keyCommand) {\n return !!keyCommand.code && !!keyCommand.run;\n }\n\n function findKeyCommands(keyCommands, keyEvent) {\n var key = _mobiledocKitUtilsKey['default'].fromEvent(keyEvent);\n\n return (0, _mobiledocKitUtilsArrayUtils.filter)(keyCommands, function (_ref) {\n var modifierMask = _ref.modifierMask;\n var code = _ref.code;\n\n return key.keyCode === code && key.modifierMask === modifierMask;\n });\n }\n});","define('mobiledoc-kit/editor/mutation-handler', ['exports', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsSet, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MUTATION = {\n NODES_CHANGED: 'childList',\n CHARACTER_DATA: 'characterData'\n };\n\n var MutationHandler = (function () {\n function MutationHandler(editor) {\n var _this = this;\n\n _classCallCheck(this, MutationHandler);\n\n this.editor = editor;\n this.logger = editor.loggerFor('mutation-handler');\n this.renderTree = null;\n this._isObserving = false;\n\n this._observer = new MutationObserver(function (mutations) {\n _this._handleMutations(mutations);\n });\n }\n\n _createClass(MutationHandler, [{\n key: 'init',\n value: function init() {\n this.startObserving();\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stopObserving();\n this._observer = null;\n }\n }, {\n key: 'suspendObservation',\n value: function suspendObservation(callback) {\n this.stopObserving();\n callback();\n this.startObserving();\n }\n }, {\n key: 'stopObserving',\n value: function stopObserving() {\n if (this._isObserving) {\n this._isObserving = false;\n this._observer.disconnect();\n }\n }\n }, {\n key: 'startObserving',\n value: function startObserving() {\n if (!this._isObserving) {\n var editor = this.editor;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot observe un-rendered editor', editor.hasRendered);\n\n this._isObserving = true;\n this.renderTree = editor._renderTree;\n\n this._observer.observe(editor.element, {\n characterData: true,\n childList: true,\n subtree: true\n });\n }\n }\n }, {\n key: 'reparsePost',\n value: function reparsePost() {\n this.editor._reparsePost();\n }\n }, {\n key: 'reparseSections',\n value: function reparseSections(sections) {\n this.editor._reparseSections(sections);\n }\n\n /**\n * for each mutation:\n * * find the target nodes:\n * * if nodes changed, target nodes are:\n * * added nodes\n * * the target from which removed nodes were removed\n * * if character data changed\n * * target node is the mutation event's target (text node)\n * * filter out nodes that are no longer attached (parentNode is null)\n * * for each remaining node:\n * * find its section, add to sections-to-reparse\n * * if no section, reparse all (and break)\n */\n }, {\n key: '_handleMutations',\n value: function _handleMutations(mutations) {\n var reparsePost = false;\n var sections = new _mobiledocKitUtilsSet['default']();\n\n for (var i = 0; i < mutations.length; i++) {\n if (reparsePost) {\n break;\n }\n\n var nodes = this._findTargetNodes(mutations[i]);\n\n for (var j = 0; j < nodes.length; j++) {\n var node = nodes[j];\n var renderNode = this._findRenderNodeFromNode(node);\n if (renderNode) {\n if (renderNode.reparsesMutationOfChildNode(node)) {\n var section = this._findSectionFromRenderNode(renderNode);\n if (section) {\n sections.add(section);\n } else {\n reparsePost = true;\n }\n }\n } else {\n reparsePost = true;\n break;\n }\n }\n }\n\n if (reparsePost) {\n this.logger.log('reparsePost (' + mutations.length + ' mutations)');\n this.reparsePost();\n } else if (sections.length) {\n this.logger.log('reparse ' + sections.length + ' sections (' + mutations.length + ' mutations)');\n this.reparseSections(sections.toArray());\n }\n }\n }, {\n key: '_findTargetNodes',\n value: function _findTargetNodes(mutation) {\n var nodes = [];\n\n switch (mutation.type) {\n case MUTATION.CHARACTER_DATA:\n nodes.push(mutation.target);\n break;\n case MUTATION.NODES_CHANGED:\n (0, _mobiledocKitUtilsArrayUtils.forEach)(mutation.addedNodes, function (n) {\n return nodes.push(n);\n });\n if (mutation.removedNodes.length) {\n nodes.push(mutation.target);\n }\n break;\n }\n\n var element = this.editor.element;\n var attachedNodes = (0, _mobiledocKitUtilsArrayUtils.filter)(nodes, function (node) {\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, node);\n });\n return attachedNodes;\n }\n }, {\n key: '_findSectionRenderNodeFromNode',\n value: function _findSectionRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node, function (rn) {\n return rn.postNode.isSection;\n });\n }\n }, {\n key: '_findRenderNodeFromNode',\n value: function _findRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node);\n }\n }, {\n key: '_findSectionFromRenderNode',\n value: function _findSectionFromRenderNode(renderNode) {\n var sectionRenderNode = this._findSectionRenderNodeFromNode(renderNode.element);\n return sectionRenderNode && sectionRenderNode.postNode;\n }\n }]);\n\n return MutationHandler;\n })();\n\n exports['default'] = MutationHandler;\n});","define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/editor/post/post-inserter', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/to-range'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils, _mobiledocKitEditorPostPostInserter, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsToRange) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n function isListSectionTagName(tagName) {\n return tagName === 'ul' || tagName === 'ol';\n }\n\n var CALLBACK_QUEUES = {\n BEFORE_COMPLETE: 'beforeComplete',\n COMPLETE: 'complete',\n AFTER_COMPLETE: 'afterComplete'\n };\n\n // There are only two events that we're concerned about for Undo, that is inserting text and deleting content.\n // These are the only two states that go on a \"run\" and create a combined undo, everything else has it's own\n // deadicated undo.\n var EDIT_ACTIONS = {\n INSERT_TEXT: 1,\n DELETE: 2\n };\n\n /**\n * The PostEditor is used to modify a post. It should not be instantiated directly.\n * Instead, a new instance of a PostEditor is created by the editor and passed\n * as the argument to the callback in {@link Editor#run}.\n *\n * Usage:\n * ```\n * editor.run((postEditor) => {\n * // postEditor is an instance of PostEditor that can operate on the\n * // editor's post\n * });\n * ```\n */\n\n var PostEditor = (function () {\n /**\n * @private\n */\n\n function PostEditor(editor) {\n var _this = this;\n\n _classCallCheck(this, PostEditor);\n\n this.editor = editor;\n this.builder = this.editor.builder;\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n this._didComplete = false;\n this.editActionTaken = null;\n\n this._renderRange = function () {\n return _this.editor.selectRange(_this._range);\n };\n this._postDidChange = function () {\n return _this.editor._postDidChange();\n };\n this._rerender = function () {\n return _this.editor.rerender();\n };\n }\n\n _createClass(PostEditor, [{\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n }, {\n key: 'begin',\n value: function begin() {\n // cache the editor's range\n this._range = this.editor.range;\n }\n\n /**\n * Schedules to select the given range on the editor after the postEditor\n * has completed its work. This also updates the postEditor's active range\n * (so that multiple calls to range-changing methods on the postEditor will\n * update the correct range).\n *\n * Usage:\n * let range = editor.range;\n * editor.run(postEditor => {\n * let nextPosition = postEditor.deleteRange(range);\n *\n * // Will position the editor's cursor at `nextPosition` after\n * // the postEditor finishes work and the editor rerenders.\n * postEditor.setRange(nextPosition);\n * });\n * @param {Range|Position} range\n * @public\n */\n }, {\n key: 'setRange',\n value: function setRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n // TODO validate that the range is valid\n // (does not contain marked-for-removal head or tail sections?)\n this._range = range;\n this.scheduleAfterRender(this._renderRange, true);\n }\n\n /**\n * Delete a range from the post\n *\n * Usage:\n * ```\n * let { range } = editor;\n * editor.run((postEditor) => {\n * let nextPosition = postEditor.deleteRange(range);\n * postEditor.setRange(nextPosition);\n * });\n * ```\n * @param {Range} range Cursor Range object with head and tail Positions\n * @return {Position} The position where the cursor would go after deletion\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass MobiledocKit Range to `deleteRange`\", range instanceof _mobiledocKitUtilsCursorRange['default']);\n\n this.editActionTaken = EDIT_ACTIONS.DELETE;\n\n var head = range.head;\n var headSection = range.head.section;\n var tail = range.tail;\n var tailSection = range.tail.section;\n var post = this.editor.post;\n\n if (headSection === tailSection) {\n return this.cutSection(headSection, head, tail);\n }\n\n var nextSection = headSection.nextLeafSection();\n\n var nextPos = this.cutSection(headSection, head, headSection.tailPosition());\n // cutSection can replace the section, so re-read headSection here\n headSection = nextPos.section;\n\n // Remove sections in the middle of the range\n while (nextSection !== tailSection) {\n var tmp = nextSection;\n nextSection = nextSection.nextLeafSection();\n this.removeSection(tmp);\n }\n\n var tailPos = this.cutSection(tailSection, tailSection.headPosition(), tail);\n // cutSection can replace the section, so re-read tailSection here\n tailSection = tailPos.section;\n\n if (tailSection.isBlank) {\n this.removeSection(tailSection);\n } else {\n // If head and tail sections are markerable, join them\n // Note: They may not be the same section type. E.g. this may join\n // a tail section that was a list item onto a markup section, or vice versa.\n // (This is the desired behavior.)\n if (headSection.isMarkerable && tailSection.isMarkerable) {\n headSection.join(tailSection);\n this._markDirty(headSection);\n this.removeSection(tailSection);\n } else if (headSection.isBlank) {\n this.removeSection(headSection);\n nextPos = tailPos;\n }\n }\n\n if (post.isBlank) {\n post.sections.append(this.builder.createMarkupSection('p'));\n nextPos = post.headPosition();\n }\n\n return nextPos;\n }\n\n /**\n * Note: This method may replace `section` with a different section.\n *\n * \"Cut\" out the part of the section inside `headOffset` and `tailOffset`.\n * If section is markerable this splits markers that straddle the head or tail (if necessary),\n * and removes markers that are wholly inside the offsets.\n * If section is a card, this may replace it with a blank markup section if the\n * positions contain the entire card.\n *\n * @param {Section} section\n * @param {Position} head\n * @param {Position} tail\n * @return {Position}\n * @private\n */\n }, {\n key: 'cutSection',\n value: function cutSection(section, head, tail) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass head position and tail position to `cutSection`', head instanceof _mobiledocKitUtilsCursorPosition['default'] && tail instanceof _mobiledocKitUtilsCursorPosition['default']);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass positions within same section to `cutSection`', head.section === tail.section);\n\n if (section.isBlank || head.isEqual(tail)) {\n return head;\n }\n if (section.isCardSection) {\n if (head.isHead() && tail.isTail()) {\n var newSection = this.builder.createMarkupSection();\n this.replaceSection(section, newSection);\n return newSection.headPosition();\n } else {\n return tail;\n }\n }\n\n var range = head.toRange(tail);\n this.splitMarkers(range).forEach(function (m) {\n return _this2.removeMarker(m);\n });\n\n return head;\n }\n }, {\n key: '_coalesceMarkers',\n value: function _coalesceMarkers(section) {\n if (section.isMarkerable) {\n this._removeBlankMarkers(section);\n this._joinSimilarMarkers(section);\n }\n }\n }, {\n key: '_removeBlankMarkers',\n value: function _removeBlankMarkers(section) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }), function (m) {\n return _this3.removeMarker(m);\n });\n }\n\n // joins markers that have identical markups\n }, {\n key: '_joinSimilarMarkers',\n value: function _joinSimilarMarkers(section) {\n var marker = section.markers.head;\n var nextMarker = undefined;\n while (marker && marker.next) {\n nextMarker = marker.next;\n\n if (marker.canJoin(nextMarker)) {\n nextMarker.value = marker.value + nextMarker.value;\n this._markDirty(nextMarker);\n this.removeMarker(marker);\n }\n\n marker = nextMarker;\n }\n }\n }, {\n key: 'removeMarker',\n value: function removeMarker(marker) {\n this._scheduleForRemoval(marker);\n if (marker.section) {\n this._markDirty(marker.section);\n marker.section.markers.remove(marker);\n }\n }\n }, {\n key: '_scheduleForRemoval',\n value: function _scheduleForRemoval(postNode) {\n var _this4 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.scheduleForRemoval();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n var removedAdjacentToList = postNode.prev && postNode.prev.isListSection || postNode.next && postNode.next.isListSection;\n if (removedAdjacentToList) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this4._joinContiguousListSections();\n });\n }\n }\n }, {\n key: '_joinContiguousListSections',\n value: function _joinContiguousListSections() {\n var _this5 = this;\n\n var post = this.editor.post;\n\n var range = this._range;\n var prev = undefined;\n var groups = [];\n var currentGroup = undefined;\n\n // FIXME do we need to force a re-render of the range if changed sections\n // are contained within the range?\n var updatedHead = null;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n if (prev && prev.isListSection && section.isListSection && prev.tagName === section.tagName) {\n\n currentGroup = currentGroup || [prev];\n currentGroup.push(section);\n } else {\n if (currentGroup) {\n groups.push(currentGroup);\n }\n currentGroup = null;\n }\n prev = section;\n });\n\n if (currentGroup) {\n groups.push(currentGroup);\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(groups, function (group) {\n var list = group[0];\n (0, _mobiledocKitUtilsArrayUtils.forEach)(group, function (listSection) {\n if (listSection === list) {\n return;\n }\n\n var currentHead = range.head;\n var prevPosition = undefined;\n\n // FIXME is there a currentHead if there is no range?\n // is the current head a list item in the section\n if (!range.isBlank && currentHead.section.isListItem && currentHead.section.parent === listSection) {\n prevPosition = list.tailPosition();\n }\n _this5._joinListSections(list, listSection);\n if (prevPosition) {\n updatedHead = prevPosition.move(FORWARD);\n }\n });\n });\n\n if (updatedHead) {\n this.setRange(updatedHead);\n }\n }\n }, {\n key: '_joinListSections',\n value: function _joinListSections(baseList, nextList) {\n baseList.join(nextList);\n this._markDirty(baseList);\n this.removeSection(nextList);\n }\n }, {\n key: '_markDirty',\n value: function _markDirty(postNode) {\n var _this6 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.markDirty();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n if (postNode.section) {\n this._markDirty(postNode.section);\n }\n if (postNode.isMarkerable) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this6._coalesceMarkers(postNode);\n });\n }\n }\n\n /**\n * @param {Position} position object with {section, offset} the marker and offset to delete from\n * @param {Number} direction The direction to delete in (default is BACKWARD)\n * @return {Position} for positioning the cursor\n * @public\n * @deprecated after v0.10.3\n */\n }, {\n key: 'deleteFrom',\n value: function deleteFrom(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n (0, _mobiledocKitUtilsDeprecate['default'])(\"`postEditor#deleteFrom is deprecated. Use `deleteAtPosition(position, direction=BACKWARD, {unit}={unit: 'char'})` instead\");\n return this.deleteAtPosition(position, direction, { unit: 'char' });\n }\n\n /**\n * Delete 1 `unit` (can be 'char' or 'word') in the given `direction` at the given\n * `position`. In almost all cases this will be equivalent to deleting the range formed\n * by expanding the position 1 unit in the given direction. The exception is when deleting\n * backward from the beginning of a list item, which reverts the list item into a markup section\n * instead of joining it with its previous list item (if any).\n *\n * Usage:\n *\n * let position = section.tailPosition();\n * // Section has text of \"Howdy!\"\n * editor.run((postEditor) => {\n * postEditor.deleteAtPosition(position);\n * });\n * // section has text of \"Howdy\"\n *\n * @param {Position} position The position to delete at\n * @param {Direction} [direction=DIRECTION.BACKWARD] direction The direction to delete in\n * @param {Object} [options]\n * @param {String} [options.unit=\"char\"] The unit of deletion (\"word\" or \"char\")\n * @return {Position}\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n var _ref = arguments.length <= 2 || arguments[2] === undefined ? { unit: 'char' } : arguments[2];\n\n var unit = _ref.unit;\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n return this._deleteAtPositionBackward(position, unit);\n } else {\n return this._deleteAtPositionForward(position, unit);\n }\n }\n }, {\n key: '_deleteAtPositionBackward',\n value: function _deleteAtPositionBackward(position, unit) {\n if (position.isHead() && position.section.isListItem) {\n this.toggleSection('p', position);\n return this._range.head;\n } else {\n var prevPosition = unit === 'word' ? position.moveWord(BACKWARD) : position.move(BACKWARD);\n var range = prevPosition.toRange(position);\n return this.deleteRange(range);\n }\n }\n }, {\n key: '_deleteAtPositionForward',\n value: function _deleteAtPositionForward(position, unit) {\n var nextPosition = unit === 'word' ? position.moveWord(FORWARD) : position.move(FORWARD);\n var range = position.toRange(nextPosition);\n return this.deleteRange(range);\n }\n\n /**\n * Split markers at two positions, once at the head, and if necessary once\n * at the tail.\n *\n * Usage:\n * ```\n * let range = editor.range;\n * editor.run((postEditor) => {\n * postEditor.splitMarkers(range);\n * });\n * ```\n * The return value will be marker object completely inside the offsets\n * provided. Markers outside of the split may also have been modified.\n *\n * @param {Range} markerRange\n * @return {Array} of markers that are inside the split\n * @private\n */\n }, {\n key: 'splitMarkers',\n value: function splitMarkers(range) {\n var post = this.editor.post;\n var head = range.head;\n var tail = range.tail;\n\n this.splitSectionMarkerAtOffset(head.section, head.offset);\n this.splitSectionMarkerAtOffset(tail.section, tail.offset);\n\n return post.markersContainedByRange(range);\n }\n }, {\n key: 'splitSectionMarkerAtOffset',\n value: function splitSectionMarkerAtOffset(section, offset) {\n var _this7 = this;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (m) {\n return _this7.removeMarker(m);\n });\n }\n\n /**\n * Split the section at the position.\n *\n * Usage:\n * ```\n * let position = editor.cursor.offsets.head;\n * editor.run((postEditor) => {\n * postEditor.splitSection(position);\n * });\n * // Will result in the creation of two new sections\n * // replacing the old one at the cursor position\n * ```\n * The return value will be the two new sections. One or both of these\n * sections can be blank (contain only a blank marker), for example if the\n * headMarkerOffset is 0.\n *\n * @param {Position} position\n * @return {Array} new sections, one for the first half and one for the second (either one can be null)\n * @public\n */\n }, {\n key: 'splitSection',\n value: function splitSection(position) {\n var _this8 = this;\n\n var section = position.section;\n\n if (section.isCardSection) {\n return this._splitCardSection(section, position);\n } else if (section.isListItem) {\n var isLastAndBlank = section.isBlank && !section.next;\n if (isLastAndBlank) {\n // if is last, replace the item with a blank markup section\n var _parent = section.parent;\n var collection = this.editor.post.sections;\n var blank = this.builder.createMarkupSection();\n this.removeSection(section);\n this.insertSectionBefore(collection, blank, _parent.next);\n\n return [null, blank];\n } else {\n var _splitListItem2 = this._splitListItem(section, position);\n\n var _splitListItem22 = _slicedToArray(_splitListItem2, 2);\n\n var pre = _splitListItem22[0];\n var post = _splitListItem22[1];\n\n return [pre, post];\n }\n } else {\n var splitSections = section.splitAtPosition(position);\n splitSections.forEach(function (s) {\n return _this8._coalesceMarkers(s);\n });\n this._replaceSection(section, splitSections);\n\n return splitSections;\n }\n }\n\n /**\n * @param {Section} cardSection\n * @param {Position} position to split at\n * @return {Section[]} 2-item array of pre and post-split sections\n * @private\n */\n }, {\n key: '_splitCardSection',\n value: function _splitCardSection(cardSection, position) {\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cards section must be split at offset 0 or 1', offset === 0 || offset === 1);\n\n var newSection = this.builder.createMarkupSection();\n var nextSection = undefined;\n var surroundingSections = undefined;\n\n if (offset === 0) {\n nextSection = cardSection;\n surroundingSections = [newSection, cardSection];\n } else {\n nextSection = cardSection.next;\n surroundingSections = [cardSection, newSection];\n }\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, newSection, nextSection);\n\n return surroundingSections;\n }\n\n /**\n * @param {Section} section\n * @param {Section} newSection\n * @return null\n * @public\n */\n }, {\n key: 'replaceSection',\n value: function replaceSection(section, newSection) {\n if (!section) {\n // FIXME should a falsy section be a valid argument?\n this.insertSectionBefore(this.editor.post.sections, newSection, null);\n } else {\n this._replaceSection(section, [newSection]);\n }\n }\n }, {\n key: 'moveSectionBefore',\n value: function moveSectionBefore(collection, renderedSection, beforeSection) {\n var newSection = renderedSection.clone();\n this.removeSection(renderedSection);\n this.insertSectionBefore(collection, newSection, beforeSection);\n return newSection;\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionUp',\n value: function moveSectionUp(renderedSection) {\n var isFirst = !renderedSection.prev;\n if (isFirst) {\n return renderedSection;\n }\n\n var collection = renderedSection.parent.sections;\n var beforeSection = renderedSection.prev;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionDown',\n value: function moveSectionDown(renderedSection) {\n var isLast = !renderedSection.next;\n if (isLast) {\n return renderedSection;\n }\n\n var beforeSection = renderedSection.next.next;\n var collection = renderedSection.parent.sections;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * Insert an array of markers at the given position. If the position is in\n * a non-markerable section (like a card section), this method throws an error.\n *\n * @param {Position} position\n * @param {Marker[]} markers\n * @return {Position} The position that represents the end of the inserted markers.\n * @public\n */\n }, {\n key: 'insertMarkers',\n value: function insertMarkers(position, markers) {\n var _this9 = this;\n\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert markers at non-markerable position', section.isMarkerable);\n\n this.editActionTaken = EDIT_ACTIONS.INSERT_TEXT;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (marker) {\n return _this9._scheduleForRemoval(marker);\n });\n\n var prevMarker = section.markerBeforeOffset(offset);\n markers.forEach(function (marker) {\n section.markers.insertAfter(marker, prevMarker);\n offset += marker.length;\n prevMarker = marker;\n });\n\n this._coalesceMarkers(section);\n this._markDirty(section);\n\n var nextPosition = section.toPosition(offset);\n this.setRange(nextPosition);\n return nextPosition;\n }\n\n /**\n * Inserts text with the given markups, ignoring the existing markups at\n * the position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @param {Markup[]} markups\n * @return {Position} position at the end of the inserted text\n */\n }, {\n key: 'insertTextWithMarkup',\n value: function insertTextWithMarkup(position, text) {\n var markups = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var marker = this.builder.createMarker(text, markups);\n return this.insertMarkers(position, [marker]);\n }\n\n /**\n * Insert the text at the given position\n * Inherits the markups already at that position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @return {Position} position at the end of the inserted text.\n */\n }, {\n key: 'insertText',\n value: function insertText(position, text) {\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var markups = position.marker && position.marker.markups;\n markups = markups || [];\n return this.insertTextWithMarkup(position, text, markups);\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this10 = this;\n\n var nextSection = section.next;\n var collection = section.parent.sections;\n\n var nextNewSection = newSections[0];\n if (nextNewSection.isMarkupSection && section.isListItem) {\n // put the new section after the ListSection (section.parent)\n // instead of after the ListItem\n collection = section.parent.parent.sections;\n nextSection = section.parent.next;\n }\n\n newSections.forEach(function (s) {\n return _this10.insertSectionBefore(collection, s, nextSection);\n });\n this.removeSection(section);\n }\n\n /**\n * Given a markerRange (for example `editor.range`) mark all markers\n * inside it as a given markup. The markup must be provided as a post\n * abstract node.\n *\n * Usage:\n *\n * let range = editor.range;\n * let strongMarkup = editor.builder.createMarkup('strong');\n * editor.run((postEditor) => {\n * postEditor.addMarkupToRange(range, strongMarkup);\n * });\n * // Will result some markers possibly being split, and the markup\n * // being applied to all markers between the split.\n *\n * @param {Range} range\n * @param {Markup} markup A markup post abstract node\n * @public\n */\n }, {\n key: 'addMarkupToRange',\n value: function addMarkupToRange(range, markup) {\n var _this11 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n var markers = this.splitMarkers(range);\n if (markers.length) {\n (function () {\n // We insert the new markup at a consistent index across the range.\n // If we just push on the end of the list, it can end up in different positions\n // of the markup stack. This results in unnecessary closing and re-opening of\n // the markup each time it changes position.\n // If we just push it at the beginning of the list, this causes unnecessary closing\n // and re-opening of surrounding tags.\n // So, we look for any tags open across the whole range, and push into the stack\n // at the end of those.\n // Prompted by https://github.com/bustle/mobiledoc-kit/issues/360\n\n var markupsOpenAcrossRange = (0, _mobiledocKitUtilsArrayUtils.reduce)(markers, function (soFar, marker) {\n return (0, _mobiledocKitUtilsArrayUtils.commonItems)(soFar, marker.markups);\n }, markers[0].markups);\n var indexToInsert = markupsOpenAcrossRange.length;\n\n markers.forEach(function (marker) {\n marker.addMarkupAtIndex(markup, indexToInsert);\n _this11._markDirty(marker);\n });\n })();\n }\n }\n\n /**\n * Given a markerRange (for example `editor.range`) remove the given\n * markup from all contained markers.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let markup = markerRange.headMarker.markups[0];\n * editor.run(postEditor => {\n * postEditor.removeMarkupFromRange(range, markup);\n * });\n * // Will result in some markers possibly being split, and the markup\n * // being removed from all markers between the split.\n * ```\n * @param {Range} range Object with offsets\n * @param {Markup|Function} markupOrCallback A markup post abstract node or\n * a function that returns true when passed a markup that should be removed\n * @private\n */\n }, {\n key: 'removeMarkupFromRange',\n value: function removeMarkupFromRange(range, markupOrMarkupCallback) {\n var _this12 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n this.splitMarkers(range).forEach(function (marker) {\n marker.removeMarkup(markupOrMarkupCallback);\n _this12._markDirty(marker);\n });\n }\n\n /**\n * Toggle the given markup in the given range (or at the position given). If the range/position\n * has the markup, the markup will be removed. If nothing in the range/position\n * has the markup, the markup will be added to everything in the range/position.\n *\n * Usage:\n * ```\n * // Remove any 'strong' markup if it exists in the selection, otherwise\n * // make it all 'strong'\n * editor.run(postEditor => postEditor.toggleMarkup('strong'));\n *\n * // add/remove a link to 'bustle.com' to the selection\n * editor.run(postEditor => {\n * const linkMarkup = postEditor.builder.createMarkup('a', {href: 'http://bustle.com'});\n * postEditor.toggleMarkup(linkMarkup);\n * });\n * ```\n * @param {Markup|String} markupOrString Either a markup object created using\n * the builder (useful when adding a markup with attributes, like an 'a' markup),\n * or, if a string, the tag name of the markup (e.g. 'strong', 'em') to toggle.\n * @param {Range|Position} range in which to toggle. Defaults to current editor range.\n * @public\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markupOrMarkupString) {\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n var markup = typeof markupOrMarkupString === 'string' ? this.builder.createMarkup(markupOrMarkupString) : markupOrMarkupString;\n\n var hasMarkup = this.editor.detectMarkupInRange(range, markup.tagName);\n // FIXME: This implies only a single markup in a range. This may not be\n // true for links (which are not the same object instance like multiple\n // strong tags would be).\n if (hasMarkup) {\n this.removeMarkupFromRange(range, hasMarkup);\n } else {\n this.addMarkupToRange(range, markup);\n }\n\n this.setRange(range);\n }\n\n /**\n * Toggles the tagName of the active section or sections in the given range/position.\n * If every section has the tag name, they will all be reset to default sections.\n * Otherwise, every section will be changed to the requested type\n *\n * @param {String} sectionTagName A valid markup section or\n * list section tag name (e.g. 'blockquote', 'h2', 'ul')\n * @param {Range|Position} range The range over which to toggle.\n * Defaults to the current editor range.\n * @public\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(sectionTagName) {\n var _this13 = this;\n\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName);\n var post = this.editor.post;\n\n var nextRange = range;\n\n var everySectionHasTagName = true;\n post.walkMarkerableSections(range, function (section) {\n if (!_this13._isSameSectionType(section, sectionTagName)) {\n everySectionHasTagName = false;\n }\n });\n\n var tagName = everySectionHasTagName ? 'p' : sectionTagName;\n var firstChanged = undefined;\n post.walkMarkerableSections(range, function (section) {\n var changedSection = _this13.changeSectionTagName(section, tagName);\n firstChanged = firstChanged || changedSection;\n });\n\n if (firstChanged) {\n nextRange = firstChanged.headPosition().toRange();\n }\n this.setRange(nextRange);\n }\n }, {\n key: '_isSameSectionType',\n value: function _isSameSectionType(section, sectionTagName) {\n return section.isListItem ? section.parent.tagName === sectionTagName : section.tagName === sectionTagName;\n }\n\n /**\n * @param {Markerable} section\n * @private\n */\n }, {\n key: 'changeSectionTagName',\n value: function changeSectionTagName(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot pass non-markerable section to `changeSectionTagName`', section.isMarkerable);\n\n if (isListSectionTagName(newTagName)) {\n return this._changeSectionToListItem(section, newTagName);\n } else if (section.isListItem) {\n return this._changeSectionFromListItem(section, newTagName);\n } else {\n section.tagName = newTagName;\n this._markDirty(section);\n return section;\n }\n }\n\n /**\n * Splits the item at the position given.\n * If the position is at the start or end of the item, the pre- or post-item\n * will contain a single empty (\"\") marker.\n * @param {ListItem} item\n * @param {Position} position\n * @return {Array} the pre-item and post-item on either side of the split\n * @private\n */\n }, {\n key: '_splitListItem',\n value: function _splitListItem(item, position) {\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list item at position that does not include item', item === section);\n\n item.splitMarkerAtOffset(offset);\n var prevMarker = item.markerBeforeOffset(offset);\n var preItem = this.builder.createListItem(),\n postItem = this.builder.createListItem();\n\n var currentItem = preItem;\n item.markers.forEach(function (marker) {\n currentItem.markers.append(marker.clone());\n if (marker === prevMarker) {\n currentItem = postItem;\n }\n });\n this._replaceSection(item, [preItem, postItem]);\n return [preItem, postItem];\n }\n\n /**\n * Splits the list at the position given.\n * @return {Array} pre-split list and post-split list, either of which could\n * be blank (0-item list) if the position is at the start or end of the list.\n *\n * Note: Contiguous list sections will be joined in the before_complete queue\n * of the postEditor.\n *\n * @private\n */\n }, {\n key: '_splitListAtPosition',\n value: function _splitListAtPosition(list, position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at position not in list', position.section.parent === list);\n\n var positionIsMiddle = !position.isHead() && !position.isTail();\n if (positionIsMiddle) {\n var item = position.section;\n\n var _splitListItem3 = // jshint ignore:line\n this._splitListItem(item, position);\n\n var _splitListItem32 = _slicedToArray(_splitListItem3, 2);\n\n var pre = _splitListItem32[0];\n var post = _splitListItem32[1];\n\n position = pre.tailPosition();\n }\n\n var preList = this.builder.createListSection(list.tagName);\n var postList = this.builder.createListSection(list.tagName);\n\n var preItem = position.section;\n var currentList = preList;\n list.items.forEach(function (item) {\n // If this item matches the start item and the position is at its start,\n // it should be appended to the postList instead of the preList\n if (item === preItem && position.isEqual(item.headPosition())) {\n currentList = postList;\n }\n currentList.items.append(item.clone());\n // If we just appended the preItem, append the remaining items to the postList\n if (item === preItem) {\n currentList = postList;\n }\n });\n\n this._replaceSection(list, [preList, postList]);\n return [preList, postList];\n }\n\n /**\n * @return Array of [prev, mid, next] lists. `prev` and `next` can\n * be blank, depending on the position of `item`. `mid` will always\n * be a 1-item list containing `item`. `prev` and `next` will be\n * removed in the before_complete queue if they are blank\n * (and still attached).\n *\n * @private\n */\n }, {\n key: '_splitListAtItem',\n value: function _splitListAtItem(list, item) {\n var _this14 = this;\n\n var next = list;\n var prev = this.builder.createListSection(next.tagName);\n var mid = this.builder.createListSection(next.tagName);\n\n var addToPrev = true;\n // must turn the LinkedList into an array so that we can remove items\n // as we iterate through it\n var items = next.items.toArray();\n items.forEach(function (i) {\n var listToAppend = undefined;\n if (i === item) {\n addToPrev = false;\n listToAppend = mid;\n } else if (addToPrev) {\n listToAppend = prev;\n } else {\n return; // break after iterating prev and mid parts of the list\n }\n listToAppend.join(i);\n _this14.removeSection(i);\n });\n var found = !addToPrev;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found);\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, mid, next);\n this.insertSectionBefore(collection, prev, mid);\n\n // Remove possibly blank prev/next lists\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n [prev, next].forEach(function (_list) {\n var isAttached = !!_list.parent;\n if (_list.isBlank && isAttached) {\n _this14.removeSection(_list);\n }\n });\n });\n\n return [prev, mid, next];\n }\n }, {\n key: '_changeSectionFromListItem',\n value: function _changeSectionFromListItem(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass list item to `_changeSectionFromListItem`', section.isListItem);\n\n var listSection = section.parent;\n var markupSection = this.builder.createMarkupSection(newTagName);\n markupSection.join(section);\n\n var _splitListAtItem2 = this._splitListAtItem(listSection, section);\n\n var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 3);\n\n var prev = _splitListAtItem22[0];\n var mid = _splitListAtItem22[1];\n var next = _splitListAtItem22[2];\n // jshint ignore:line\n this.replaceSection(mid, markupSection);\n return markupSection;\n }\n }, {\n key: '_changeSectionToListItem',\n value: function _changeSectionToListItem(section, newTagName) {\n var isAlreadyCorrectListItem = section.isListItem && section.parent.tagName === newTagName;\n\n if (isAlreadyCorrectListItem) {\n return section;\n }\n\n var listSection = this.builder.createListSection(newTagName);\n listSection.join(section);\n\n var sectionToReplace = undefined;\n if (section.isListItem) {\n var _splitListAtItem3 = this._splitListAtItem(section.parent, section);\n\n var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 3);\n\n var prev = _splitListAtItem32[0];\n var mid = _splitListAtItem32[1];\n var next = _splitListAtItem32[2];\n // jshint ignore:line\n sectionToReplace = mid;\n } else {\n sectionToReplace = section;\n }\n this.replaceSection(sectionToReplace, listSection);\n return listSection;\n }\n\n /**\n * Insert a given section before another one, updating the post abstract\n * and the rendered UI.\n *\n * Usage:\n * ```\n * let markerRange = editor.range;\n * let sectionWithCursor = markerRange.headMarker.section;\n * let section = editor.builder.createCardSection('my-image');\n * let collection = sectionWithCursor.parent.sections;\n * editor.run((postEditor) => {\n * postEditor.insertSectionBefore(collection, section, sectionWithCursor);\n * });\n * ```\n * @param {LinkedList} collection The list of sections to insert into\n * @param {Object} section The new section\n * @param {Object} beforeSection Optional The section \"before\" is relative to,\n * if falsy the new section will be appended to the collection\n * @public\n */\n }, {\n key: 'insertSectionBefore',\n value: function insertSectionBefore(collection, section, beforeSection) {\n collection.insertBefore(section, beforeSection);\n this._markDirty(section.parent);\n }\n\n /**\n * Insert the given section after the current active section, or, if no\n * section is active, at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSection',\n value: function insertSection(section) {\n var activeSection = this.editor.activeSection;\n var nextSection = activeSection && activeSection.next;\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, section, nextSection);\n }\n\n /**\n * Insert the given section at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSectionAtEnd',\n value: function insertSectionAtEnd(section) {\n this.insertSectionBefore(this.editor.post.sections, section, null);\n }\n\n /**\n * Insert the `post` at the given position in the editor's post.\n * @param {Position} position\n * @param {Post} post\n * @private\n */\n }, {\n key: 'insertPost',\n value: function insertPost(position, newPost) {\n var post = this.editor.post;\n var inserter = new _mobiledocKitEditorPostPostInserter['default'](this, post);\n var nextPosition = inserter.insert(position, newPost);\n return nextPosition;\n }\n\n /**\n * Remove a given section from the post abstract and the rendered UI.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let sectionWithCursor = range.head.section;\n * editor.run((postEditor) => {\n * postEditor.removeSection(sectionWithCursor);\n * });\n * ```\n * @param {Object} section The section to remove\n * @public\n */\n }, {\n key: 'removeSection',\n value: function removeSection(section) {\n var parent = section.parent;\n this._scheduleForRemoval(section);\n parent.sections.remove(section);\n\n if (parent.isListSection) {\n this._scheduleListRemovalIfEmpty(parent);\n }\n }\n }, {\n key: 'removeAllSections',\n value: function removeAllSections() {\n var _this15 = this;\n\n this.editor.post.sections.toArray().forEach(function (section) {\n _this15.removeSection(section);\n });\n }\n }, {\n key: 'migrateSectionsFromPost',\n value: function migrateSectionsFromPost(post) {\n var _this16 = this;\n\n post.sections.toArray().forEach(function (section) {\n post.sections.remove(section);\n _this16.insertSectionBefore(_this16.editor.post.sections, section, null);\n });\n }\n }, {\n key: '_scheduleListRemovalIfEmpty',\n value: function _scheduleListRemovalIfEmpty(listSection) {\n var _this17 = this;\n\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n // if the list is attached and blank after we do other rendering stuff,\n // remove it\n var isAttached = !!listSection.parent;\n if (isAttached && listSection.isBlank) {\n _this17.removeSection(listSection);\n }\n });\n }\n\n /**\n * A method for adding work the deferred queue\n *\n * @param {Function} callback to run during completion\n * @param {Boolean} [once=false] Whether to only schedule the callback once.\n * @public\n */\n }, {\n key: 'schedule',\n value: function schedule(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Work can only be scheduled before a post edit has completed', !this._didComplete);\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.COMPLETE, callback);\n }\n }\n\n /**\n * A method for adding work the deferred queue. The callback will only\n * be added to the queue once, even if `scheduleOnce` is called multiple times.\n * The function cannot be an anonymous function.\n *\n * @param {Function} callback to run during completion\n * @public\n */\n }, {\n key: 'scheduleOnce',\n value: function scheduleOnce(callback) {\n this.schedule(callback, true);\n }\n\n /**\n * Add a rerender job to the queue\n *\n * @public\n */\n }, {\n key: 'scheduleRerender',\n value: function scheduleRerender() {\n this.scheduleOnce(this._rerender);\n }\n\n /**\n * Schedule a notification that the post has been changed.\n * The notification will result in the editor firing its `postDidChange`\n * hook after the postEditor completes its work (at the end of {@link Editor#run}).\n *\n * @public\n */\n }, {\n key: 'scheduleDidUpdate',\n value: function scheduleDidUpdate() {\n this.scheduleOnce(this._postDidChange);\n }\n }, {\n key: 'scheduleAfterRender',\n value: function scheduleAfterRender(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n }\n }\n\n /**\n * Flush any work on the queue. {@link Editor#run} calls this method; it\n * should not be called directly.\n *\n * @private\n */\n }, {\n key: 'complete',\n value: function complete() {\n (0, _mobiledocKitUtilsAssert['default'])('Post editing can only be completed once', !this._didComplete);\n\n this.runCallbacks(CALLBACK_QUEUES.BEFORE_COMPLETE);\n this._didComplete = true;\n this.runCallbacks(CALLBACK_QUEUES.COMPLETE);\n this.runCallbacks(CALLBACK_QUEUES.AFTER_COMPLETE);\n }\n }, {\n key: 'undoLastChange',\n value: function undoLastChange() {\n this.editor._editHistory.stepBackward(this);\n }\n }, {\n key: 'redoLastChange',\n value: function redoLastChange() {\n this.editor._editHistory.stepForward(this);\n }\n }, {\n key: 'cancelSnapshot',\n value: function cancelSnapshot() {\n this._shouldCancelSnapshot = true;\n }\n }]);\n\n return PostEditor;\n })();\n\n exports['default'] = PostEditor;\n});","define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MARKERABLE = 'markerable',\n NESTED_MARKERABLE = 'nested_markerable',\n NON_MARKERABLE = 'non_markerable';\n\n var Visitor = (function () {\n function Visitor(inserter, cursorPosition) {\n _classCallCheck(this, Visitor);\n\n var postEditor = inserter.postEditor;\n var post = inserter.post;\n\n this.postEditor = postEditor;\n this._post = post;\n this.cursorPosition = cursorPosition;\n this.builder = this.postEditor.builder;\n\n this._hasInsertedFirstLeafSection = false;\n }\n\n _createClass(Visitor, [{\n key: 'visit',\n value: function visit(node) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit node of type ' + node.type, !!this[method]);\n this[method](node);\n }\n }, {\n key: '_canMergeSection',\n value: function _canMergeSection(section) {\n if (this._hasInsertedFirstLeafSection) {\n return false;\n } else {\n return this._isMarkerable && section.isMarkerable;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(node) {\n var _this = this;\n\n if (this.cursorSection.isBlank && !this._isNested) {\n // replace blank section with entire post\n var newSections = node.sections.map(function (s) {\n return s.clone();\n });\n this._replaceSection(this.cursorSection, newSections);\n } else {\n node.sections.forEach(function (section) {\n return _this.visit(section);\n });\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(node) {\n this[MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(node) {\n var _this2 = this;\n\n var hasNext = !!node.next;\n node.items.forEach(function (item) {\n return _this2.visit(item);\n });\n\n if (this._isNested && hasNext) {\n this._breakNestedAtCursor();\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(node) {\n this[NESTED_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: NON_MARKERABLE,\n value: function value(section) {\n if (this._isNested) {\n this._breakNestedAtCursor();\n } else if (!this.cursorSection.isBlank) {\n this._breakAtCursor();\n }\n\n this._insertLeafSection(section);\n }\n }, {\n key: MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n } else if (this._isNested && this._isMarkerable) {\n // If we are attaching a markerable section to a list item,\n // insert a linebreak then merge the section onto the resulting blank list item\n this._breakAtCursor();\n\n // Advance the cursor to the head of the blank list item\n var nextPosition = this.cursorSection.next.headPosition();\n this.cursorPosition = nextPosition;\n\n // Merge this section onto the list item\n this._mergeSection(section);\n } else {\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n }\n }, {\n key: NESTED_MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n return;\n }\n\n section = this._isNested ? section : this._wrapNestedSection(section);\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n\n // break out of a nested cursor position\n }, {\n key: '_breakNestedAtCursor',\n value: function _breakNestedAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call _breakNestedAtCursor if not nested', this._isNested);\n\n var parent = this.cursorSection.parent;\n var cursorAtEndOfList = this.cursorPosition.isEqual(parent.tailPosition());\n\n if (cursorAtEndOfList) {\n var blank = this.builder.createMarkupSection();\n this._insertSectionAfter(blank, parent);\n } else {\n var _breakListAtCursor2 = this._breakListAtCursor();\n\n var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 3);\n\n var pre = _breakListAtCursor22[0];\n var blank = _breakListAtCursor22[1];\n var post = _breakListAtCursor22[2];\n // jshint ignore:line\n this.cursorPosition = blank.tailPosition();\n }\n }\n }, {\n key: '_breakListAtCursor',\n value: function _breakListAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _splitParentSection if cursor position is not nested', this._isNested);\n\n var list = this.cursorSection.parent,\n position = this.cursorPosition,\n blank = this.builder.createMarkupSection();\n\n var _postEditor$_splitListAtPosition = this.postEditor._splitListAtPosition(list, position);\n\n var _postEditor$_splitListAtPosition2 = _slicedToArray(_postEditor$_splitListAtPosition, 2);\n\n var pre = _postEditor$_splitListAtPosition2[0];\n var post = _postEditor$_splitListAtPosition2[1];\n\n var collection = this._post.sections,\n reference = post;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n return [pre, blank, post];\n }\n }, {\n key: '_wrapNestedSection',\n value: function _wrapNestedSection(section) {\n var tagName = section.parent.tagName;\n var parent = this.builder.createListSection(tagName);\n parent.items.append(section.clone());\n return parent;\n }\n }, {\n key: '_mergeSection',\n value: function _mergeSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only merge markerable sections', this._isMarkerable && section.isMarkerable);\n this._hasInsertedFirstLeafSection = true;\n\n var markers = section.markers.map(function (m) {\n return m.clone();\n });\n var position = this.postEditor.insertMarkers(this.cursorPosition, markers);\n\n this.cursorPosition = position;\n }\n\n // Can be called to add a line break when in a nested section or a parent\n // section.\n }, {\n key: '_breakAtCursor',\n value: function _breakAtCursor() {\n if (this.cursorSection.isBlank) {\n return;\n } else if (this._isMarkerable) {\n this._breakMarkerableAtCursor();\n } else {\n this._breakNonMarkerableAtCursor();\n }\n }\n\n // Inserts a blank section before/after the cursor,\n // depending on cursor position.\n }, {\n key: '_breakNonMarkerableAtCursor',\n value: function _breakNonMarkerableAtCursor() {\n var collection = this._post.sections,\n blank = this.builder.createMarkupSection(),\n reference = this.cursorPosition.isHead() ? this.cursorSection : this.cursorSection.next;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n this.cursorPosition = blank.tailPosition();\n }\n }, {\n key: '_breakMarkerableAtCursor',\n value: function _breakMarkerableAtCursor() {\n var _postEditor$splitSection = // jshint ignore:line\n this.postEditor.splitSection(this.cursorPosition);\n\n var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 2);\n\n var pre = _postEditor$splitSection2[0];\n var post = _postEditor$splitSection2[1];\n\n this.cursorPosition = pre.tailPosition();\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot replace section that does not have parent.sections', section.parent && section.parent.sections);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass enumerable to _replaceSection', !!newSections.forEach);\n\n var collection = section.parent.sections;\n var reference = section.next;\n this.postEditor.removeSection(section);\n newSections.forEach(function (section) {\n _this3.postEditor.insertSectionBefore(collection, section, reference);\n });\n var lastSection = newSections[newSections.length - 1];\n\n this.cursorPosition = lastSection.tailPosition();\n }\n }, {\n key: '_insertSectionBefore',\n value: function _insertSectionBefore(section, reference) {\n var collection = this.cursorSection.parent.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n\n this.cursorPosition = section.tailPosition();\n }\n\n // Insert a section after the parent section.\n // E.g., add a markup section after a list section\n }, {\n key: '_insertSectionAfter',\n value: function _insertSectionAfter(section, parent) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _insertSectionAfter nested section', !parent.isNested);\n var reference = parent.next;\n var collection = this._post.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n this.cursorPosition = section.tailPosition();\n }\n }, {\n key: '_insertLeafSection',\n value: function _insertLeafSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only _insertLeafSection when cursor is at end of section', this.cursorPosition.isTail());\n\n this._hasInsertedFirstLeafSection = true;\n section = section.clone();\n\n if (this.cursorSection.isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert leaf non-markerable section when cursor is nested', !(section.isMarkerable && this._isNested));\n this._replaceSection(this.cursorSection, [section]);\n } else if (this.cursorSection.next && this.cursorSection.next.isBlank) {\n this._replaceSection(this.cursorSection.next, [section]);\n } else {\n var reference = this.cursorSection.next;\n this._insertSectionBefore(section, reference);\n }\n }\n }, {\n key: 'cursorPosition',\n get: function get() {\n return this._cursorPosition;\n },\n set: function set(position) {\n this._cursorPosition = position;\n this.postEditor.setRange(position);\n }\n }, {\n key: '_isMarkerable',\n get: function get() {\n return this.cursorSection.isMarkerable;\n }\n }, {\n key: 'cursorSection',\n get: function get() {\n return this.cursorPosition.section;\n }\n }, {\n key: 'cursorOffset',\n get: function get() {\n return this.cursorPosition.offset;\n }\n }, {\n key: '_isNested',\n get: function get() {\n return this.cursorSection.isNested;\n }\n }]);\n\n return Visitor;\n })();\n\n var Inserter = (function () {\n function Inserter(postEditor, post) {\n _classCallCheck(this, Inserter);\n\n this.postEditor = postEditor;\n this.post = post;\n }\n\n _createClass(Inserter, [{\n key: 'insert',\n value: function insert(cursorPosition, newPost) {\n var visitor = new Visitor(this, cursorPosition);\n visitor.visit(newPost);\n return visitor.cursorPosition;\n }\n }]);\n\n return Inserter;\n })();\n\n exports['default'] = Inserter;\n});","define(\"mobiledoc-kit/editor/selection-change-observer\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var instance = undefined;\n\n var SelectionChangeObserver = (function () {\n function SelectionChangeObserver() {\n _classCallCheck(this, SelectionChangeObserver);\n\n this.started = false;\n this.listeners = [];\n this.selection = {};\n }\n\n _createClass(SelectionChangeObserver, [{\n key: \"addListener\",\n value: function addListener(listener) {\n if (this.listeners.indexOf(listener) === -1) {\n this.listeners.push(listener);\n this.start();\n }\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n var index = this.listeners.indexOf(listener);\n if (index !== -1) {\n this.listeners.splice(index, 1);\n if (this.listeners.length === 0) {\n this.stop();\n }\n }\n }\n }, {\n key: \"start\",\n value: function start() {\n if (this.started) {\n return;\n }\n this.started = true;\n\n this.poll();\n }\n }, {\n key: \"stop\",\n value: function stop() {\n this.started = false;\n this.selection = {};\n }\n }, {\n key: \"notifyListeners\",\n value: function notifyListeners() /* newSelection, prevSelection */{\n var _arguments = arguments;\n\n this.listeners.forEach(function (listener) {\n listener.selectionDidChange.apply(listener, _arguments);\n });\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.stop();\n this.listeners = [];\n }\n }, {\n key: \"getSelection\",\n value: function getSelection() {\n var selection = window.getSelection();\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n return { anchorNode: anchorNode, focusNode: focusNode, anchorOffset: anchorOffset, focusOffset: focusOffset };\n }\n }, {\n key: \"poll\",\n value: function poll() {\n var _this = this;\n\n if (this.started) {\n this.update();\n this.runNext(function () {\n return _this.poll();\n });\n }\n }\n }, {\n key: \"runNext\",\n value: function runNext(fn) {\n window.requestAnimationFrame(fn);\n }\n }, {\n key: \"update\",\n value: function update() {\n var prevSelection = this.selection;\n var curSelection = this.getSelection();\n if (!this.selectionIsEqual(prevSelection, curSelection)) {\n this.selection = curSelection;\n this.notifyListeners(curSelection, prevSelection);\n }\n }\n }, {\n key: \"selectionIsEqual\",\n value: function selectionIsEqual(s1, s2) {\n return s1.anchorNode === s2.anchorNode && s1.anchorOffset === s2.anchorOffset && s1.focusNode === s2.focusNode && s1.focusOffset === s2.focusOffset;\n }\n }], [{\n key: \"getInstance\",\n value: function getInstance() {\n if (!instance) {\n instance = new SelectionChangeObserver();\n }\n return instance;\n }\n }, {\n key: \"addListener\",\n value: function addListener(listener) {\n SelectionChangeObserver.getInstance().addListener(listener);\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n SelectionChangeObserver.getInstance().removeListener(listener);\n }\n }]);\n\n return SelectionChangeObserver;\n })();\n\n exports[\"default\"] = SelectionChangeObserver;\n});","define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/editor/selection-change-observer'], function (exports, _mobiledocKitEditorSelectionChangeObserver) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SelectionManager = (function () {\n function SelectionManager(editor, callback) {\n _classCallCheck(this, SelectionManager);\n\n this.editor = editor;\n this.callback = callback;\n this.started = false;\n }\n\n _createClass(SelectionManager, [{\n key: 'start',\n value: function start() {\n if (this.started) {\n return;\n }\n\n _mobiledocKitEditorSelectionChangeObserver['default'].addListener(this);\n this.started = true;\n }\n }, {\n key: 'stop',\n value: function stop() {\n this.started = false;\n _mobiledocKitEditorSelectionChangeObserver['default'].removeListener(this);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stop();\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange() {\n if (this.started) {\n this.callback.apply(this, arguments);\n }\n }\n }]);\n\n return SelectionManager;\n })();\n\n exports['default'] = SelectionManager;\n});","define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var TextInputHandler = (function () {\n function TextInputHandler(editor) {\n _classCallCheck(this, TextInputHandler);\n\n this.editor = editor;\n this._handlers = [];\n }\n\n _createClass(TextInputHandler, [{\n key: 'register',\n value: function register(handler) {\n (0, _mobiledocKitUtilsAssert['default'])('Input Handler is not valid', this._validateHandler(handler));\n this._handlers.push(handler);\n }\n }, {\n key: 'unregister',\n value: function unregister(name) {\n var handlers = this._handlers;\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i].name === name) {\n handlers.splice(i, 1);\n }\n }\n }\n }, {\n key: 'handle',\n value: function handle(string) {\n var editor = this.editor;\n\n editor.insertText(string);\n\n var matchedHandler = this._findHandler();\n if (matchedHandler) {\n var _matchedHandler = _slicedToArray(matchedHandler, 2);\n\n var handler = _matchedHandler[0];\n var matches = _matchedHandler[1];\n\n handler.run(editor, matches);\n }\n }\n }, {\n key: '_findHandler',\n value: function _findHandler() {\n var _editor$range = this.editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n var preText = section.textUntil(head);\n\n for (var i = 0; i < this._handlers.length; i++) {\n var handler = this._handlers[i];\n var text = handler.text;\n var match = handler.match;\n\n if (text && (0, _mobiledocKitUtilsStringUtils.endsWith)(preText, text)) {\n return [handler, [text]];\n } else if (match && match.test(preText)) {\n return [handler, match.exec(preText)];\n }\n }\n }\n }, {\n key: '_validateHandler',\n value: function _validateHandler(handler) {\n (0, _mobiledocKitUtilsDeprecate['default'])('Registered input handlers require a \"name\" property so that they can be unregistered', !!handler.name);\n return !!handler.run && ( // has `run`\n !!handler.text || !!handler.match) && // and `text` or `match`\n !(!!handler.text && !!handler.match); // not both `text` and `match`\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._handlers = [];\n }\n }]);\n\n return TextInputHandler;\n })();\n\n exports['default'] = TextInputHandler;\n});","define('mobiledoc-kit/editor/text-input-handlers', ['exports'], function (exports) {\n /**\n * Convert section at the editor's cursor position into a list.\n * Does nothing if the cursor position is not at the start of the section,\n * or if the section is already a list item.\n *\n * @param {Editor} editor\n * @param {String} listTagName (\"ul\" or \"ol\")\n * @public\n */\n 'use strict';\n\n exports.replaceWithListSection = replaceWithListSection;\n exports.replaceWithHeaderSection = replaceWithHeaderSection;\n\n function replaceWithListSection(editor, listTagName) {\n var _editor$range = editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n if (section.isListItem) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var item = builder.createListItem();\n var listSection = builder.createListSection(listTagName, [item]);\n\n postEditor.replaceSection(section, listSection);\n postEditor.setRange(listSection.headPosition());\n });\n }\n\n /**\n * Convert section at the editor's cursor position into a header section.\n * Does nothing if the cursor position is not at the start of the section.\n *\n * @param {Editor} editor\n * @param {String} headingTagName ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')\n * @public\n */\n\n function replaceWithHeaderSection(editor, headingTagName) {\n var _editor$range2 = editor.range;\n var head = _editor$range2.head;\n var section = _editor$range2.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var newSection = builder.createMarkupSection(headingTagName);\n postEditor.replaceSection(section, newSection);\n postEditor.setRange(newSection.headPosition());\n });\n }\n\n var DEFAULT_TEXT_INPUT_HANDLERS = [{\n name: 'ul',\n // \"* \" -> ul\n match: /^\\* $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ul');\n }\n }, {\n name: 'ol',\n // \"1\" -> ol, \"1.\" -> ol\n match: /^1\\.? $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ol');\n }\n }, {\n name: 'heading',\n /*\n * \"# \" -> h1\n * \"## \" -> h2\n * \"### \" -> h3\n * \"#### \" -> h4\n * \"##### \" -> h5\n * \"###### \" -> h6\n */\n match: /^(#{1,6}) $/,\n run: function run(editor, matches) {\n var capture = matches[1];\n var headingTag = 'h' + capture.length;\n replaceWithHeaderSection(editor, headingTag);\n }\n }];\n exports.DEFAULT_TEXT_INPUT_HANDLERS = DEFAULT_TEXT_INPUT_HANDLERS;\n});","define('mobiledoc-kit/editor/ui', ['exports'], function (exports) {\n /**\n * @module UI\n */\n\n /**\n * @callback promptCallback\n * @param {String} url The URL to pass back to the editor for linking\n * to the selected text.\n */\n\n /**\n * @callback showPrompt\n * @param {String} message The text of the prompt.\n * @param {String} defaultValue The initial URL to display in the prompt.\n * @param {module:UI~promptCallback} callback Once your handler has accepted a URL,\n * it should pass it to `callback` so that the editor may link the\n * selected text.\n */\n\n /**\n * Exposes the core behavior for linking and unlinking text, and allows for\n * customization of the URL input handler.\n * @param {Editor} editor An editor instance to operate on. If a range is selected,\n * either prompt for a URL and add a link or un-link the\n * currently linked text.\n * @param {module:UI~showPrompt} [showPrompt] An optional custom input handler. Defaults\n * to using `window.prompt`.\n * @example\n * let myPrompt = (message, defaultURL, promptCallback) => {\n * let url = window.prompt(\"Overriding the defaults\", \"http://placekitten.com\");\n * promptCallback(url);\n * };\n *\n * editor.registerKeyCommand({\n * str: \"META+K\",\n * run(editor) {\n * toggleLink(editor, myPrompt);\n * }\n * });\n * @public\n */\n\n 'use strict';\n\n exports.toggleLink = toggleLink;\n var defaultShowPrompt = function defaultShowPrompt(message, defaultValue, callback) {\n return callback(window.prompt(message, defaultValue));\n };\n\n function toggleLink(editor) {\n var showPrompt = arguments.length <= 1 || arguments[1] === undefined ? defaultShowPrompt : arguments[1];\n\n if (editor.range.isCollapsed) {\n return;\n }\n\n var selectedText = editor.cursor.selectedText();\n var defaultUrl = '';\n if (selectedText.indexOf('http') !== -1) {\n defaultUrl = selectedText;\n }\n\n var range = editor.range;\n\n var hasLink = editor.detectMarkupInRange(range, 'a');\n\n if (hasLink) {\n editor.run(function (postEditor) {\n return postEditor.toggleMarkup('a');\n });\n } else {\n showPrompt('Enter a URL', defaultUrl, function (url) {\n if (!url) {\n return;\n }\n\n editor.run(function (postEditor) {\n var markup = postEditor.builder.createMarkup('a', { href: url });\n postEditor.toggleMarkup(markup);\n });\n });\n }\n }\n});","define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n var Mobiledoc = {\n Editor: _mobiledocKitEditorEditor['default'],\n UI: _mobiledocKitEditorUi,\n ImageCard: _mobiledocKitCardsImage['default'],\n Range: _mobiledocKitUtilsCursorRange['default'],\n Position: _mobiledocKitUtilsCursorPosition['default'],\n Error: _mobiledocKitUtilsMobiledocError['default'],\n VERSION: _mobiledocKitVersion['default']\n };\n\n function registerGlobal(global) {\n global.Mobiledoc = Mobiledoc;\n }\n\n exports.Editor = _mobiledocKitEditorEditor['default'];\n exports.UI = _mobiledocKitEditorUi;\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports['default'] = Mobiledoc;\n});","define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Markerable = (function (_Section) {\n _inherits(Markerable, _Section);\n\n function Markerable(type, tagName) {\n var _this = this;\n\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n _classCallCheck(this, Markerable);\n\n _get(Object.getPrototypeOf(Markerable.prototype), 'constructor', this).call(this, type);\n this.isMarkerable = true;\n this.tagName = tagName;\n this.markers = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(m) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only insert markers and atoms into markerable (was: ' + m.type + ')', m.isMarker || m.isAtom);\n m.section = m.parent = _this;\n },\n freeItem: function freeItem(m) {\n return m.section = m.parent = null;\n }\n });\n\n markers.forEach(function (m) {\n return _this.markers.append(m);\n });\n }\n\n _createClass(Markerable, [{\n key: 'canJoin',\n value: function canJoin(other) {\n return other.isMarkerable && other.type === this.type && other.tagName === this.tagName;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newMarkers = this.markers.map(function (m) {\n return m.clone();\n });\n return this.builder.createMarkerableSection(this.type, this.tagName, newMarkers);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get textUntil for a position not in this section', position.section === this);\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n var text = '';\n var currentMarker = this.markers.head;\n while (currentMarker) {\n if (currentMarker === marker) {\n text += currentMarker.textUntil(offsetInMarker);\n break;\n } else {\n text += currentMarker.text;\n currentMarker = currentMarker.next;\n }\n }\n return text;\n }\n\n /**\n * @param {Marker}\n * @param {Number} markerOffset The offset relative to the start of the marker\n *\n * @return {Number} The offset relative to the start of this section\n */\n }, {\n key: 'offsetOfMarker',\n value: function offsetOfMarker(marker) {\n var markerOffset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get offsetOfMarker for marker that is not child of this', marker.section === this);\n\n // FIXME it is possible, when we get a cursor position before having finished reparsing,\n // for markerOffset to be > marker.length. We shouldn't rely on this functionality.\n\n var offset = 0;\n var currentMarker = this.markers.head;\n while (currentMarker && currentMarker !== marker.next) {\n var _length = currentMarker === marker ? markerOffset : currentMarker.length;\n offset += _length;\n currentMarker = currentMarker.next;\n }\n\n return offset;\n }\n\n // puts clones of this.markers into beforeSection and afterSection,\n // all markers before the marker/offset split go in beforeSection, and all\n // after the marker/offset split go in afterSection\n // @return {Array} [beforeSection, afterSection], two new sections\n }, {\n key: '_redistributeMarkers',\n value: function _redistributeMarkers(beforeSection, afterSection, marker) {\n var offset = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3];\n\n var currentSection = beforeSection;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.markers, function (m) {\n if (m === marker) {\n var _marker$split = marker.split(offset);\n\n var _marker$split2 = _toArray(_marker$split);\n\n var beforeMarker = _marker$split2[0];\n\n var afterMarkers = _marker$split2.slice(1);\n\n beforeSection.markers.append(beforeMarker);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(afterMarkers, function (_m) {\n return afterSection.markers.append(_m);\n });\n currentSection = afterSection;\n } else {\n currentSection.markers.append(m.clone());\n }\n });\n\n return [beforeSection, afterSection];\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker() /*marker, offset=0*/{\n (0, _mobiledocKitUtilsAssert['default'])('splitAtMarker must be implemented by sub-class', false);\n }\n\n /**\n * Split this section's marker (if any) at the given offset, so that\n * there is now a marker boundary at that offset (useful for later applying\n * a markup to a range)\n * @param {Number} sectionOffset The offset relative to start of this section\n * @return {EditObject} An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank.\n * After calling `splitMarkerAtOffset(offset)`, there will always be a valid\n * result returned from `markerBeforeOffset(offset)`.\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset(sectionOffset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot splitMarkerAtOffset when offset is > length', sectionOffset <= this.length);\n var markerOffset = undefined;\n var len = 0;\n var currentMarker = this.markers.head;\n var edit = { added: [], removed: [] };\n\n if (!currentMarker) {\n var blankMarker = this.builder.createMarker();\n this.markers.prepend(blankMarker);\n edit.added.push(blankMarker);\n } else {\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n // nothing to do, there is a gap at the requested offset\n break;\n } else if (len > sectionOffset) {\n var _edit$added;\n\n markerOffset = currentMarker.length - (len - sectionOffset);\n var newMarkers = currentMarker.splitAtOffset(markerOffset);\n (_edit$added = edit.added).push.apply(_edit$added, _toConsumableArray(newMarkers));\n edit.removed.push(currentMarker);\n this.markers.splice(currentMarker, 1, newMarkers);\n break;\n } else {\n currentMarker = currentMarker.next;\n }\n }\n }\n\n return edit;\n }\n }, {\n key: 'splitAtPosition',\n value: function splitAtPosition(position) {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n return this.splitAtMarker(marker, offsetInMarker);\n }\n\n // returns the marker just before this offset.\n // It is an error to call this method with an offset that is in the middle\n // of a marker.\n }, {\n key: 'markerBeforeOffset',\n value: function markerBeforeOffset(sectionOffset) {\n var len = 0;\n var currentMarker = this.markers.head;\n\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n return currentMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('markerBeforeOffset called with sectionOffset not between markers', len < sectionOffset);\n currentMarker = currentMarker.next;\n }\n }\n }\n }, {\n key: 'markerPositionAtOffset',\n value: function markerPositionAtOffset(offset) {\n var currentOffset = 0;\n var currentMarker = undefined;\n var remaining = offset;\n this.markers.detect(function (marker) {\n currentOffset = Math.min(remaining, marker.length);\n remaining -= currentOffset;\n if (remaining === 0) {\n currentMarker = marker;\n return true; // break out of detect\n }\n });\n\n return { marker: currentMarker, offset: currentOffset };\n }\n }, {\n key: 'markersFor',\n\n /**\n * @return {Array} New markers that match the boundaries of the\n * range. Does not change the existing markers in this section.\n */\n value: function markersFor(headOffset, tailOffset) {\n var range = { head: { section: this, offset: headOffset },\n tail: { section: this, offset: tailOffset } };\n\n var markers = [];\n this._markersInRange(range, function (marker, _ref) {\n var markerHead = _ref.markerHead;\n var markerTail = _ref.markerTail;\n var isContained = _ref.isContained;\n\n var cloned = marker.clone();\n if (!isContained) {\n // cannot do marker.value.slice if the marker is an atom -- this breaks the atom's \"atomic\" value\n // If a marker is an atom `isContained` should always be true so\n // we shouldn't hit this code path. FIXME add tests\n cloned.value = marker.value.slice(markerHead, markerTail);\n }\n markers.push(cloned);\n });\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n this._markersInRange(range, function (marker) {\n marker.markups.forEach(function (m) {\n return markups.add(m);\n });\n });\n return markups.toArray();\n }\n\n // calls the callback with (marker, {markerHead, markerTail, isContained})\n // for each marker that is wholly or partially contained in the range.\n }, {\n key: '_markersInRange',\n value: function _markersInRange(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call #_markersInRange if range expands beyond this section', head.section === this && tail.section === this);\n var headOffset = head.offset;var tailOffset = tail.offset;\n\n var currentHead = 0,\n currentTail = 0,\n currentMarker = this.markers.head;\n\n while (currentMarker) {\n currentTail += currentMarker.length;\n\n if (currentTail > headOffset && currentHead < tailOffset) {\n var markerHead = Math.max(headOffset - currentHead, 0);\n var markerTail = currentMarker.length - Math.max(currentTail - tailOffset, 0);\n var isContained = markerHead === 0 && markerTail === currentMarker.length;\n\n callback(currentMarker, { markerHead: markerHead, markerTail: markerTail, isContained: isContained });\n }\n\n currentHead += currentMarker.length;\n currentMarker = currentMarker.next;\n\n if (currentHead > tailOffset) {\n break;\n }\n }\n }\n\n // mutates this by appending the other section's (cloned) markers to it\n }, {\n key: 'join',\n value: function join(otherSection) {\n var _this2 = this;\n\n var beforeMarker = this.markers.tail;\n var afterMarker = null;\n\n otherSection.markers.forEach(function (m) {\n if (!m.isBlank) {\n m = m.clone();\n _this2.markers.append(m);\n if (!afterMarker) {\n afterMarker = m;\n }\n }\n });\n\n return { beforeMarker: beforeMarker, afterMarker: afterMarker };\n }\n }, {\n key: 'isBlank',\n get: function get() {\n if (!this.markers.length) {\n return true;\n }\n return this.markers.every(function (m) {\n return m.isBlank;\n });\n }\n }, {\n key: 'text',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.value;\n }, '');\n }\n }, {\n key: 'length',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.length;\n }, 0);\n }\n }]);\n\n return Markerable;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Markerable;\n});","define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/cursor/position'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCursorPosition) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function unimplementedMethod(methodName, me) {\n (0, _mobiledocKitUtilsAssert['default'])('`' + methodName + '()` must be implemented by ' + me.constructor.name, false);\n }\n\n var Section = (function (_LinkedItem) {\n _inherits(Section, _LinkedItem);\n\n function Section(type) {\n _classCallCheck(this, Section);\n\n _get(Object.getPrototypeOf(Section.prototype), 'constructor', this).call(this);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create section without type', !!type);\n this.type = type;\n this.isSection = true;\n this.isMarkerable = false;\n this.isNested = false;\n this.isSection = true;\n this.isLeafSection = true;\n }\n\n _createClass(Section, [{\n key: 'isValidTagName',\n value: function isValidTagName() /* normalizedTagName */{\n unimplementedMethod('isValidTagName', this);\n }\n }, {\n key: 'clone',\n value: function clone() {\n unimplementedMethod('clone', this);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* otherSection */{\n unimplementedMethod('canJoin', this);\n }\n\n /**\n * @return {Position} The position at the start of this section\n * @public\n */\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.toPosition(0);\n }\n\n /**\n * @return {Position} The position at the end of this section\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.toPosition(this.length);\n }\n\n /**\n * @param {Number} offset\n * @return {Position} The position in this section at the given offset\n * @public\n */\n }, {\n key: 'toPosition',\n value: function toPosition(offset) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass number to `toPosition`\", typeof offset === 'number');\n (0, _mobiledocKitUtilsAssert['default'])(\"Cannot call `toPosition` with offset > length\", offset <= this.length);\n\n return new _mobiledocKitUtilsCursorPosition['default'](this, offset);\n }\n\n /**\n * @return {Range} A range from this section's head to tail positions\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'join',\n value: function join() {\n unimplementedMethod('join', this);\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* position */{\n return '';\n }\n\n /**\n * Markerable sections should override this method\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset() {\n var blankEdit = { added: [], removed: [] };\n return blankEdit;\n }\n }, {\n key: 'nextLeafSection',\n value: function nextLeafSection() {\n var next = this.next;\n if (next) {\n if (!!next.items) {\n return next.items.head;\n } else {\n return next;\n }\n } else {\n if (this.isNested) {\n return this.parent.nextLeafSection();\n }\n }\n }\n }, {\n key: 'immediatelyNextMarkerableSection',\n value: function immediatelyNextMarkerableSection() {\n var next = this.nextLeafSection();\n while (next && !next.isMarkerable) {\n next = next.nextLeafSection();\n }\n return next;\n }\n }, {\n key: 'previousLeafSection',\n value: function previousLeafSection() {\n var prev = this.prev;\n\n if (prev) {\n if (!!prev.items) {\n return prev.items.tail;\n } else {\n return prev;\n }\n } else {\n if (this.isNested) {\n return this.parent.previousLeafSection();\n }\n }\n }\n }, {\n key: 'tagName',\n set: function set(val) {\n var normalizedTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(val);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot set section tagName to ' + val, this.isValidTagName(normalizedTagName));\n this._tagName = normalizedTagName;\n },\n get: function get() {\n return this._tagName;\n }\n }, {\n key: 'length',\n get: function get() {\n return 0;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n unimplementedMethod('isBlank', this);\n }\n }]);\n\n return Section;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = Section;\n});","define('mobiledoc-kit/models/atom-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var AtomNode = (function () {\n function AtomNode(editor, atom, model, element, atomOptions) {\n _classCallCheck(this, AtomNode);\n\n this.editor = editor;\n this.atom = atom;\n this.model = model;\n this.atomOptions = atomOptions;\n this.element = element;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(AtomNode, [{\n key: 'render',\n value: function render() {\n if (!this._rendered) {\n var options = this.atomOptions;\n var env = this.env;\n var _model = this.model;\n var value = _model.value;\n var payload = _model.payload;\n\n // cache initial render\n this._rendered = this.atom.render({ options: options, env: env, value: value, payload: payload });\n }\n\n this._validateAndAppendRenderResult(this._rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.atom.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + name + '\" must return a DOM node (returned value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n }\n }, {\n key: 'env',\n get: function get() {\n var _this = this;\n\n return {\n name: this.atom.name,\n onTeardown: function onTeardown(callback) {\n return _this._teardownCallback = callback;\n },\n save: function save(value) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _this.model.value = value;\n _this.model.payload = payload;\n\n _this.editor._postDidChange();\n _this.teardown();\n _this.render();\n }\n };\n }\n }]);\n\n return AtomNode;\n })();\n\n exports['default'] = AtomNode;\n});","define('mobiledoc-kit/models/atom', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var ATOM_LENGTH = 1;\n\n var Atom = (function (_LinkedItem) {\n _inherits(Atom, _LinkedItem);\n\n function Atom(name, value, payload) {\n var _this = this;\n\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n _classCallCheck(this, Atom);\n\n _get(Object.getPrototypeOf(Atom.prototype), 'constructor', this).call(this);\n this.name = name;\n this.value = value;\n this.text = ''; // An atom never has text, but it does have a value\n (0, _mobiledocKitUtilsAssert['default'])('Atom must have value', value !== undefined && value !== null);\n this.payload = payload;\n this.type = _mobiledocKitModelsTypes.ATOM_TYPE;\n this.isMarker = false;\n this.isAtom = true;\n\n this.markups = [];\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Atom, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createAtom(this.name, this.value, this.payload, clonedMarkups);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* other */{\n return false;\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* offset */{\n return '';\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? offset : arguments[1];\n return (function () {\n var markers = [];\n\n if (endOffset === 0) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n markers.push(this.clone());\n\n if (offset === ATOM_LENGTH) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n return markers;\n }).apply(this, arguments);\n }\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n\n var builder = this.builder;\n\n var clone = this.clone();\n var blankMarker = builder.createMarker('');\n var pre = undefined,\n post = undefined;\n\n if (offset === 0) {\n pre = blankMarker;\n post = clone;\n } else if (offset === ATOM_LENGTH) {\n pre = clone;\n post = blankMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Invalid offset given to Atom#splitAtOffset: \"' + offset + '\"', false);\n }\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n return [pre, post];\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return ATOM_LENGTH;\n }\n }]);\n\n return Atom;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Atom, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Atom;\n});","define('mobiledoc-kit/models/card-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CardNode = (function () {\n function CardNode(editor, card, section, element, options) {\n _classCallCheck(this, CardNode);\n\n this.editor = editor;\n this.card = card;\n this.section = section;\n this.element = element;\n this.options = options;\n\n this.mode = null;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(CardNode, [{\n key: 'render',\n value: function render(mode) {\n if (this.mode === mode) {\n return;\n }\n\n this.teardown();\n\n this.mode = mode;\n\n var method = mode === 'display' ? 'render' : 'edit';\n method = this.card[method];\n\n (0, _mobiledocKitUtilsAssert['default'])('Card is missing \"' + method + '\" (tried to render mode: \"' + mode + '\")', !!method);\n var rendered = method({\n env: this.env,\n options: this.options,\n payload: this.section.payload\n });\n\n this._validateAndAppendRenderResult(rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: 'didRender',\n value: function didRender() {\n if (this._didRenderCallback) {\n this._didRenderCallback();\n }\n }\n }, {\n key: 'display',\n value: function display() {\n this.render('display');\n }\n }, {\n key: 'edit',\n value: function edit() {\n this.render('edit');\n }\n }, {\n key: 'remove',\n value: function remove() {\n var _this = this;\n\n this.editor.run(function (postEditor) {\n return postEditor.removeSection(_this.section);\n });\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.card.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + name + '\" must render dom (render value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n this._rendered = rendered;\n this.didRender();\n }\n }, {\n key: 'env',\n get: function get() {\n var _this2 = this;\n\n return {\n name: this.card.name,\n isInEditor: true,\n onTeardown: function onTeardown(callback) {\n return _this2._teardownCallback = callback;\n },\n didRender: function didRender(callback) {\n return _this2._didRenderCallback = callback;\n },\n edit: function edit() {\n return _this2.edit();\n },\n save: function save(payload) {\n var transition = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\n _this2.section.payload = payload;\n\n _this2.editor._postDidChange();\n if (transition) {\n _this2.display();\n }\n },\n cancel: function cancel() {\n return _this2.display();\n },\n remove: function remove() {\n return _this2.remove();\n },\n postModel: this.section\n };\n }\n }]);\n\n return CardNode;\n })();\n\n exports['default'] = CardNode;\n});","define('mobiledoc-kit/models/card', ['exports', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/copy'], function (exports, _mobiledocKitModels_section, _mobiledocKitModelsTypes, _mobiledocKitUtilsCopy) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var CARD_MODES = {\n DISPLAY: 'display',\n EDIT: 'edit'\n };\n\n exports.CARD_MODES = CARD_MODES;\n var CARD_LENGTH = 1;\n\n var DEFAULT_INITIAL_MODE = CARD_MODES.DISPLAY;\n\n var Card = (function (_Section) {\n _inherits(Card, _Section);\n\n function Card(name, payload) {\n _classCallCheck(this, Card);\n\n _get(Object.getPrototypeOf(Card.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.CARD_TYPE);\n this.name = name;\n this.payload = payload;\n this.setInitialMode(DEFAULT_INITIAL_MODE);\n this.isCardSection = true;\n }\n\n _createClass(Card, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var payload = (0, _mobiledocKitUtilsCopy.shallowCopyObject)(this.payload);\n var card = this.builder.createCardSection(this.name, payload);\n // If this card is currently rendered, clone the mode it is\n // currently in as the default mode of the new card.\n var mode = this._initialMode;\n if (this.renderNode && this.renderNode.cardNode) {\n mode = this.renderNode.cardNode.mode;\n }\n card.setInitialMode(mode);\n return card;\n }\n\n /**\n * set the mode that this will be rendered into initially\n * @private\n */\n }, {\n key: 'setInitialMode',\n value: function setInitialMode(initialMode) {\n // TODO validate initialMode\n this._initialMode = initialMode;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return CARD_LENGTH;\n }\n }]);\n\n return Card;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Card;\n});","define('mobiledoc-kit/models/image', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Image = (function (_Section) {\n _inherits(Image, _Section);\n\n function Image() {\n _classCallCheck(this, Image);\n\n _get(Object.getPrototypeOf(Image.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE);\n this.src = null;\n }\n\n _createClass(Image, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return 1;\n }\n }]);\n\n return Image;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Image;\n});","define('mobiledoc-kit/models/lifecycle-callbacks', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LifecycleCallbacks = (function () {\n function LifecycleCallbacks() {\n var _this = this;\n\n var queueNames = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, LifecycleCallbacks);\n\n this.callbackQueues = {};\n this.removalQueues = {};\n\n queueNames.forEach(function (name) {\n _this.callbackQueues[name] = [];\n _this.removalQueues[name] = [];\n });\n }\n\n _createClass(LifecycleCallbacks, [{\n key: 'runCallbacks',\n value: function runCallbacks(queueName) {\n var args = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var queue = this._getQueue(queueName);\n queue.forEach(function (cb) {\n return cb.apply(undefined, _toConsumableArray(args));\n });\n\n var toRemove = this.removalQueues[queueName];\n toRemove.forEach(function (cb) {\n var index = queue.indexOf(cb);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n });\n\n this.removalQueues[queueName] = [];\n }\n }, {\n key: 'addCallback',\n value: function addCallback(queueName, callback) {\n this._getQueue(queueName).push(callback);\n }\n }, {\n key: '_scheduleCallbackForRemoval',\n value: function _scheduleCallbackForRemoval(queueName, callback) {\n this.removalQueues[queueName].push(callback);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce(queueName, callback) {\n var queue = this._getQueue(queueName);\n if (queue.indexOf(callback) === -1) {\n queue.push(callback);\n this._scheduleCallbackForRemoval(queueName, callback);\n }\n }\n }, {\n key: '_getQueue',\n value: function _getQueue(queueName) {\n var queue = this.callbackQueues[queueName];\n (0, _mobiledocKitUtilsAssert['default'])('No queue found for \"' + queueName + '\"', !!queue);\n return queue;\n }\n }]);\n\n return LifecycleCallbacks;\n })();\n\n exports['default'] = LifecycleCallbacks;\n});","define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_ITEM_TAGNAMES = ['li'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_ITEM_TAGNAMES = VALID_LIST_ITEM_TAGNAMES;\n\n var ListItem = (function (_Markerable) {\n _inherits(ListItem, _Markerable);\n\n function ListItem(tagName) {\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, ListItem);\n\n _get(Object.getPrototypeOf(ListItem.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, tagName, markers);\n this.isListItem = true;\n this.isNested = true;\n }\n\n _createClass(ListItem, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_ITEM_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n // FIXME need to check if we are going to split into two list items\n // or a list item and a new markup section:\n var isLastItem = !this.next;\n var createNewSection = !marker && offset === 0 && isLastItem;\n\n var beforeSection = this.builder.createListItem();\n var afterSection = createNewSection ? this.builder.createMarkupSection() : this.builder.createListItem();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }, {\n key: 'post',\n get: function get() {\n return this.section.post;\n }\n }]);\n\n return ListItem;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = ListItem;\n});","define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_SECTION_TAGNAMES = ['ul', 'ol'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_SECTION_TAGNAMES = VALID_LIST_SECTION_TAGNAMES;\n var DEFAULT_TAG_NAME = VALID_LIST_SECTION_TAGNAMES[0];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n\n var ListSection = (function (_Section) {\n _inherits(ListSection, _Section);\n\n function ListSection() {\n var _this = this;\n\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, ListSection);\n\n _get(Object.getPrototypeOf(ListSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_SECTION_TYPE);\n this.tagName = tagName;\n this.isListSection = true;\n this.isLeafSection = false;\n\n this.items = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(i) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem);\n i.section = i.parent = _this;\n },\n freeItem: function freeItem(i) {\n return i.section = i.parent = null;\n }\n });\n this.sections = this.items;\n\n items.forEach(function (i) {\n return _this.items.append(i);\n });\n }\n\n _createClass(ListSection, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.items.head.headPosition();\n }\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.items.tail.tailPosition();\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newSection = this.builder.createListSection(this.tagName);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.items, function (i) {\n return newSection.items.append(i.clone());\n });\n return newSection;\n }\n\n /**\n * Mutates this list\n * @param {ListSection|Markerable}\n * @return null\n */\n }, {\n key: 'join',\n value: function join(other) {\n var _this2 = this;\n\n if (other.isListSection) {\n other.items.forEach(function (i) {\n return _this2.join(i);\n });\n } else if (other.isMarkerable) {\n var item = this.builder.createListItem();\n item.join(other);\n this.items.append(item);\n }\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.items.isEmpty;\n }\n }]);\n\n return ListSection;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = ListSection;\n});","define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // Unicode uses a pair of \"surrogate\" characters\" (a high- and low-surrogate)\n // to encode characters outside the basic multilingual plane (like emoji and\n // some languages).\n // These values are the unicode code points for the start and end of the\n // high- and low-surrogate characters.\n // See \"high surrogate\" and \"low surrogate\" on\n // https://en.wikipedia.org/wiki/Unicode_block\n var HIGH_SURROGATE_RANGE = [0xD800, 0xDBFF];\n exports.HIGH_SURROGATE_RANGE = HIGH_SURROGATE_RANGE;\n var LOW_SURROGATE_RANGE = [0xDC00, 0xDFFF];\n\n exports.LOW_SURROGATE_RANGE = LOW_SURROGATE_RANGE;\n var Marker = (function (_LinkedItem) {\n _inherits(Marker, _LinkedItem);\n\n function Marker() {\n var _this = this;\n\n var value = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, Marker);\n\n _get(Object.getPrototypeOf(Marker.prototype), 'constructor', this).call(this);\n this.value = value;\n (0, _mobiledocKitUtilsAssert['default'])('Marker must have value', value !== undefined && value !== null);\n this.markups = [];\n this.type = _mobiledocKitModelsTypes.MARKER_TYPE;\n this.isMarker = true;\n this.isAtom = false;\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Marker, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createMarker(this.value, clonedMarkups);\n }\n }, {\n key: 'charAt',\n value: function charAt(offset) {\n return this.value.slice(offset, offset + 1);\n }\n\n /**\n * A marker's text is equal to its value.\n * Compare with an Atom which distinguishes between text and value\n */\n }, {\n key: 'deleteValueAtOffset',\n\n // delete the character at this offset,\n // update the value with the new value\n value: function deleteValueAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot delete value at offset outside bounds', offset >= 0 && offset <= this.length);\n\n var width = 1;\n var code = this.value.charCodeAt(offset);\n if (code >= HIGH_SURROGATE_RANGE[0] && code <= HIGH_SURROGATE_RANGE[1]) {\n width = 2;\n } else if (code >= LOW_SURROGATE_RANGE[0] && code <= LOW_SURROGATE_RANGE[1]) {\n width = 2;\n offset = offset - 1;\n }\n\n var left = this.value.slice(0, offset);\n var right = this.value.slice(offset + width);\n\n this.value = left + right;\n\n return width;\n }\n }, {\n key: 'canJoin',\n value: function canJoin(other) {\n return other && other.isMarker && (0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(this.markups, other.markups);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(offset) {\n return this.value.slice(0, offset);\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? this.length : arguments[1];\n\n var markers = [this.builder.createMarker(this.value.substring(0, offset)), this.builder.createMarker(this.value.substring(offset, endOffset)), this.builder.createMarker(this.value.substring(endOffset))];\n\n this.markups.forEach(function (mu) {\n return markers.forEach(function (m) {\n return m.addMarkup(mu);\n });\n });\n return markers;\n }\n\n /**\n * @return {Array} 2 markers either or both of which could be blank\n */\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n var value = this.value;\n var builder = this.builder;\n\n var pre = builder.createMarker(value.substring(0, offset));\n var post = builder.createMarker(value.substring(offset));\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n\n return [pre, post];\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.isBlank;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.length === 0;\n }\n }, {\n key: 'text',\n get: function get() {\n return this.value;\n }\n }, {\n key: 'length',\n get: function get() {\n return this.value.length;\n }\n }]);\n\n return Marker;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Marker, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Marker;\n});","define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // valid values of `tagName` for a MarkupSection\n var VALID_MARKUP_SECTION_TAGNAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_SECTION_TAGNAMES = VALID_MARKUP_SECTION_TAGNAMES;\n // valid element names for a MarkupSection. A MarkupSection with a tagName\n // not in this will be rendered as a div with a className matching the\n // tagName\n var MARKUP_SECTION_ELEMENT_NAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n exports.MARKUP_SECTION_ELEMENT_NAMES = MARKUP_SECTION_ELEMENT_NAMES;\n var DEFAULT_TAG_NAME = VALID_MARKUP_SECTION_TAGNAMES[8];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n var MarkupSection = (function (_Markerable) {\n _inherits(MarkupSection, _Markerable);\n\n function MarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, MarkupSection);\n\n _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers);\n this.isMarkupSection = true;\n }\n\n _createClass(MarkupSection, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_MARKUP_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var beforeSection = this.builder.createMarkupSection(this.tagName, []);\n var afterSection = this.builder.createMarkupSection();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }]);\n\n return MarkupSection;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = MarkupSection;\n});","define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var VALID_MARKUP_TAGNAMES = ['a', 'b', 'code', 'em', 'i', 's', // strikethrough\n 'strong', 'sub', // subscript\n 'sup', // superscript\n 'u'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_TAGNAMES = VALID_MARKUP_TAGNAMES;\n var VALID_ATTRIBUTES = ['href', 'rel'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n\n var Markup = (function () {\n /*\n * @param {Object} attributes key-values\n */\n\n function Markup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, Markup);\n\n this.tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must use attributes object param (not array) for Markup', !Array.isArray(attributes));\n\n this.attributes = (0, _mobiledocKitUtilsArrayUtils.filterObject)(attributes, VALID_ATTRIBUTES);\n this.type = _mobiledocKitModelsTypes.MARKUP_TYPE;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1);\n }\n\n _createClass(Markup, [{\n key: 'isForwardInclusive',\n value: function isForwardInclusive() {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(\"a\") ? false : true;\n }\n }, {\n key: 'isBackwardInclusive',\n value: function isBackwardInclusive() {\n return false;\n }\n }, {\n key: 'hasTag',\n value: function hasTag(tagName) {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n }\n }, {\n key: 'getAttribute',\n value: function getAttribute(name) {\n return this.attributes[name];\n }\n }], [{\n key: 'isValidElement',\n value: function isValidElement(element) {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n return VALID_MARKUP_TAGNAMES.indexOf(tagName) !== -1;\n }\n }]);\n\n return Markup;\n })();\n\n exports['default'] = Markup;\n});","define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/models/atom', 'mobiledoc-kit/models/post', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/image', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsAtom, _mobiledocKitModelsPost, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsImage, _mobiledocKitModelsMarker, _mobiledocKitModelsMarkup, _mobiledocKitModelsCard, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function cacheKey(tagName, attributes) {\n return (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName) + '-' + (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(attributes).join('-');\n }\n\n function addMarkupToCache(cache, markup) {\n cache[cacheKey(markup.tagName, markup.attributes)] = markup;\n }\n\n function findMarkupInCache(cache, tagName, attributes) {\n var key = cacheKey(tagName, attributes);\n return cache[key];\n }\n\n /**\n * The PostNodeBuilder is used to create new {@link Post} primitives, such\n * as a MarkupSection, a CardSection, a Markup, etc. Every instance of an\n * {@link Editor} has its own builder instance. The builder can be used\n * inside an {@link Editor#run} callback to programmatically create new\n * Post primitives to insert into the document.\n * A PostNodeBuilder should be read from the Editor, *not* instantiated on its own.\n */\n\n var PostNodeBuilder = (function () {\n /**\n * @private\n */\n\n function PostNodeBuilder() {\n _classCallCheck(this, PostNodeBuilder);\n\n this.markupCache = {};\n }\n\n /**\n * @return {Post} A new, blank post\n */\n\n _createClass(PostNodeBuilder, [{\n key: 'createPost',\n value: function createPost() {\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var post = new _mobiledocKitModelsPost['default']();\n post.builder = this;\n\n sections.forEach(function (s) {\n return post.sections.append(s);\n });\n\n return post;\n }\n }, {\n key: 'createMarkerableSection',\n value: function createMarkerableSection(type, tagName) {\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.createListItem(markers);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.createMarkupSection(tagName, markers);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markerable section of type ' + type, false);\n }\n }\n\n /**\n * @param {tagName} [tagName='P']\n * @param {Marker[]} [markers=[]]\n * @return {MarkupSection}\n */\n }, {\n key: 'createMarkupSection',\n value: function createMarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0];\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers);\n if (isGenerated) {\n section.isGenerated = true;\n }\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListSection',\n value: function createListSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0];\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsListSection['default'](tagName, items);\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListItem',\n value: function createListItem() {\n var markers = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('li');\n var item = new _mobiledocKitModelsListItem['default'](tagName, markers);\n item.builder = this;\n return item;\n }\n }, {\n key: 'createImageSection',\n value: function createImageSection(url) {\n var section = new _mobiledocKitModelsImage['default']();\n if (url) {\n section.src = url;\n }\n return section;\n }\n\n /**\n * @param {String} name\n * @param {Object} [payload={}]\n * @return {CardSection}\n */\n }, {\n key: 'createCardSection',\n value: function createCardSection(name) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var card = new _mobiledocKitModelsCard['default'](name, payload);\n card.builder = this;\n return card;\n }\n\n /**\n * @param {String} value\n * @param {Markup[]} [markups=[]]\n * @return {Marker}\n */\n }, {\n key: 'createMarker',\n value: function createMarker(value) {\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var marker = new _mobiledocKitModelsMarker['default'](value, markups);\n marker.builder = this;\n return marker;\n }\n\n /**\n * @param {String} name\n * @param {String} [value='']\n * @param {Object} [payload={}]\n * @param {Markup[]} [markups=[]]\n * @return {Atom}\n */\n }, {\n key: 'createAtom',\n value: function createAtom(name) {\n var value = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var payload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n var atom = new _mobiledocKitModelsAtom['default'](name, value, payload, markups);\n atom.builder = this;\n return atom;\n }\n\n /**\n * @param {String} tagName\n * @param {Object} attributes Key-value pairs of attributes for the markup\n * @return {Markup}\n */\n }, {\n key: 'createMarkup',\n value: function createMarkup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n var markup = findMarkupInCache(this.markupCache, tagName, attributes);\n if (!markup) {\n markup = new _mobiledocKitModelsMarkup['default'](tagName, attributes);\n markup.builder = this;\n addMarkupToCache(this.markupCache, markup);\n }\n\n return markup;\n }\n }]);\n\n return PostNodeBuilder;\n })();\n\n exports['default'] = PostNodeBuilder;\n});","define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * The Post is an in-memory representation of an editor's document.\n * An editor always has a single post. The post is organized into a list of\n * sections. Each section may be markerable (contains \"markers\", aka editable\n * text) or non-markerable (e.g., a card).\n * When persisting a post, it must first be serialized (loss-lessly) into\n * mobiledoc using {@link Editor#serialize}.\n */\n\n var Post = (function () {\n /**\n * @private\n */\n\n function Post() {\n var _this = this;\n\n _classCallCheck(this, Post);\n\n this.type = _mobiledocKitModelsTypes.POST_TYPE;\n this.sections = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(s) {\n return s.post = s.parent = _this;\n },\n freeItem: function freeItem(s) {\n return s.post = s.parent = null;\n }\n });\n }\n\n /**\n * @return {Position} The position at the start of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n\n _createClass(Post, [{\n key: 'headPosition',\n value: function headPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.head.headPosition();\n }\n }\n\n /**\n * @return {Position} The position at the end of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.tail.tailPosition();\n }\n }\n\n /**\n * @return {Range} A range encompassing the entire post\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'markersContainedByRange',\n\n /**\n * @param {Range} range\n * @return {Array} markers that are completely contained by the range\n */\n value: function markersContainedByRange(range) {\n var markers = [];\n\n this.walkMarkerableSections(range, function (section) {\n section._markersInRange(range.trimTo(section), function (m, _ref) {\n var isContained = _ref.isContained;\n if (isContained) {\n markers.push(m);\n }\n });\n });\n\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n\n if (range.isCollapsed) {\n var pos = range.head;\n if (pos.isMarkerable) {\n var back = pos.markerIn(-1);\n var forward = pos.markerIn(1);\n\n if (back && forward && back === forward) {\n back.markups.forEach(function (m) {\n return markups.add(m);\n });\n } else {\n (back && back.markups || []).forEach(function (m) {\n if (m.isForwardInclusive()) {\n markups.add(m);\n }\n });\n (forward && forward.markups || []).forEach(function (m) {\n if (m.isBackwardInclusive()) {\n markups.add(m);\n }\n });\n }\n }\n } else {\n this.walkMarkerableSections(range, function (section) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markupsInRange(range.trimTo(section)), function (m) {\n return markups.add(m);\n });\n });\n }\n\n return markups.toArray();\n }\n }, {\n key: 'walkAllLeafSections',\n value: function walkAllLeafSections(callback) {\n var range = this.headPosition().toRange(this.tailPosition());\n return this.walkLeafSections(range, callback);\n }\n }, {\n key: 'walkLeafSections',\n value: function walkLeafSections(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n var index = 0;\n var nextSection = undefined,\n shouldStop = undefined;\n var currentSection = head.section;\n\n while (currentSection) {\n nextSection = this._nextLeafSection(currentSection);\n shouldStop = currentSection === tail.section;\n\n callback(currentSection, index);\n index++;\n\n if (shouldStop) {\n break;\n } else {\n currentSection = nextSection;\n }\n }\n }\n }, {\n key: 'walkMarkerableSections',\n value: function walkMarkerableSections(range, callback) {\n this.walkLeafSections(range, function (section) {\n if (section.isMarkerable) {\n callback(section);\n }\n });\n }\n\n // return the next section that has markers after this one,\n // possibly skipping non-markerable sections\n }, {\n key: '_nextLeafSection',\n value: function _nextLeafSection(section) {\n if (!section) {\n return null;\n }\n\n var next = section.next;\n if (next) {\n if (next.isLeafSection) {\n return next;\n } else if (!!next.items) {\n return next.items.head;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false);\n }\n } else if (section.isNested) {\n // if there is no section after this, but this section is a child\n // (e.g. a ListItem inside a ListSection), check for a markerable\n // section after its parent\n return this._nextLeafSection(section.parent);\n }\n }\n\n /**\n * @param {Range} range\n * @return {Post} A new post, constrained to {range}\n */\n }, {\n key: 'trimTo',\n value: function trimTo(range) {\n var post = this.builder.createPost();\n var builder = this.builder;\n\n var sectionParent = post,\n listParent = null;\n this.walkLeafSections(range, function (section) {\n var newSection = undefined;\n if (section.isMarkerable) {\n if (section.isListItem) {\n if (listParent) {\n sectionParent = null;\n } else {\n listParent = builder.createListSection(section.parent.tagName);\n post.sections.append(listParent);\n sectionParent = null;\n }\n newSection = builder.createListItem();\n listParent.items.append(newSection);\n } else {\n listParent = null;\n sectionParent = post;\n newSection = builder.createMarkupSection(section.tagName);\n }\n\n var currentRange = range.trimTo(section);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markersFor(currentRange.headSectionOffset, currentRange.tailSectionOffset), function (m) {\n return newSection.markers.append(m);\n });\n } else {\n newSection = section.clone();\n }\n if (sectionParent) {\n sectionParent.sections.append(newSection);\n }\n });\n return post;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.sections.isEmpty;\n }\n\n /**\n * If the post has no sections, or only has one, blank section, then it does\n * not have content and this method returns false. Otherwise it is true.\n * @return {Boolean}\n * @public\n */\n }, {\n key: 'hasContent',\n get: function get() {\n if (this.sections.length > 1 || this.sections.length === 1 && !this.sections.head.isBlank) {\n return true;\n } else {\n return false;\n }\n }\n }]);\n\n return Post;\n })();\n\n exports['default'] = Post;\n});","define('mobiledoc-kit/models/render-node', ['exports', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var RenderNode = (function (_LinkedItem) {\n _inherits(RenderNode, _LinkedItem);\n\n function RenderNode(postNode, renderTree) {\n _classCallCheck(this, RenderNode);\n\n _get(Object.getPrototypeOf(RenderNode.prototype), 'constructor', this).call(this);\n this.parent = null;\n this.isDirty = true;\n this.isRemoved = false;\n this.postNode = postNode;\n this._childNodes = null;\n this._element = null;\n this._cursorElement = null; // blank render nodes need a cursor element\n this.renderTree = renderTree;\n\n // RenderNodes for Markers keep track of their markupElement\n this.markupElement = null;\n\n // RenderNodes for Atoms use these properties\n this.headTextNode = null;\n this.tailTextNode = null;\n this.atomNode = null;\n\n // RenderNodes for cards use this property\n this.cardNode = null;\n }\n\n _createClass(RenderNode, [{\n key: 'isAttached',\n value: function isAttached() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot check if a renderNode is attached without an element.', !!this.element);\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(this.renderTree.rootElement, this.element);\n }\n }, {\n key: 'scheduleForRemoval',\n value: function scheduleForRemoval() {\n this.isRemoved = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markDirty',\n value: function markDirty() {\n this.isDirty = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markClean',\n value: function markClean() {\n this.isDirty = false;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.element = null;\n this.parent = null;\n this.postNode = null;\n this.renderTree = null;\n }\n }, {\n key: 'reparsesMutationOfChildNode',\n value: function reparsesMutationOfChildNode(node) {\n if (this.postNode.isCardSection) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.cardNode.element, node);\n } else if (this.postNode.isAtom) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.atomNode.element, node);\n }\n return true;\n }\n }, {\n key: 'childNodes',\n get: function get() {\n var _this = this;\n\n if (!this._childNodes) {\n this._childNodes = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(item) {\n return item.parent = _this;\n },\n freeItem: function freeItem(item) {\n return item.destroy();\n }\n });\n }\n return this._childNodes;\n }\n }, {\n key: 'isRendered',\n get: function get() {\n return !!this.element;\n }\n }, {\n key: 'element',\n set: function set(element) {\n var currentElement = this._element;\n this._element = element;\n\n if (currentElement) {\n this.renderTree.removeElementRenderNode(currentElement);\n }\n\n if (element) {\n this.renderTree.setElementRenderNode(element, this);\n }\n },\n get: function get() {\n return this._element;\n }\n }, {\n key: 'cursorElement',\n set: function set(cursorElement) {\n this._cursorElement = cursorElement;\n },\n get: function get() {\n return this._cursorElement || this.element;\n }\n }]);\n\n return RenderNode;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = RenderNode;\n});","define('mobiledoc-kit/models/render-tree', ['exports', 'mobiledoc-kit/models/render-node', 'mobiledoc-kit/utils/element-map'], function (exports, _mobiledocKitModelsRenderNode, _mobiledocKitUtilsElementMap) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var RenderTree = (function () {\n function RenderTree(rootPostNode) {\n _classCallCheck(this, RenderTree);\n\n this._rootNode = this.buildRenderNode(rootPostNode);\n this._elements = new _mobiledocKitUtilsElementMap['default']();\n }\n\n /*\n * @return {RenderNode} The root render node in this tree\n */\n\n _createClass(RenderTree, [{\n key: 'getElementRenderNode',\n\n /*\n * @param {DOMNode} element\n * @return {RenderNode} The renderNode for this element, if any\n */\n value: function getElementRenderNode(element) {\n return this._elements.get(element);\n }\n }, {\n key: 'setElementRenderNode',\n value: function setElementRenderNode(element, renderNode) {\n this._elements.set(element, renderNode);\n }\n }, {\n key: 'removeElementRenderNode',\n value: function removeElementRenderNode(element) {\n this._elements.remove(element);\n }\n\n /**\n * @param {DOMNode} element\n * Walk up from the dom element until we find a renderNode element\n */\n }, {\n key: 'findRenderNodeFromElement',\n value: function findRenderNodeFromElement(element) {\n var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {\n return true;\n } : arguments[1];\n\n var renderNode = undefined;\n while (element) {\n renderNode = this.getElementRenderNode(element);\n if (renderNode && conditionFn(renderNode)) {\n return renderNode;\n }\n\n // continue loop\n element = element.parentNode;\n\n // stop if we are at the root element\n if (element === this.rootElement) {\n if (conditionFn(this.rootNode)) {\n return this.rootNode;\n } else {\n return;\n }\n }\n }\n }\n }, {\n key: 'buildRenderNode',\n value: function buildRenderNode(postNode) {\n var renderNode = new _mobiledocKitModelsRenderNode['default'](postNode, this);\n postNode.renderNode = renderNode;\n return renderNode;\n }\n }, {\n key: 'rootNode',\n get: function get() {\n return this._rootNode;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'isDirty',\n get: function get() {\n return this.rootNode && this.rootNode.isDirty;\n }\n\n /*\n * @return {DOMNode} The root DOM element in this tree\n */\n }, {\n key: 'rootElement',\n get: function get() {\n return this.rootNode.element;\n }\n }]);\n\n return RenderTree;\n })();\n\n exports['default'] = RenderTree;\n});","define('mobiledoc-kit/models/types', ['exports'], function (exports) {\n 'use strict';\n\n var MARKUP_SECTION_TYPE = 'markup-section';\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var LIST_SECTION_TYPE = 'list-section';\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var MARKUP_TYPE = 'markup';\n exports.MARKUP_TYPE = MARKUP_TYPE;\n var MARKER_TYPE = 'marker';\n exports.MARKER_TYPE = MARKER_TYPE;\n var POST_TYPE = 'post';\n exports.POST_TYPE = POST_TYPE;\n var LIST_ITEM_TYPE = 'list-item';\n exports.LIST_ITEM_TYPE = LIST_ITEM_TYPE;\n var CARD_TYPE = 'card-section';\n exports.CARD_TYPE = CARD_TYPE;\n var IMAGE_SECTION_TYPE = 'image-section';\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var ATOM_TYPE = 'atom';\n exports.ATOM_TYPE = ATOM_TYPE;\n});","define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/parsers/section', 'mobiledoc-kit/models/markup'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCharacters, _mobiledocKitParsersSection, _mobiledocKitModelsMarkup) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.transformHTMLText = transformHTMLText;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var GOOGLE_DOCS_CONTAINER_ID_REGEX = /^docs\\-internal\\-guid/;\n\n var NO_BREAK_SPACE_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.NO_BREAK_SPACE, 'g');\n var TAB_CHARACTER_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.TAB_CHARACTER, 'g');\n\n function transformHTMLText(textContent) {\n var text = textContent;\n text = text.replace(NO_BREAK_SPACE_REGEX, ' ');\n text = text.replace(TAB_CHARACTER_REGEX, _mobiledocKitUtilsCharacters.TAB);\n return text;\n }\n\n function isGoogleDocsContainer(element) {\n return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id);\n }\n\n function detectRootElement(element) {\n var childNodes = element.childNodes || [];\n var googleDocsContainer = (0, _mobiledocKitUtilsArrayUtils.detect)(childNodes, isGoogleDocsContainer);\n\n if (googleDocsContainer) {\n return googleDocsContainer;\n } else {\n return element;\n }\n }\n\n var TAG_REMAPPING = {\n 'b': 'strong',\n 'i': 'em'\n };\n\n function remapTagName(tagName) {\n var normalized = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var remapped = TAG_REMAPPING[normalized];\n return remapped || normalized;\n }\n\n function trim(str) {\n return str.replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n\n function walkMarkerableNodes(parent, callback) {\n var currentNode = parent;\n\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(currentNode) || (0, _mobiledocKitUtilsDomUtils.isElementNode)(currentNode) && currentNode.classList.contains(_mobiledocKitRenderersEditorDom.ATOM_CLASS_NAME)) {\n callback(currentNode);\n } else {\n currentNode = currentNode.firstChild;\n while (currentNode) {\n walkMarkerableNodes(currentNode, callback);\n currentNode = currentNode.nextSibling;\n }\n }\n }\n\n /**\n * Parses DOM element -> Post\n * @private\n */\n\n var DOMParser = (function () {\n function DOMParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, DOMParser);\n\n this.builder = builder;\n this.sectionParser = new _mobiledocKitParsersSection['default'](this.builder, options);\n }\n\n _createClass(DOMParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n var post = this.builder.createPost();\n var rootElement = detectRootElement(element);\n\n this._eachChildNode(rootElement, function (child) {\n var sections = _this.parseSections(child);\n _this.appendSections(post, sections);\n });\n\n return post;\n }\n }, {\n key: 'appendSections',\n value: function appendSections(post, sections) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(sections, function (section) {\n return _this2.appendSection(post, section);\n });\n }\n }, {\n key: 'appendSection',\n value: function appendSection(post, section) {\n if (section.isBlank || section.isMarkerable && trim(section.text) === '') {\n return;\n }\n\n var lastSection = post.sections.tail;\n if (lastSection && lastSection._inferredTagName && section._inferredTagName && lastSection.tagName === section.tagName) {\n lastSection.join(section);\n } else {\n post.sections.append(section);\n }\n }\n }, {\n key: '_eachChildNode',\n value: function _eachChildNode(element, callback) {\n var nodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n return callback(node);\n });\n }\n }, {\n key: 'parseSections',\n value: function parseSections(element) {\n return this.sectionParser.parse(element);\n }\n\n // walk up from the textNode until the rootNode, converting each\n // parentNode into a markup\n }, {\n key: 'collectMarkups',\n value: function collectMarkups(textNode, rootNode) {\n var markups = [];\n var currentNode = textNode.parentNode;\n while (currentNode && currentNode !== rootNode) {\n var markup = this.markupFromNode(currentNode);\n if (markup) {\n markups.push(markup);\n }\n\n currentNode = currentNode.parentNode;\n }\n return markups;\n }\n\n // Turn an element node into a markup\n }, {\n key: 'markupFromNode',\n value: function markupFromNode(node) {\n if (_mobiledocKitModelsMarkup['default'].isValidElement(node)) {\n var tagName = remapTagName(node.tagName);\n var attributes = (0, _mobiledocKitUtilsDomUtils.getAttributes)(node);\n return this.builder.createMarkup(tagName, attributes);\n }\n }\n\n // FIXME should move to the section parser?\n // FIXME the `collectMarkups` logic could simplify the section parser?\n }, {\n key: 'reparseSection',\n value: function reparseSection(section, renderTree) {\n switch (section.type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n return this.reparseListSection(section, renderTree);\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.reparseListItem(section, renderTree);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.reparseMarkupSection(section, renderTree);\n default:\n return; // can only parse the above types\n }\n }\n }, {\n key: 'reparseMarkupSection',\n value: function reparseMarkupSection(section, renderTree) {\n return this._reparseSectionContainingMarkers(section, renderTree);\n }\n }, {\n key: 'reparseListItem',\n value: function reparseListItem(listItem, renderTree) {\n return this._reparseSectionContainingMarkers(listItem, renderTree);\n }\n }, {\n key: 'reparseListSection',\n value: function reparseListSection(listSection, renderTree) {\n var _this3 = this;\n\n listSection.items.forEach(function (li) {\n return _this3.reparseListItem(li, renderTree);\n });\n }\n }, {\n key: '_reparseSectionContainingMarkers',\n value: function _reparseSectionContainingMarkers(section, renderTree) {\n var _this4 = this;\n\n var element = section.renderNode.element;\n var seenRenderNodes = [];\n var previousMarker = undefined;\n\n walkMarkerableNodes(element, function (node) {\n var marker = undefined;\n var renderNode = renderTree.getElementRenderNode(node);\n if (renderNode) {\n if (renderNode.postNode.isMarker) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n if (text.length) {\n marker = renderNode.postNode;\n marker.value = text;\n marker.markups = markups;\n } else {\n renderNode.scheduleForRemoval();\n }\n } else if (renderNode.postNode.isAtom) {\n var _renderNode = renderNode;\n var headTextNode = _renderNode.headTextNode;\n var tailTextNode = _renderNode.tailTextNode;\n\n if (headTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = headTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n headTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n if (previousMarker && previousMarker.isMarker) {\n previousMarker.value += value;\n if (previousMarker.renderNode) {\n previousMarker.renderNode.markDirty();\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newPreviousMarker = _this4.builder.createMarker(value, newMarkups);\n section.markers.insertBefore(newPreviousMarker, postNode);\n\n var newPreviousRenderNode = renderTree.buildRenderNode(newPreviousMarker);\n newPreviousRenderNode.markDirty();\n section.renderNode.markDirty();\n\n seenRenderNodes.push(newPreviousRenderNode);\n section.renderNode.childNodes.insertBefore(newPreviousRenderNode, renderNode);\n }\n }\n if (tailTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = tailTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n tailTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n\n if (renderNode.postNode.next && renderNode.postNode.next.isMarker) {\n var nextMarker = renderNode.postNode.next;\n\n if (nextMarker.renderNode) {\n var nextValue = nextMarker.renderNode.element.textContent;\n nextMarker.renderNode.element.textContent = value + nextValue;\n } else {\n var nextValue = value + nextMarker.value;\n nextMarker.value = nextValue;\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newMarker = _this4.builder.createMarker(value, newMarkups);\n\n section.markers.insertAfter(newMarker, postNode);\n\n var newRenderNode = renderTree.buildRenderNode(newMarker);\n seenRenderNodes.push(newRenderNode);\n\n newRenderNode.markDirty();\n section.renderNode.markDirty();\n\n section.renderNode.childNodes.insertAfter(newRenderNode, renderNode);\n }\n }\n if (renderNode) {\n marker = renderNode.postNode;\n }\n }\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n marker = _this4.builder.createMarker(text, markups);\n\n renderNode = renderTree.buildRenderNode(marker);\n renderNode.element = node;\n renderNode.markClean();\n section.renderNode.markDirty();\n\n var previousRenderNode = previousMarker && previousMarker.renderNode;\n section.markers.insertAfter(marker, previousMarker);\n section.renderNode.childNodes.insertAfter(renderNode, previousRenderNode);\n }\n\n if (renderNode) {\n seenRenderNodes.push(renderNode);\n }\n previousMarker = marker;\n });\n\n var renderNode = section.renderNode.childNodes.head;\n while (renderNode) {\n if (seenRenderNodes.indexOf(renderNode) === -1) {\n renderNode.scheduleForRemoval();\n }\n renderNode = renderNode.next;\n }\n }\n }]);\n\n return DOMParser;\n })();\n\n exports['default'] = DOMParser;\n});","define('mobiledoc-kit/parsers/html', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/parsers/dom'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitParsersDom) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var HTMLParser = (function () {\n function HTMLParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, HTMLParser);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass builder to HTMLParser', builder);\n this.builder = builder;\n this.options = options;\n }\n\n /**\n * @param {String} html to parse\n * @return {Post} A post abstract\n */\n\n _createClass(HTMLParser, [{\n key: 'parse',\n value: function parse(html) {\n var dom = (0, _mobiledocKitUtilsDomUtils.parseHTML)(html);\n var parser = new _mobiledocKitParsersDom['default'](this.builder, this.options);\n return parser.parse(dom);\n }\n }]);\n\n return HTMLParser;\n })();\n\n exports['default'] = HTMLParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var version = _ref.version;\n var sectionData = _ref.sections;\n\n try {\n var markerTypes = sectionData[0];\n var sections = sectionData[1];\n\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this2 = this;\n\n sections.forEach(function (section) {\n return _this2.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ' + type, false);\n }\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref3, post) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var type = _ref32[0];\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref4, post) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var src = _ref42[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 3);\n\n var type = _ref62[0];\n var tagName = _ref62[1];\n var items = _ref62[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this3 = this;\n\n items.forEach(function (i) {\n return _this3.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this4 = this;\n\n markers.forEach(function (m) {\n return _this4.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref7, parent) {\n var _this5 = this;\n\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var markerTypeIndexes = _ref72[0];\n var closeCount = _ref72[1];\n var value = _ref72[2];\n\n markerTypeIndexes.forEach(function (index) {\n _this5.markups.push(_this5.markerTypes[index]);\n });\n var marker = this.builder.createMarker(value, this.markups.slice());\n parent.markers.append(marker);\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var version = _ref.version;\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var type = _ref52[0];\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var type = _ref62[0];\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var type = _ref72[0];\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var type = _ref82[0];\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE:\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value),\n _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3),\n atomName = _getAtomTypeFromIndex2[0],\n atomValue = _getAtomTypeFromIndex2[1],\n atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc03, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var version = _ref.version;\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var type = _ref52[0];\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var type = _ref62[0];\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var type = _ref72[0];\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var type = _ref82[0];\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE:\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value),\n _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3),\n atomName = _getAtomTypeFromIndex2[0],\n atomValue = _getAtomTypeFromIndex2[1],\n atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n function parseVersion(mobiledoc) {\n return mobiledoc.version;\n }\n\n exports['default'] = {\n parse: function parse(builder, mobiledoc) {\n var version = parseVersion(mobiledoc);\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc02['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false);\n }\n }\n };\n});","define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkup, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitParsersDom, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SKIPPABLE_ELEMENT_TAG_NAMES = ['style', 'head', 'title', 'meta'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n var NEWLINES = /\\n/g;\n function sanitize(text) {\n text = text.replace(NEWLINES, '');\n return text;\n }\n\n /**\n * parses an element into a section, ignoring any non-markup\n * elements contained within\n * @private\n */\n\n var SectionParser = (function () {\n function SectionParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, SectionParser);\n\n this.builder = builder;\n this.plugins = options.plugins || [];\n }\n\n _createClass(SectionParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n if (this._isSkippable(element)) {\n return [];\n }\n this.sections = [];\n this.state = {};\n\n this._updateStateFromElement(element);\n\n var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n\n if (this.state.section.isListSection) {\n this.parseListItems(childNodes);\n } else {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n _this.parseNode(el);\n });\n }\n\n this._closeCurrentSection();\n\n return this.sections;\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(childNodes) {\n var _this2 = this;\n\n var state = this.state;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n var parsed = new _this2.constructor(_this2.builder).parse(el);\n var li = parsed[0];\n if (li && li.isListItem) {\n state.section.items.append(li);\n }\n });\n }\n }, {\n key: 'runPlugins',\n value: function runPlugins(node) {\n var _this3 = this;\n\n var isNodeFinished = false;\n var env = {\n addSection: function addSection(section) {\n _this3._closeCurrentSection();\n _this3.sections.push(section);\n },\n addMarkerable: function addMarkerable(marker) {\n var state = _this3.state;\n var section = state.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable);\n if (state.text) {\n _this3._createMarker();\n }\n section.markers.append(marker);\n },\n nodeFinished: function nodeFinished() {\n isNodeFinished = true;\n }\n };\n for (var i = 0; i < this.plugins.length; i++) {\n var plugin = this.plugins[i];\n plugin(node, this.builder, env);\n if (isNodeFinished) {\n return true;\n }\n }\n return false;\n }\n }, {\n key: 'parseNode',\n value: function parseNode(node) {\n if (!this.state.section) {\n this._updateStateFromElement(node);\n }\n\n var nodeFinished = this.runPlugins(node);\n if (nodeFinished) {\n return;\n }\n\n switch (node.nodeType) {\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT:\n this.parseTextNode(node);\n break;\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT:\n this.parseElementNode(node);\n break;\n }\n }\n }, {\n key: 'parseElementNode',\n value: function parseElementNode(element) {\n var _state$markups,\n _this4 = this;\n\n var state = this.state;\n\n var markups = this._markupsFromElement(element);\n if (markups.length && state.text.length) {\n this._createMarker();\n }\n (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups));\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.childNodes, function (node) {\n _this4.parseNode(node);\n });\n\n if (markups.length && state.text.length) {\n // create the marker started for this node\n this._createMarker();\n }\n\n // pop the current markups from the stack\n state.markups.splice(-markups.length, markups.length);\n }\n }, {\n key: 'parseTextNode',\n value: function parseTextNode(textNode) {\n var state = this.state;\n\n state.text += sanitize(textNode.textContent);\n }\n }, {\n key: '_updateStateFromElement',\n value: function _updateStateFromElement(element) {\n var state = this.state;\n\n state.section = this._createSectionFromElement(element);\n state.markups = this._markupsFromElement(element);\n state.text = '';\n }\n }, {\n key: '_closeCurrentSection',\n value: function _closeCurrentSection() {\n var sections = this.sections;\n var state = this.state;\n\n if (!state.section) {\n return;\n }\n\n // close a trailing text node if it exists\n if (state.text.length) {\n this._createMarker();\n }\n\n sections.push(state.section);\n state.section = null;\n }\n }, {\n key: '_markupsFromElement',\n value: function _markupsFromElement(element) {\n var builder = this.builder;\n\n var markups = [];\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n return markups;\n }\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n if (this._isValidMarkupForElement(tagName, element)) {\n markups.push(builder.createMarkup(tagName, (0, _mobiledocKitUtilsDomUtils.getAttributes)(element)));\n }\n\n this._markupsFromElementStyle(element).forEach(function (markup) {\n return markups.push(markup);\n });\n\n return markups;\n }\n }, {\n key: '_isValidMarkupForElement',\n value: function _isValidMarkupForElement(tagName, element) {\n if (_mobiledocKitModelsMarkup.VALID_MARKUP_TAGNAMES.indexOf(tagName) === -1) {\n return false;\n } else if (tagName === 'b') {\n // google docs add a that should not\n // create a \"b\" markup\n return element.style.fontWeight !== 'normal';\n }\n return true;\n }\n }, {\n key: '_markupsFromElementStyle',\n value: function _markupsFromElementStyle(element) {\n var builder = this.builder;\n\n var markups = [];\n var _element$style = element.style;\n var fontStyle = _element$style.fontStyle;\n var fontWeight = _element$style.fontWeight;\n\n if (fontStyle === 'italic') {\n markups.push(builder.createMarkup('em'));\n }\n if (fontWeight === 'bold' || fontWeight === '700') {\n markups.push(builder.createMarkup('strong'));\n }\n return markups;\n }\n }, {\n key: '_createMarker',\n value: function _createMarker() {\n var state = this.state;\n\n var text = (0, _mobiledocKitParsersDom.transformHTMLText)(state.text);\n var marker = this.builder.createMarker(text, state.markups);\n state.section.markers.append(marker);\n state.text = '';\n }\n }, {\n key: '_getSectionDetails',\n value: function _getSectionDetails(element) {\n var sectionType = undefined,\n tagName = undefined,\n inferredTagName = false;\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n inferredTagName = true;\n } else {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_ITEM_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n } else {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n inferredTagName = true;\n }\n }\n\n return { sectionType: sectionType, tagName: tagName, inferredTagName: inferredTagName };\n }\n }, {\n key: '_createSectionFromElement',\n value: function _createSectionFromElement(element) {\n var builder = this.builder;\n\n var section = undefined;\n\n var _getSectionDetails2 = this._getSectionDetails(element);\n\n var tagName = _getSectionDetails2.tagName;\n var sectionType = _getSectionDetails2.sectionType;\n var inferredTagName = _getSectionDetails2.inferredTagName;\n\n switch (sectionType) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n section = builder.createListSection(tagName);\n break;\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n section = builder.createListItem();\n break;\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = builder.createMarkupSection(tagName);\n section._inferredTagName = inferredTagName;\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot parse section from element', false);\n }\n\n return section;\n }\n }, {\n key: '_isSkippable',\n value: function _isSkippable(element) {\n return (0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) || element.nodeType === _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT && (0, _mobiledocKitUtilsArrayUtils.contains)(SKIPPABLE_ELEMENT_TAG_NAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName));\n }\n }]);\n\n return SectionParser;\n })();\n\n exports['default'] = SectionParser;\n});","define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup-section'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkupSection) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var UL_LI_REGEX = /^\\* (.*)$/;\n var OL_LI_REGEX = /^\\d\\.? (.*)$/;\n var CR = '\\r';\n var LF = '\\n';\n var CR_REGEX = new RegExp(CR, 'g');\n var CR_LF_REGEX = new RegExp(CR + LF, 'g');\n\n var SECTION_BREAK = LF;\n\n exports.SECTION_BREAK = SECTION_BREAK;\n function normalizeLineEndings(text) {\n return text.replace(CR_LF_REGEX, LF).replace(CR_REGEX, LF);\n }\n\n var TextParser = (function () {\n function TextParser(builder, options) {\n _classCallCheck(this, TextParser);\n\n this.builder = builder;\n this.options = options;\n\n this.post = this.builder.createPost();\n this.prevSection = null;\n }\n\n /**\n * @param {String} text to parse\n * @return {Post} a post abstract\n */\n\n _createClass(TextParser, [{\n key: 'parse',\n value: function parse(text) {\n var _this = this;\n\n text = normalizeLineEndings(text);\n text.split(SECTION_BREAK).forEach(function (text) {\n var section = _this._parseSection(text);\n _this._appendSection(section);\n });\n\n return this.post;\n }\n }, {\n key: '_parseSection',\n value: function _parseSection(text) {\n var tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME,\n type = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n section = undefined;\n\n if (UL_LI_REGEX.test(text)) {\n tagName = 'ul';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(UL_LI_REGEX)[1];\n } else if (OL_LI_REGEX.test(text)) {\n tagName = 'ol';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(OL_LI_REGEX)[1];\n }\n\n var markers = [this.builder.createMarker(text)];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n var item = this.builder.createListItem(markers);\n var list = this.builder.createListSection(tagName, [item]);\n section = list;\n break;\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = this.builder.createMarkupSection(tagName, markers);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown type encountered ' + type, false);\n }\n\n return section;\n }\n }, {\n key: '_appendSection',\n value: function _appendSection(section) {\n var _this2 = this;\n\n var isSameListSection = section.isListSection && this.prevSection && this.prevSection.isListSection && this.prevSection.tagName === section.tagName;\n\n if (isSameListSection) {\n section.items.forEach(function (item) {\n _this2.prevSection.items.append(item.clone());\n });\n } else {\n this.post.sections.insertAfter(section, this.prevSection);\n this.prevSection = section;\n }\n }\n }]);\n\n return TextParser;\n })();\n\n exports['default'] = TextParser;\n});","define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/card-node', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/atom-node', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitModelsCardNode, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsAtomNode, _mobiledocKitModelsTypes, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitModelsMarkupSection, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCharacters) {\n 'use strict';\n\n var _destroyHooks;\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CARD_ELEMENT_CLASS_NAME = '__mobiledoc-card';\n exports.CARD_ELEMENT_CLASS_NAME = CARD_ELEMENT_CLASS_NAME;\n var NO_BREAK_SPACE = ' ';\n exports.NO_BREAK_SPACE = NO_BREAK_SPACE;\n var TAB_CHARACTER = ' ';\n exports.TAB_CHARACTER = TAB_CHARACTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n var ZWNJ = '‌';\n exports.ZWNJ = ZWNJ;\n var ATOM_CLASS_NAME = '-mobiledoc-kit__atom';\n exports.ATOM_CLASS_NAME = ATOM_CLASS_NAME;\n var EDITOR_HAS_NO_CONTENT_CLASS_NAME = '__has-no-content';\n exports.EDITOR_HAS_NO_CONTENT_CLASS_NAME = EDITOR_HAS_NO_CONTENT_CLASS_NAME;\n var EDITOR_ELEMENT_CLASS_NAME = '__mobiledoc-editor';\n\n exports.EDITOR_ELEMENT_CLASS_NAME = EDITOR_ELEMENT_CLASS_NAME;\n function createElementFromMarkup(doc, markup) {\n var element = doc.createElement(markup.tagName);\n Object.keys(markup.attributes).forEach(function (k) {\n element.setAttribute(k, markup.attributes[k]);\n });\n return element;\n }\n\n var TWO_SPACES = '' + SPACE + SPACE;\n var SPACE_AND_NO_BREAK = '' + SPACE + NO_BREAK_SPACE;\n var SPACES_REGEX = new RegExp(TWO_SPACES, 'g');\n var TAB_REGEX = new RegExp(_mobiledocKitUtilsCharacters.TAB, 'g');\n var endsWithSpace = function endsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.endsWith)(text, SPACE);\n };\n var startsWithSpace = function startsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.startsWith)(text, SPACE);\n };\n\n // FIXME: This can be done more efficiently with a single pass\n // building a correct string based on the original.\n function renderHTMLText(marker) {\n var text = marker.value;\n text = text.replace(SPACES_REGEX, SPACE_AND_NO_BREAK).replace(TAB_REGEX, TAB_CHARACTER);\n\n // If the first marker has a leading space or the last marker has a\n // trailing space, the browser will collapse the space when we position\n // the cursor.\n // See https://github.com/bustle/mobiledoc-kit/issues/68\n // and https://github.com/bustle/mobiledoc-kit/issues/75\n if (marker.isMarker && endsWithSpace(text) && !marker.next) {\n text = text.substr(0, text.length - 1) + NO_BREAK_SPACE;\n }\n if (marker.isMarker && startsWithSpace(text) && (!marker.prev || marker.prev.isMarker && endsWithSpace(marker.prev.value))) {\n text = NO_BREAK_SPACE + text.substr(1);\n }\n return text;\n }\n\n // ascends from element upward, returning the last parent node that is not\n // parentElement\n function penultimateParentOf(element, parentElement) {\n while (parentElement && element.parentNode !== parentElement && element.parentNode !== document.body // ensure the while loop stops\n ) {\n element = element.parentNode;\n }\n return element;\n }\n\n function renderMarkupSection(section) {\n var element = undefined;\n if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) {\n element = document.createElement(section.tagName);\n } else {\n element = document.createElement('div');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName);\n }\n\n return element;\n }\n\n function renderListSection(section) {\n return document.createElement(section.tagName);\n }\n\n function renderListItem() {\n return document.createElement('li');\n }\n\n function renderCursorPlaceholder() {\n return document.createElement('br');\n }\n\n function renderInlineCursorPlaceholder() {\n return document.createTextNode(ZWNJ);\n }\n\n function renderCard() {\n var wrapper = document.createElement('div');\n var cardElement = document.createElement('div');\n cardElement.contentEditable = false;\n (0, _mobiledocKitUtilsDomUtils.addClassName)(cardElement, CARD_ELEMENT_CLASS_NAME);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n wrapper.appendChild(cardElement);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n return { wrapper: wrapper, cardElement: cardElement };\n }\n\n /**\n * Wrap the element in all of the opened markups\n * @return {DOMElement} the wrapped element\n * @private\n */\n function wrapElement(element, openedMarkups) {\n var wrappedElement = element;\n\n for (var i = openedMarkups.length - 1; i >= 0; i--) {\n var markup = openedMarkups[i];\n var openedElement = createElementFromMarkup(document, markup);\n openedElement.appendChild(wrappedElement);\n wrappedElement = openedElement;\n }\n\n return wrappedElement;\n }\n\n // Attach the element to its parent element at the correct position based on the\n // previousRenderNode\n function attachElementToParent(element, parentElement) {\n var previousRenderNode = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n if (previousRenderNode) {\n var previousSibling = previousRenderNode.element;\n var previousSiblingPenultimate = penultimateParentOf(previousSibling, parentElement);\n parentElement.insertBefore(element, previousSiblingPenultimate.nextSibling);\n } else {\n parentElement.insertBefore(element, parentElement.firstChild);\n }\n }\n\n function renderAtom(atom, element, previousRenderNode) {\n var atomElement = document.createElement('span');\n atomElement.contentEditable = false;\n\n var wrapper = document.createElement('span');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(wrapper, ATOM_CLASS_NAME);\n var headTextNode = renderInlineCursorPlaceholder();\n var tailTextNode = renderInlineCursorPlaceholder();\n\n wrapper.appendChild(headTextNode);\n wrapper.appendChild(atomElement);\n wrapper.appendChild(tailTextNode);\n\n var wrappedElement = wrapElement(wrapper, atom.openedMarkups);\n attachElementToParent(wrappedElement, element, previousRenderNode);\n\n return {\n markupElement: wrappedElement,\n wrapper: wrapper,\n atomElement: atomElement,\n headTextNode: headTextNode,\n tailTextNode: tailTextNode\n };\n }\n\n function getNextMarkerElement(renderNode) {\n var element = renderNode.element.parentNode;\n var marker = renderNode.postNode;\n var closedCount = marker.closedMarkups.length;\n\n while (closedCount--) {\n element = element.parentNode;\n }\n return element;\n }\n\n /**\n * Render the marker\n * @param {Marker} marker the marker to render\n * @param {DOMNode} element the element to attach the rendered marker to\n * @param {RenderNode} [previousRenderNode] The render node before this one, which\n * affects the determination of where to insert this rendered marker.\n * @return {Object} With properties `element` and `markupElement`.\n * The element (textNode) that has the text for\n * this marker, and the outermost rendered element. If the marker has no\n * markups, element and markupElement will be the same textNode\n * @private\n */\n function renderMarker(marker, parentElement, previousRenderNode) {\n var text = renderHTMLText(marker);\n\n var element = document.createTextNode(text);\n var markupElement = wrapElement(element, marker.openedMarkups);\n attachElementToParent(markupElement, parentElement, previousRenderNode);\n\n return { element: element, markupElement: markupElement };\n }\n\n // Attach the render node's element to the DOM,\n // replacing the originalElement if it exists\n function attachRenderNodeElementToDOM(renderNode) {\n var originalElement = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n var element = renderNode.element;\n var hasRendered = !!originalElement;\n\n if (hasRendered) {\n var parentElement = renderNode.parent.element;\n parentElement.replaceChild(element, originalElement);\n } else {\n var parentElement = undefined,\n nextSiblingElement = undefined;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n parentElement = previousElement.parentNode;\n nextSiblingElement = previousElement.nextSibling;\n } else {\n parentElement = renderNode.parent.element;\n nextSiblingElement = parentElement.firstChild;\n }\n parentElement.insertBefore(element, nextSiblingElement);\n }\n }\n\n function removeRenderNodeSectionFromParent(renderNode, section) {\n var parent = renderNode.parent.postNode;\n parent.sections.remove(section);\n }\n\n function removeRenderNodeElementFromParent(renderNode) {\n if (renderNode.element && renderNode.element.parentNode) {\n renderNode.element.parentNode.removeChild(renderNode.element);\n }\n }\n\n function validateCards() {\n var cards = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(cards, function (card) {\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define type \"dom\", has: \"' + card.type + '\"', card.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define `render` method', !!card.render);\n });\n return cards;\n }\n\n function validateAtoms() {\n var atoms = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(atoms, function (atom) {\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define type \"dom\", has: \"' + atom.type + '\"', atom.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define `render` method', !!atom.render);\n });\n return atoms;\n }\n\n var Visitor = (function () {\n function Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Visitor);\n\n this.editor = editor;\n this.cards = validateCards(cards);\n this.atoms = validateAtoms(atoms);\n this.unknownCardHandler = unknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler;\n this.options = options;\n }\n\n _createClass(Visitor, [{\n key: '_findCard',\n value: function _findCard(cardName) {\n var card = (0, _mobiledocKitUtilsArrayUtils.detect)(this.cards, function (card) {\n return card.name === cardName;\n });\n return card || this._createUnknownCard(cardName);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(cardName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown card \"' + cardName + '\" found, but no unknownCardHandler is defined', !!this.unknownCardHandler);\n\n return {\n name: cardName,\n type: 'dom',\n render: this.unknownCardHandler,\n edit: this.unknownCardHandler\n };\n }\n }, {\n key: '_findAtom',\n value: function _findAtom(atomName) {\n var atom = (0, _mobiledocKitUtilsArrayUtils.detect)(this.atoms, function (atom) {\n return atom.name === atomName;\n });\n return atom || this._createUnknownAtom(atomName);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(atomName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown atom \"' + atomName + '\" found, but no unknownAtomHandler is defined', !!this.unknownAtomHandler);\n\n return {\n name: atomName,\n type: 'dom',\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(renderNode, post, visit) {\n if (!renderNode.element) {\n renderNode.element = document.createElement('div');\n }\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_ELEMENT_CLASS_NAME);\n if (post.hasContent) {\n (0, _mobiledocKitUtilsDomUtils.removeClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n } else {\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n }\n visit(renderNode, post.sections);\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n // Always rerender the section -- its tag name or attributes may have changed.\n // TODO make this smarter, only rerendering and replacing the element when necessary\n renderNode.element = renderMarkupSection(section);\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n if (section.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, section.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n renderNode.element = renderListSection(section);\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var visitAll = true;\n visit(renderNode, section.items, visitAll);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(renderNode, item, visit) {\n // FIXME do we need to do anything special for rerenders?\n renderNode.element = renderListItem();\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, null);\n\n if (item.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, item.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKER_TYPE,\n value: function value(renderNode, marker) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var _renderMarker = renderMarker(marker, parentElement, renderNode.prev);\n\n var element = _renderMarker.element;\n var markupElement = _renderMarker.markupElement;\n\n renderNode.element = element;\n renderNode.markupElement = markupElement;\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(renderNode, section) {\n if (renderNode.element) {\n if (renderNode.element.src !== section.src) {\n renderNode.element.src = section.src;\n }\n } else {\n var element = document.createElement('img');\n element.src = section.src;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n var nextElement = previousElement.nextSibling;\n if (nextElement) {\n nextElement.parentNode.insertBefore(element, nextElement);\n }\n }\n if (!element.parentNode) {\n renderNode.parent.element.appendChild(element);\n }\n renderNode.element = element;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(renderNode, section) {\n var originalElement = renderNode.element;\n var editor = this.editor;\n var options = this.options;\n\n var card = this._findCard(section.name);\n\n var _renderCard = renderCard();\n\n var wrapper = _renderCard.wrapper;\n var cardElement = _renderCard.cardElement;\n\n renderNode.element = wrapper;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var cardNode = new _mobiledocKitModelsCardNode['default'](editor, card, section, cardElement, options);\n renderNode.cardNode = cardNode;\n\n var initialMode = section._initialMode;\n cardNode[initialMode]();\n }\n }, {\n key: _mobiledocKitModelsTypes.ATOM_TYPE,\n value: function value(renderNode, atomModel) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var editor = this.editor;\n var options = this.options;\n\n var _renderAtom = renderAtom(atomModel, parentElement, renderNode.prev);\n\n var wrapper = _renderAtom.wrapper;\n var markupElement = _renderAtom.markupElement;\n var atomElement = _renderAtom.atomElement;\n var headTextNode = _renderAtom.headTextNode;\n var tailTextNode = _renderAtom.tailTextNode;\n\n var atom = this._findAtom(atomModel.name);\n\n var atomNode = renderNode.atomNode;\n if (!atomNode) {\n // create new AtomNode\n atomNode = new _mobiledocKitModelsAtomNode['default'](editor, atom, atomModel, atomElement, options);\n } else {\n // retarget atomNode to new atom element\n atomNode.element = atomElement;\n }\n\n atomNode.render();\n\n renderNode.atomNode = atomNode;\n renderNode.element = wrapper;\n renderNode.headTextNode = headTextNode;\n renderNode.tailTextNode = tailTextNode;\n renderNode.markupElement = markupElement;\n }\n }]);\n\n return Visitor;\n })();\n\n var destroyHooks = (_destroyHooks = {}, _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.POST_TYPE, function () /*renderNode, post*/{\n (0, _mobiledocKitUtilsAssert['default'])('post destruction is not supported by the renderer', false);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (renderNode, li) {\n removeRenderNodeSectionFromParent(renderNode, li);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKER_TYPE, function (renderNode, marker) {\n // FIXME before we render marker, should delete previous renderNode's element\n // and up until the next marker element\n\n // If an atom throws during render we may end up later destroying a renderNode\n // that has not rendered yet, so exit early here if so.\n if (!renderNode.isRendered) {\n return;\n }\n var markupElement = renderNode.markupElement;\n\n if (marker.section) {\n marker.section.markers.remove(marker);\n }\n\n if (markupElement.parentNode) {\n // if no parentNode, the browser already removed this element\n markupElement.parentNode.removeChild(markupElement);\n }\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.CARD_TYPE, function (renderNode, section) {\n if (renderNode.cardNode) {\n renderNode.cardNode.teardown();\n }\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.ATOM_TYPE, function (renderNode, atom) {\n if (renderNode.atomNode) {\n renderNode.atomNode.teardown();\n }\n\n // an atom is a kind of marker so just call its destroy hook vs copying here\n destroyHooks[_mobiledocKitModelsTypes.MARKER_TYPE](renderNode, atom);\n }), _destroyHooks);\n\n // removes children from parentNode (a RenderNode) that are scheduled for removal\n function removeDestroyedChildren(parentNode) {\n var forceRemoval = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n var child = parentNode.childNodes.head;\n var nextChild = undefined,\n method = undefined;\n while (child) {\n nextChild = child.next;\n if (child.isRemoved || forceRemoval) {\n removeDestroyedChildren(child, true);\n method = child.postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('editor-dom cannot destroy \"' + method + '\"', !!destroyHooks[method]);\n destroyHooks[method](child, child.postNode);\n parentNode.childNodes.remove(child);\n }\n child = nextChild;\n }\n }\n\n // Find an existing render node for the given postNode, or\n // create one, insert it into the tree, and return it\n function lookupNode(renderTree, parentNode, postNode, previousNode) {\n if (postNode.renderNode) {\n return postNode.renderNode;\n } else {\n var renderNode = renderTree.buildRenderNode(postNode);\n parentNode.childNodes.insertAfter(renderNode, previousNode);\n return renderNode;\n }\n }\n\n var Renderer = (function () {\n function Renderer(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Renderer);\n\n this.editor = editor;\n this.visitor = new Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options);\n this.nodes = [];\n this.hasRendered = false;\n }\n\n _createClass(Renderer, [{\n key: 'destroy',\n value: function destroy() {\n if (!this.hasRendered) {\n return;\n }\n var renderNode = this.renderTree.rootNode;\n var force = true;\n removeDestroyedChildren(renderNode, force);\n }\n }, {\n key: 'visit',\n value: function visit(renderTree, parentNode, postNodes) {\n var _this = this;\n\n var visitAll = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];\n\n var previousNode = undefined;\n postNodes.forEach(function (postNode) {\n var node = lookupNode(renderTree, parentNode, postNode, previousNode);\n if (node.isDirty || visitAll) {\n _this.nodes.push(node);\n }\n previousNode = node;\n });\n }\n }, {\n key: 'render',\n value: function render(renderTree) {\n var _this2 = this;\n\n this.hasRendered = true;\n this.renderTree = renderTree;\n var renderNode = renderTree.rootNode;\n var method = undefined,\n postNode = undefined;\n\n while (renderNode) {\n removeDestroyedChildren(renderNode);\n postNode = renderNode.postNode;\n\n method = postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]);\n // jshint -W083\n this.visitor[method](renderNode, postNode, function () {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return _this2.visit.apply(_this2, [renderTree].concat(args));\n });\n // jshint +W083\n renderNode.markClean();\n renderNode = this.nodes.shift();\n }\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-kit/renderers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.2.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, name, payload]);\n },\n openPost: function openPost() {\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n sections: [this.markerTypes, this.sections]\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.1';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n exports['default'] = {\n render: function render(post, version) {\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc02['default'].render(post);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc03['default'].render(post);\n case undefined:\n case null:\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc031['default'].render(post);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false);\n }\n }\n };\n});","define(\"mobiledoc-kit/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function detect(enumerable, callback) {\n if (enumerable.detect) {\n return enumerable.detect(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return enumerable[i];\n }\n }\n }\n }\n\n function any(enumerable, callback) {\n if (enumerable.any) {\n return enumerable.any(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return true;\n }\n }\n\n return false;\n }\n\n function every(enumerable, callback) {\n if (enumerable.every) {\n return enumerable.every(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (!callback(enumerable[i])) {\n return false;\n }\n }\n return true;\n }\n\n function toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n }\n\n /**\n * Useful for array-like things that aren't\n * actually arrays, like NodeList\n * @private\n */\n function forEach(enumerable, callback) {\n if (enumerable.forEach) {\n enumerable.forEach(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n callback(enumerable[i], i);\n }\n }\n }\n\n function filter(enumerable, conditionFn) {\n var filtered = [];\n forEach(enumerable, function (i) {\n if (conditionFn(i)) {\n filtered.push(i);\n }\n });\n return filtered;\n }\n\n /**\n * @return {Integer} the number of items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItemLength(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return offset;\n }\n\n /**\n * @return {Array} the items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItems(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return listA.slice(0, offset);\n }\n\n // return new array without falsy items like ruby's `compact`\n function compact(enumerable) {\n return filter(enumerable, function (i) {\n return !!i;\n });\n }\n\n function reduce(enumerable, callback, initialValue) {\n var previousValue = initialValue;\n forEach(enumerable, function (val, index) {\n previousValue = callback(previousValue, val, index);\n });\n return previousValue;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n function kvArrayToObject(array) {\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n\n // check shallow equality of two non-nested arrays\n function isArrayEqual(arr1, arr2) {\n var l1 = arr1.length,\n l2 = arr2.length;\n if (l1 !== l2) {\n return false;\n }\n\n for (var i = 0; i < l1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n return true;\n }\n\n // return an object with only the valid keys\n function filterObject(object) {\n var validKeys = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var result = {};\n forEach(filter(Object.keys(object), function (key) {\n return validKeys.indexOf(key) !== -1;\n }), function (key) {\n return result[key] = object[key];\n });\n return result;\n }\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function values(object) {\n return Object.keys(object).map(function (key) {\n return object[key];\n });\n }\n\n exports.detect = detect;\n exports.forEach = forEach;\n exports.any = any;\n exports.every = every;\n exports.filter = filter;\n exports.commonItemLength = commonItemLength;\n exports.commonItems = commonItems;\n exports.compact = compact;\n exports.reduce = reduce;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n exports.kvArrayToObject = kvArrayToObject;\n exports.isArrayEqual = isArrayEqual;\n exports.toArray = toArray;\n exports.filterObject = filterObject;\n exports.contains = contains;\n exports.values = values;\n});","define('mobiledoc-kit/utils/assert', ['exports', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n exports['default'] = function (message, conditional) {\n if (!conditional) {\n throw new _mobiledocKitUtilsMobiledocError['default'](message);\n }\n };\n});","define('mobiledoc-kit/utils/browser', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n isMac: function isMac() {\n return typeof window !== 'undefined' && window.navigator && /Mac/.test(window.navigator.platform);\n },\n isWin: function isWin() {\n return typeof window !== 'undefined' && window.navigator && /Win/.test(window.navigator.platform);\n }\n };\n});","define('mobiledoc-kit/utils/characters', ['exports'], function (exports) {\n 'use strict';\n\n var TAB = '\\t';\n exports.TAB = TAB;\n var ENTER = '\\n';\n exports.ENTER = ENTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n});","define('mobiledoc-kit/utils/compiler', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports.visit = visit;\n exports.compile = compile;\n exports.visitArray = visitArray;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function visit(visitor, node, opcodes) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit unknown type ' + method, !!visitor[method]);\n visitor[method](node, opcodes);\n }\n\n function compile(compiler, opcodes) {\n for (var i = 0, l = opcodes.length; i < l; i++) {\n var _opcodes$i = _toArray(opcodes[i]);\n\n var method = _opcodes$i[0];\n\n var params = _opcodes$i.slice(1);\n\n var _length = params.length;\n if (_length === 0) {\n compiler[method].call(compiler);\n } else if (_length === 1) {\n compiler[method].call(compiler, params[0]);\n } else if (_length === 2) {\n compiler[method].call(compiler, params[0], params[1]);\n } else {\n compiler[method].apply(compiler, params);\n }\n }\n }\n\n function visitArray(visitor, nodes, opcodes) {\n if (!nodes || nodes.length === 0) {\n return;\n }\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n visit(visitor, node, opcodes);\n });\n }\n});","define(\"mobiledoc-kit/utils/copy\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function shallowCopyObject(object) {\n var copy = {};\n Object.keys(object).forEach(function (key) {\n copy[key] = object[key];\n });\n return copy;\n }\n\n exports.shallowCopyObject = shallowCopyObject;\n});","define('mobiledoc-kit/utils/cursor', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/key'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKey) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n\n var Cursor = (function () {\n function Cursor(editor) {\n _classCallCheck(this, Cursor);\n\n this.editor = editor;\n this.renderTree = editor._renderTree;\n this.post = editor.post;\n }\n\n _createClass(Cursor, [{\n key: 'clearSelection',\n value: function clearSelection() {\n (0, _mobiledocKitUtilsSelectionUtils.clearSelection)();\n }\n\n /**\n * @return {Boolean} true when there is either a collapsed cursor in the\n * editor's element or a selection that is contained in the editor's element\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.editor.hasRendered && (this._hasCollapsedSelection() || this._hasSelection());\n }\n }, {\n key: 'hasSelection',\n value: function hasSelection() {\n return this.editor.hasRendered && this._hasSelection();\n }\n\n /**\n * @return {Boolean} Can the cursor be on this element?\n */\n }, {\n key: 'isAddressable',\n value: function isAddressable(element) {\n var renderTree = this.renderTree;\n\n var renderNode = renderTree.findRenderNodeFromElement(element);\n if (renderNode && renderNode.postNode.isCardSection) {\n var renderedElement = renderNode.element;\n\n // card sections have addressable text nodes containing ‌\n // as their first and last child\n if (element !== renderedElement && element !== renderedElement.firstChild && element !== renderedElement.lastChild) {\n return false;\n }\n }\n\n return !!renderNode;\n }\n\n /*\n * @return {Range} Cursor#Range object\n */\n }, {\n key: '_findNodeForPosition',\n value: function _findNodeForPosition(position) {\n var section = position.section;\n\n var node = undefined,\n offset = undefined;\n if (section.isCardSection) {\n offset = 0;\n if (position.offset === 0) {\n node = section.renderNode.element.firstChild;\n } else {\n node = section.renderNode.element.lastChild;\n }\n } else if (section.isBlank) {\n node = section.renderNode.cursorElement;\n offset = 0;\n } else {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n if (marker.isAtom) {\n if (offsetInMarker > 0) {\n // FIXME -- if there is a next marker, focus on it?\n offset = 0;\n node = marker.renderNode.tailTextNode;\n } else {\n offset = 0;\n node = marker.renderNode.headTextNode;\n }\n } else {\n node = marker.renderNode.element;\n offset = offsetInMarker;\n }\n }\n\n return { node: node, offset: offset };\n }\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n if (range.isBlank) {\n this.clearSelection();\n return;\n }\n\n var head = range.head;\n var tail = range.tail;\n var direction = range.direction;\n\n var _findNodeForPosition2 = this._findNodeForPosition(head);\n\n var headNode = _findNodeForPosition2.node;\n var headOffset = _findNodeForPosition2.offset;\n\n var _findNodeForPosition3 = this._findNodeForPosition(tail);\n\n var tailNode = _findNodeForPosition3.node;\n var tailOffset = _findNodeForPosition3.offset;\n\n this._moveToNode(headNode, headOffset, tailNode, tailOffset, direction);\n\n // Firefox sometimes doesn't keep focus in the editor after adding a card\n this.editor._ensureFocus();\n }\n }, {\n key: 'selectedText',\n value: function selectedText() {\n // FIXME remove this\n return this.selection.toString();\n }\n\n /**\n * @param {textNode} node\n * @param {integer} offset\n * @param {textNode} endNode\n * @param {integer} endOffset\n * @param {integer} direction forward or backward, default forward\n * @private\n */\n }, {\n key: '_moveToNode',\n value: function _moveToNode(node, offset, endNode, endOffset) {\n var direction = arguments.length <= 4 || arguments[4] === undefined ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : arguments[4];\n\n this.clearSelection();\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n var _ref = [endNode, endOffset, node, offset];\n node = _ref[0];\n offset = _ref[1];\n endNode = _ref[2];\n endOffset = _ref[3];\n }\n\n var range = document.createRange();\n range.setStart(node, offset);\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD && !!this.selection.extend) {\n this.selection.addRange(range);\n this.selection.extend(endNode, endOffset);\n } else {\n range.setEnd(endNode, endOffset);\n this.selection.addRange(range);\n }\n }\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var element = this.editor.element;\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange || _selectionRange.collapsed) {\n return false;\n }\n\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode) && (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.focusNode);\n }\n }, {\n key: '_hasCollapsedSelection',\n value: function _hasCollapsedSelection() {\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange) {\n return false;\n }\n\n var element = this.editor.element;\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode);\n }\n }, {\n key: 'offsets',\n get: function get() {\n if (!this.hasCursor()) {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n\n var selection = this.selection;\n var renderTree = this.renderTree;\n\n var parentNode = this.editor.element;\n selection = (0, _mobiledocKitUtilsSelectionUtils.constrainSelectionTo)(selection, parentNode);\n\n var _comparePosition = (0, _mobiledocKitUtilsSelectionUtils.comparePosition)(selection);\n\n var headNode = _comparePosition.headNode;\n var headOffset = _comparePosition.headOffset;\n var tailNode = _comparePosition.tailNode;\n var tailOffset = _comparePosition.tailOffset;\n var direction = _comparePosition.direction;\n\n var headPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, headNode, headOffset);\n var tailPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, tailNode, tailOffset);\n\n return new _mobiledocKitUtilsCursorRange['default'](headPosition, tailPosition, direction);\n }\n }, {\n key: 'selection',\n get: function get() {\n return window.getSelection();\n }\n }, {\n key: '_selectionRange',\n get: function get() {\n var selection = this.selection;\n\n if (selection.rangeCount === 0) {\n return null;\n }\n return selection.getRangeAt(0);\n }\n }]);\n\n return Cursor;\n })();\n\n exports['default'] = Cursor;\n});","define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitModelsMarker, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsKey, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n var WORD_CHAR_REGEX = /\\w|_|:/;\n\n function findParentSectionFromNode(renderTree, node) {\n var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) {\n return renderNode.postNode.isSection;\n });\n\n return renderNode && renderNode.postNode;\n }\n\n function findOffsetInMarkerable(markerable, node, offset) {\n var offsetInSection = 0;\n var marker = markerable.markers.head;\n while (marker) {\n var markerNode = marker.renderNode.element;\n if (markerNode === node) {\n return offsetInSection + offset;\n } else if (marker.isAtom) {\n if (marker.renderNode.headTextNode === node) {\n return offsetInSection;\n } else if (marker.renderNode.tailTextNode === node) {\n return offsetInSection + 1;\n }\n }\n\n offsetInSection += marker.length;\n marker = marker.next;\n }\n\n return offsetInSection;\n }\n\n function findOffsetInSection(section, node, offset) {\n if (section.isMarkerable) {\n return findOffsetInMarkerable(section, node, offset);\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('findOffsetInSection must be called with markerable or card section', section.isCardSection);\n\n var wrapperNode = section.renderNode.element;\n var endTextNode = wrapperNode.lastChild;\n if (node === endTextNode) {\n return 1;\n }\n return 0;\n }\n }\n\n var Position = undefined,\n BlankPosition = undefined;\n\n Position = (function () {\n /**\n * A position is a logical location (zero-width, or \"collapsed\") in a post,\n * typically between two characters in a section.\n * Two positions (a head and a tail) make up a {@link Range}.\n * @constructor\n */\n\n function Position(section) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var isBlank = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n _classCallCheck(this, Position);\n\n if (!isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Position must have a section that is addressable by the cursor', section && section.isLeafSection);\n (0, _mobiledocKitUtilsAssert['default'])('Position must have numeric offset', typeof offset === 'number');\n }\n\n this.section = section;\n this.offset = offset;\n this.isBlank = isBlank;\n }\n\n /**\n * @param {integer} x x-position in current viewport\n * @param {integer} y y-position in current viewport\n * @param {Editor} editor\n * @return {Position|null}\n */\n\n _createClass(Position, [{\n key: 'toRange',\n\n /**\n * Returns a range from this position to the given tail. If no explicit\n * tail is given this returns a collapsed range focused on this position.\n * @param {Position} [tail=this] The ending position\n * @return {Range}\n * @public\n */\n value: function toRange() {\n var tail = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0];\n var direction = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n return new _mobiledocKitUtilsCursorRange['default'](this, tail, direction);\n }\n }, {\n key: 'markerIn',\n\n /**\n * Returns the marker in `direction` from this position.\n * If the position is in the middle of a marker, the direction is irrelevant.\n * Otherwise, if the position is at a boundary between two markers, returns the\n * marker to the left if `direction` === BACKWARD and the marker to the right\n * if `direction` === FORWARD (assuming left-to-right text direction).\n * @param {Direction}\n * @return {Marker|undefined}\n */\n value: function markerIn(direction) {\n if (!this.isMarkerable) {\n return;\n }\n\n var marker = this.marker;\n var offsetInMarker = this.offsetInMarker;\n\n if (!marker) {\n return;\n }\n\n if (offsetInMarker > 0 && offsetInMarker < marker.length) {\n return marker;\n } else if (offsetInMarker === 0) {\n return direction === BACKWARD ? marker : marker.prev;\n } else if (offsetInMarker === marker.length) {\n return direction === FORWARD ? marker.next : marker;\n }\n }\n }, {\n key: 'isEqual',\n value: function isEqual(position) {\n return this.section === position.section && this.offset === position.offset;\n }\n\n /**\n * @return {Boolean} If this position is at the head of the post\n */\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return this.move(BACKWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the tail of the post\n */\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return this.move(FORWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the head of its section\n */\n }, {\n key: 'isHead',\n value: function isHead() {\n return this.isEqual(this.section.headPosition());\n }\n\n /**\n * @return {Boolean} If this position is at the tail of its section\n */\n }, {\n key: 'isTail',\n value: function isTail() {\n return this.isEqual(this.section.tailPosition());\n }\n\n /**\n * Move the position 1 unit in `direction`.\n *\n * @param {Number} units to move. > 0 moves right, < 0 moves left\n * @return {Position} Return a new position one unit in the given\n * direction. If the position is moving left and at the beginning of the post,\n * the same position will be returned. Same if the position is moving right and\n * at the end of the post.\n */\n }, {\n key: 'move',\n value: function move(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Position#move', typeof units === 'number');\n\n if (units < 0) {\n return this.moveLeft().move(++units);\n } else if (units > 0) {\n return this.moveRight().move(--units);\n } else {\n return this;\n }\n }\n\n /**\n * @param {Number} direction (FORWARD or BACKWARD)\n * @return {Position} The result of moving 1 \"word\" unit in `direction`\n */\n }, {\n key: 'moveWord',\n value: function moveWord(direction) {\n var isPostBoundary = direction === BACKWARD ? this.isHeadOfPost() : this.isTailOfPost();\n if (isPostBoundary) {\n return this;\n }\n\n if (!this.isMarkerable) {\n return this.move(direction);\n }\n\n var pos = this;\n\n // Helper fn to check if the pos is at the `dir` boundary of its section\n var isBoundary = function isBoundary(pos, dir) {\n return dir === BACKWARD ? pos.isHead() : pos.isTail();\n };\n // Get the char at this position (looking forward/right)\n var getChar = function getChar(pos) {\n var marker = pos.marker;\n var offsetInMarker = pos.offsetInMarker;\n\n return marker.charAt(offsetInMarker);\n };\n // Get the char in `dir` at this position\n var peekChar = function peekChar(pos, dir) {\n return dir === BACKWARD ? getChar(pos.move(BACKWARD)) : getChar(pos);\n };\n // Whether there is an atom in `dir` from this position\n var isAtom = function isAtom(pos, dir) {\n // Special case when position is at end, the marker associated with it is\n // the marker to its left. Normally `pos#marker` is the marker to the right of the pos's offset.\n if (dir === BACKWARD && pos.isTail() && pos.marker.isAtom) {\n return true;\n }\n return dir === BACKWARD ? pos.move(BACKWARD).marker.isAtom : pos.marker.isAtom;\n };\n\n if (isBoundary(pos, direction)) {\n // extend movement into prev/next section\n return pos.move(direction).moveWord(direction);\n }\n\n var seekWord = function seekWord(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && !WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first word char\n while (seekWord(pos)) {\n pos = pos.move(direction);\n }\n\n if (isAtom(pos, direction)) {\n return pos.move(direction);\n }\n\n var seekBoundary = function seekBoundary(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first boundary position\n while (seekBoundary(pos)) {\n pos = pos.move(direction);\n }\n\n return pos;\n }\n\n /**\n * The position to the left of this position.\n * If this position is the post's headPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveLeft',\n value: function moveLeft() {\n if (this.isHead()) {\n var prev = this.section.previousLeafSection();\n return prev ? prev.tailPosition() : this;\n } else {\n var offset = this.offset - 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset);\n if (code >= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[1]) {\n offset = offset - 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n\n /**\n * The position to the right of this position.\n * If this position is the post's tailPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveRight',\n value: function moveRight() {\n if (this.isTail()) {\n var next = this.section.nextLeafSection();\n return next ? next.headPosition() : this;\n } else {\n var offset = this.offset + 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset - 1);\n if (code >= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[1]) {\n offset = offset + 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n var _this = this;\n\n var post = this.section.post;\n var leafSectionIndex = undefined;\n post.walkAllLeafSections(function (section, index) {\n if (section === _this.section) {\n leafSectionIndex = index;\n }\n });\n return leafSectionIndex;\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return this.section && this.section.isMarkerable;\n }\n\n /**\n * Returns the marker at this position, in the backward direction\n * (i.e., the marker to the left of the cursor if the cursor is on a marker boundary and text is left-to-right)\n * @return {Marker|undefined}\n */\n }, {\n key: 'marker',\n get: function get() {\n return this.isMarkerable && this.markerPosition.marker;\n }\n }, {\n key: 'offsetInMarker',\n get: function get() {\n return this.markerPosition.offset;\n }\n }, {\n key: 'markerPosition',\n\n /**\n * @private\n */\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get markerPosition without a section', !!this.section);\n (0, _mobiledocKitUtilsAssert['default'])('cannot get markerPosition of a non-markerable', !!this.section.isMarkerable);\n return this.section.markerPositionAtOffset(this.offset);\n }\n }], [{\n key: 'atPoint',\n value: function atPoint(x, y, editor) {\n var _renderTree = editor._renderTree;\n var rootElement = editor.element;\n\n var elementFromPoint = document.elementFromPoint(x, y);\n if (!(0, _mobiledocKitUtilsDomUtils.containsNode)(rootElement, elementFromPoint)) {\n return;\n }\n\n var _findOffsetInNode = (0, _mobiledocKitUtilsSelectionUtils.findOffsetInNode)(elementFromPoint, { left: x, top: y });\n\n var node = _findOffsetInNode.node;\n var offset = _findOffsetInNode.offset;\n\n return Position.fromNode(_renderTree, node, offset);\n }\n }, {\n key: 'blankPosition',\n value: function blankPosition() {\n return new BlankPosition();\n }\n }, {\n key: 'fromNode',\n value: function fromNode(renderTree, node, offset) {\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n return Position.fromTextNode(renderTree, node, offset);\n } else {\n return Position.fromElementNode(renderTree, node, offset);\n }\n }\n }, {\n key: 'fromTextNode',\n value: function fromTextNode(renderTree, textNode, offsetInNode) {\n var renderNode = renderTree.getElementRenderNode(textNode);\n var section = undefined,\n offsetInSection = undefined;\n\n if (renderNode) {\n var marker = renderNode.postNode;\n section = marker.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for mapped text node \"' + textNode.textContent + '\"', !!section);\n offsetInSection = section.offsetOfMarker(marker, offsetInNode);\n } else {\n // all text nodes should be rendered by markers except:\n // * text nodes inside cards\n // * text nodes created by the browser during text input\n // both of these should have rendered parent sections, though\n section = findParentSectionFromNode(renderTree, textNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for un-mapped text node \"' + textNode.textContent + '\"', !!section);\n\n offsetInSection = findOffsetInSection(section, textNode, offsetInNode);\n }\n\n return new Position(section, offsetInSection);\n }\n }, {\n key: 'fromElementNode',\n value: function fromElementNode(renderTree, elementNode, offset) {\n var position = undefined;\n\n // The browser may change the reported selection to equal the editor's root\n // element if the user clicks an element that is immediately removed,\n // which can happen when clicking to remove a card.\n if (elementNode === renderTree.rootElement) {\n var post = renderTree.rootNode.postNode;\n position = offset === 0 ? post.headPosition() : post.tailPosition();\n } else {\n var section = findParentSectionFromNode(renderTree, elementNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section from element node', !!section);\n\n if (section.isCardSection) {\n // Selections in cards are usually made on a text node\n // containing a ‌ on one side or the other of the card but\n // some scenarios (Firefox) will result in selecting the\n // card's wrapper div. If the offset is 2 we've selected\n // the final zwnj and should consider the cursor at the\n // end of the card (offset 1). Otherwise, the cursor is at\n // the start of the card\n position = offset < 2 ? section.headPosition() : section.tailPosition();\n } else {\n\n // In Firefox it is possible for the cursor to be on an atom's wrapper\n // element. (In Chrome/Safari, the browser corrects this to be on\n // one of the text nodes surrounding the wrapper).\n // This code corrects for when the browser reports the cursor position\n // to be on the wrapper element itself\n var renderNode = renderTree.getElementRenderNode(elementNode);\n var postNode = renderNode && renderNode.postNode;\n if (postNode && postNode.isAtom) {\n var sectionOffset = section.offsetOfMarker(postNode);\n if (offset > 1) {\n // we are on the tail side of the atom\n sectionOffset += postNode.length;\n }\n position = new Position(section, sectionOffset);\n } else {\n // The offset is 0 if the cursor is on a non-atom-wrapper element node\n // (e.g., a
    tag in a blank markup section)\n position = section.headPosition();\n }\n }\n }\n\n return position;\n }\n }]);\n\n return Position;\n })();\n\n BlankPosition = (function (_Position) {\n _inherits(BlankPosition, _Position);\n\n function BlankPosition() {\n _classCallCheck(this, BlankPosition);\n\n _get(Object.getPrototypeOf(BlankPosition.prototype), 'constructor', this).call(this, null, 0, true);\n }\n\n _createClass(BlankPosition, [{\n key: 'isEqual',\n value: function isEqual(other) {\n return other && other.isBlank;\n }\n }, {\n key: 'toRange',\n value: function toRange() {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return false;\n }\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return false;\n }\n }, {\n key: 'isHead',\n value: function isHead() {\n return false;\n }\n }, {\n key: 'isTail',\n value: function isTail() {\n return false;\n }\n }, {\n key: 'move',\n value: function move() {\n return this;\n }\n }, {\n key: 'moveWord',\n value: function moveWord() {\n return this;\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('must implement get leafSectionIndex', false);\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return false;\n }\n }, {\n key: 'marker',\n get: function get() {\n return false;\n }\n }, {\n key: 'markerPosition',\n get: function get() {\n return {};\n }\n }]);\n\n return BlankPosition;\n })(Position);\n\n exports['default'] = Position;\n});","define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsKey, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * A logical range of a {@link Post}.\n * Usually an instance of Range will be read from the {@link Editor#range} property,\n * but it may be useful to instantiate a range directly when programmatically modifying a Post.\n */\n\n var Range = (function () {\n /**\n * @param {Position} head\n * @param {Position} [tail=head]\n * @param {Direction} [direction=null]\n * @return {Range}\n * @private\n */\n\n function Range(head) {\n var tail = arguments.length <= 1 || arguments[1] === undefined ? head : arguments[1];\n var direction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n return (function () {\n _classCallCheck(this, Range);\n\n /** @property {Position} head */\n this.head = head;\n\n /** @property {Position} tail */\n this.tail = tail;\n\n /** @property {Direction} direction */\n this.direction = direction;\n }).apply(this, arguments);\n }\n\n /**\n * Shorthand to create a new range from a section(s) and offset(s).\n * When given only a head section and offset, creates a collapsed range.\n * @param {Section} headSection\n * @param {number} headOffset\n * @param {Section} [tailSection=headSection]\n * @param {number} [tailOffset=headOffset]\n * @param {Direction} [direction=null]\n * @return {Range}\n */\n\n _createClass(Range, [{\n key: 'trimTo',\n\n /**\n * @param {Markerable} section\n * @return {Range} A range that is constrained to only the part that\n * includes the section.\n * FIXME -- if the section isn't the head or tail, it's assumed to be\n * wholly contained. It's possible to call `trimTo` with a selection that is\n * outside of the range, though, which would invalidate that assumption.\n * There's no efficient way to determine if a section is within a range, yet.\n * @private\n */\n value: function trimTo(section) {\n var length = section.length;\n\n var headOffset = section === this.head.section ? Math.min(this.head.offset, length) : 0;\n var tailOffset = section === this.tail.section ? Math.min(this.tail.offset, length) : length;\n\n return Range.create(section, headOffset, section, tailOffset);\n }\n\n /**\n * Expands the range 1 unit in the given direction\n * If the range is expandable in the given direction, always returns a\n * non-collapsed range.\n * @param {Number} units If units is > 0, the range is extended to the right,\n * otherwise range is extended to the left.\n * @return {Range}\n * @public\n */\n }, {\n key: 'extend',\n value: function extend(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Range#extend', typeof units === 'number');\n\n if (units === 0) {\n return this;\n }\n\n var head = this.head;\n var tail = this.tail;\n var currentDirection = this.direction;\n\n switch (currentDirection) {\n case _mobiledocKitUtilsKey.DIRECTION.FORWARD:\n return new Range(head, tail.move(units), currentDirection);\n case _mobiledocKitUtilsKey.DIRECTION.BACKWARD:\n return new Range(head.move(units), tail, currentDirection);\n default:\n var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n return new Range(head, tail, newDirection).extend(units);\n }\n }\n\n /**\n * Moves this range 1 unit in the given direction.\n * If the range is collapsed, returns a collapsed range shifted by 1 unit,\n * otherwise collapses this range to the position at the `direction` end of the range.\n * Always returns a collapsed range.\n * @param {Direction} direction\n * @return {Range}\n * @public\n */\n }, {\n key: 'move',\n value: function move(direction) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass DIRECTION.FORWARD (' + _mobiledocKitUtilsKey.DIRECTION.FORWARD + ') or DIRECTION.BACKWARD (' + _mobiledocKitUtilsKey.DIRECTION.BACKWARD + ') to Range#move', direction === _mobiledocKitUtilsKey.DIRECTION.FORWARD || direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD);\n\n var focusedPosition = this.focusedPosition;\n var isCollapsed = this.isCollapsed;\n\n if (isCollapsed) {\n return new Range(focusedPosition.move(direction));\n } else {\n return this._collapse(direction);\n }\n }\n\n /**\n * expand a range to all markers matching a given check\n *\n * @param {Function} detectMarker\n * @return {Range} The expanded range\n *\n * @public\n */\n }, {\n key: 'expandByMarker',\n value: function expandByMarker(detectMarker) {\n var head = this.head;\n var tail = this.tail;\n var direction = this.direction;\n var headSection = head.section;\n\n if (headSection !== tail.section) {\n throw new Error('#expandByMarker does not work across sections. Perhaps you should confirm the range is collapsed');\n }\n\n var firstNotMatchingDetect = function firstNotMatchingDetect(i) {\n return !detectMarker(i);\n };\n\n var headMarker = head.section.markers.detect(firstNotMatchingDetect, head.marker, true);\n headMarker = headMarker && headMarker.next || head.marker;\n var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker));\n\n var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker);\n tailMarker = tailMarker && tailMarker.prev || tail.marker;\n var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length);\n\n return headPosition.toRange(tailPosition, direction);\n }\n }, {\n key: '_collapse',\n value: function _collapse(direction) {\n return new Range(direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail);\n }\n }, {\n key: 'isEqual',\n value: function isEqual(other) {\n return other && this.head.isEqual(other.head) && this.tail.isEqual(other.tail);\n }\n }, {\n key: 'focusedPosition',\n get: function get() {\n return this.direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.head.isBlank && this.tail.isBlank;\n }\n\n // \"legacy\" APIs\n }, {\n key: 'headSection',\n get: function get() {\n return this.head.section;\n }\n }, {\n key: 'tailSection',\n get: function get() {\n return this.tail.section;\n }\n }, {\n key: 'headSectionOffset',\n get: function get() {\n return this.head.offset;\n }\n }, {\n key: 'tailSectionOffset',\n get: function get() {\n return this.tail.offset;\n }\n }, {\n key: 'isCollapsed',\n get: function get() {\n return this.head.isEqual(this.tail);\n }\n }, {\n key: 'headMarker',\n get: function get() {\n return this.head.marker;\n }\n }, {\n key: 'tailMarker',\n get: function get() {\n return this.tail.marker;\n }\n }, {\n key: 'headMarkerOffset',\n get: function get() {\n return this.head.offsetInMarker;\n }\n }, {\n key: 'tailMarkerOffset',\n get: function get() {\n return this.tail.offsetInMarker;\n }\n }], [{\n key: 'create',\n value: function create(headSection, headOffset) {\n var tailSection = arguments.length <= 2 || arguments[2] === undefined ? headSection : arguments[2];\n var tailOffset = arguments.length <= 3 || arguments[3] === undefined ? headOffset : arguments[3];\n var direction = arguments.length <= 4 || arguments[4] === undefined ? null : arguments[4];\n return (function () {\n return new Range(new _mobiledocKitUtilsCursorPosition['default'](headSection, headOffset), new _mobiledocKitUtilsCursorPosition['default'](tailSection, tailOffset), direction);\n })();\n }\n }, {\n key: 'blankRange',\n value: function blankRange() {\n return new Range(_mobiledocKitUtilsCursorPosition['default'].blankPosition(), _mobiledocKitUtilsCursorPosition['default'].blankPosition());\n }\n }]);\n\n return Range;\n })();\n\n exports['default'] = Range;\n});","define(\"mobiledoc-kit/utils/deprecate\", [\"exports\"], function (exports) {\n /**\n * Usage:\n * Without a conditional, always prints deprecate message:\n * `deprecate('This is deprecated')`\n *\n * Conditional deprecation, works similarly to `assert`, prints deprecation if\n * conditional is false:\n * `deprecate('Deprecated only if foo !== bar', foo === bar)`\n */\n \"use strict\";\n\n exports[\"default\"] = deprecate;\n\n function deprecate(message) {\n var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (!conditional) {\n console.log(\"[mobiledoc-kit] [DEPRECATED]: \" + message); // jshint ignore:line\n }\n }\n});","define('mobiledoc-kit/utils/dom-utils', ['exports', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n COMMENT: 8\n };\n\n exports.NODE_TYPES = NODE_TYPES;\n function isTextNode(node) {\n return node.nodeType === NODE_TYPES.TEXT;\n }\n\n function isCommentNode(node) {\n return node.nodeType === NODE_TYPES.COMMENT;\n }\n\n function isElementNode(node) {\n return node.nodeType === NODE_TYPES.ELEMENT;\n }\n\n // perform a pre-order tree traversal of the dom, calling `callbackFn(node)`\n // for every node for which `conditionFn(node)` is true\n function walkDOM(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n var conditionFn = arguments.length <= 2 || arguments[2] === undefined ? function () {\n return true;\n } : arguments[2];\n\n var currentNode = topNode;\n\n if (conditionFn(currentNode)) {\n callbackFn(currentNode);\n }\n\n currentNode = currentNode.firstChild;\n\n while (currentNode) {\n walkDOM(currentNode, callbackFn, conditionFn);\n currentNode = currentNode.nextSibling;\n }\n }\n\n function walkTextNodes(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n\n var conditionFn = function conditionFn(node) {\n return isTextNode(node);\n };\n walkDOM(topNode, callbackFn, conditionFn);\n }\n\n function clearChildNodes(element) {\n while (element.childNodes.length) {\n element.removeChild(element.childNodes[0]);\n }\n }\n\n /**\n * @return {Boolean} true when the child node is contained or the same as\n * (e.g., inclusive containment) the parent node\n * see https://github.com/webmodules/node-contains/blob/master/index.js\n * Mimics the behavior of `Node.contains`, which is broken in IE 10\n * @private\n */\n function containsNode(parentNode, childNode) {\n if (parentNode === childNode) {\n return true;\n }\n var position = parentNode.compareDocumentPosition(childNode);\n return !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY);\n }\n\n /**\n * converts the element's NamedNodeMap of attrs into\n * an object with key-value pairs\n * @param {DOMNode} element\n * @return {Object} key-value pairs\n * @private\n */\n function getAttributes(element) {\n var result = {};\n if (element.hasAttributes()) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.attributes, function (_ref) {\n var name = _ref.name;\n var value = _ref.value;\n\n result[name] = value;\n });\n }\n return result;\n }\n\n function addClassName(element, className) {\n element.classList.add(className);\n }\n\n function removeClassName(element, className) {\n element.classList.remove(className);\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n\n function parseHTML(html) {\n var div = document.createElement('div');\n div.innerHTML = html;\n return div;\n }\n\n function serializeHTML(node) {\n var div = document.createElement('div');\n div.appendChild(node);\n return div.innerHTML;\n }\n\n exports.containsNode = containsNode;\n exports.clearChildNodes = clearChildNodes;\n exports.getAttributes = getAttributes;\n exports.walkDOM = walkDOM;\n exports.walkTextNodes = walkTextNodes;\n exports.addClassName = addClassName;\n exports.removeClassName = removeClassName;\n exports.normalizeTagName = normalizeTagName;\n exports.isTextNode = isTextNode;\n exports.isCommentNode = isCommentNode;\n exports.isElementNode = isElementNode;\n exports.parseHTML = parseHTML;\n exports.serializeHTML = serializeHTML;\n});","define('mobiledoc-kit/utils/element-map', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // start at one to make the falsy semantics easier\n var uuidGenerator = 1;\n\n var ElementMap = (function () {\n function ElementMap() {\n _classCallCheck(this, ElementMap);\n\n this._map = {};\n }\n\n _createClass(ElementMap, [{\n key: 'set',\n value: function set(key, value) {\n var uuid = key._uuid;\n if (!uuid) {\n key._uuid = uuid = '' + uuidGenerator++;\n }\n this._map[uuid] = value;\n }\n }, {\n key: 'get',\n value: function get(key) {\n if (key._uuid) {\n return this._map[key._uuid];\n }\n return null;\n }\n }, {\n key: 'remove',\n value: function remove(key) {\n (0, _mobiledocKitUtilsAssert['default'])('tried to fetch a value for an element not seen before', !!key._uuid);\n delete this._map[key._uuid];\n }\n }]);\n\n return ElementMap;\n })();\n\n exports['default'] = ElementMap;\n});","define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function getEventTargetMatchingTag(tagName, target, container) {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n // Traverses up DOM from an event target to find the node matching specifed tag\n while (target && target !== container) {\n if ((0, _mobiledocKitUtilsDomUtils.normalizeTagName)(target.tagName) === tagName) {\n return target;\n }\n target = target.parentNode;\n }\n }\n\n function getElementRelativeOffset(element) {\n var offset = { left: 0, top: -window.pageYOffset };\n var offsetParent = element.offsetParent;\n var offsetParentPosition = window.getComputedStyle(offsetParent).position;\n var offsetParentRect;\n\n if (offsetParentPosition === 'relative') {\n offsetParentRect = offsetParent.getBoundingClientRect();\n offset.left = offsetParentRect.left;\n offset.top = offsetParentRect.top;\n }\n return offset;\n }\n\n function getElementComputedStyleNumericProp(element, prop) {\n return parseFloat(window.getComputedStyle(element)[prop]);\n }\n\n function positionElementToRect(element, rect, topOffset, leftOffset) {\n var relativeOffset = getElementRelativeOffset(element);\n var style = element.style;\n var round = Math.round;\n var left, top;\n\n topOffset = topOffset || 0;\n leftOffset = leftOffset || 0;\n left = round(rect.left - relativeOffset.left - leftOffset);\n top = round(rect.top - relativeOffset.top - topOffset);\n style.left = left + 'px';\n style.top = top + 'px';\n return { left: left, top: top };\n }\n\n function positionElementHorizontallyCenteredToRect(element, rect, topOffset) {\n var horizontalCenter = element.offsetWidth / 2 - rect.width / 2;\n return positionElementToRect(element, rect, topOffset, horizontalCenter);\n }\n\n function positionElementCenteredBelow(element, belowElement) {\n var elementMargin = getElementComputedStyleNumericProp(element, 'marginTop');\n return positionElementHorizontallyCenteredToRect(element, belowElement.getBoundingClientRect(), -element.offsetHeight - elementMargin);\n }\n\n function setData(element, name, value) {\n if (element.dataset) {\n element.dataset[name] = value;\n } else {\n var dataName = (0, _mobiledocKitUtilsStringUtils.dasherize)(name);\n return element.setAttribute(dataName, value);\n }\n }\n\n exports.setData = setData;\n exports.getEventTargetMatchingTag = getEventTargetMatchingTag;\n exports.getElementRelativeOffset = getElementRelativeOffset;\n exports.getElementComputedStyleNumericProp = getElementComputedStyleNumericProp;\n exports.positionElementToRect = positionElementToRect;\n exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect;\n exports.positionElementCenteredBelow = positionElementCenteredBelow;\n});","define('mobiledoc-kit/utils/environment', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n hasDOM: function hasDOM() {\n return typeof document !== 'undefined';\n }\n };\n});","define(\"mobiledoc-kit/utils/fixed-queue\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var FixedQueue = (function () {\n function FixedQueue() {\n var length = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\n _classCallCheck(this, FixedQueue);\n\n this._maxLength = length;\n this._items = [];\n }\n\n _createClass(FixedQueue, [{\n key: \"pop\",\n value: function pop() {\n return this._items.pop();\n }\n }, {\n key: \"push\",\n value: function push(item) {\n this._items.push(item);\n if (this.length > this._maxLength) {\n this._items.shift();\n }\n }\n }, {\n key: \"clear\",\n value: function clear() {\n this._items = [];\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this._items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this._items.length;\n }\n }]);\n\n return FixedQueue;\n })();\n\n exports[\"default\"] = FixedQueue;\n});","define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.modifierMask = modifierMask;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * @typedef Direction\n * @enum {number}\n * @property {number} FORWARD\n * @property {number} BACKWARD\n */\n var DIRECTION = {\n FORWARD: 1,\n BACKWARD: -1\n };\n exports.DIRECTION = DIRECTION;\n var MODIFIERS = {\n META: 1, // also called \"command\" on OS X\n CTRL: 2,\n SHIFT: 4,\n ALT: 8 // also called \"option\" on OS X\n };\n\n exports.MODIFIERS = MODIFIERS;\n\n function modifierMask(event) {\n var metaKey = event.metaKey;\n var shiftKey = event.shiftKey;\n var ctrlKey = event.ctrlKey;\n var altKey = event.altKey;\n\n var modVal = function modVal(val, modifier) {\n return val && modifier || 0;\n };\n return modVal(metaKey, MODIFIERS.META) + modVal(shiftKey, MODIFIERS.SHIFT) + modVal(ctrlKey, MODIFIERS.CTRL) + modVal(altKey, MODIFIERS.ALT);\n }\n\n var SPECIAL_KEYS = {\n BACKSPACE: _mobiledocKitUtilsKeycodes['default'].BACKSPACE,\n TAB: _mobiledocKitUtilsKeycodes['default'].TAB,\n ENTER: _mobiledocKitUtilsKeycodes['default'].ENTER,\n ESC: _mobiledocKitUtilsKeycodes['default'].ESC,\n SPACE: _mobiledocKitUtilsKeycodes['default'].SPACE,\n PAGEUP: _mobiledocKitUtilsKeycodes['default'].PAGEUP,\n PAGEDOWN: _mobiledocKitUtilsKeycodes['default'].PAGEDOWN,\n END: _mobiledocKitUtilsKeycodes['default'].END,\n HOME: _mobiledocKitUtilsKeycodes['default'].HOME,\n LEFT: _mobiledocKitUtilsKeycodes['default'].LEFT,\n UP: _mobiledocKitUtilsKeycodes['default'].UP,\n RIGHT: _mobiledocKitUtilsKeycodes['default'].RIGHT,\n DOWN: _mobiledocKitUtilsKeycodes['default'].DOWN,\n INS: _mobiledocKitUtilsKeycodes['default'].INS,\n DEL: _mobiledocKitUtilsKeycodes['default'].DELETE\n };\n\n exports.SPECIAL_KEYS = SPECIAL_KEYS;\n // heuristic for determining if `event` is a key event\n function isKeyEvent(event) {\n return (/^key/.test(event.type)\n );\n }\n\n /**\n * An abstraction around a KeyEvent\n * that key listeners in the editor can use\n * to determine what sort of key was pressed\n */\n var Key = (function () {\n function Key(event) {\n _classCallCheck(this, Key);\n\n this.keyCode = event.keyCode;\n this.charCode = event.charCode;\n this.event = event;\n this.modifierMask = modifierMask(event);\n }\n\n _createClass(Key, [{\n key: 'toString',\n value: function toString() {\n if (this.isTab()) {\n return _mobiledocKitUtilsCharacters.TAB;\n }\n return String.fromCharCode(this.charCode);\n }\n }, {\n key: 'isEscape',\n value: function isEscape() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ESC;\n }\n }, {\n key: 'isDelete',\n value: function isDelete() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].BACKSPACE || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE;\n }\n }, {\n key: 'isForwardDelete',\n value: function isForwardDelete() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE;\n }\n }, {\n key: 'isArrow',\n value: function isArrow() {\n return this.isHorizontalArrow() || this.isVerticalArrow();\n }\n }, {\n key: 'isHorizontalArrow',\n value: function isHorizontalArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT || this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT;\n }\n }, {\n key: 'isHorizontalArrowWithoutModifiersOtherThanShift',\n value: function isHorizontalArrowWithoutModifiersOtherThanShift() {\n return this.isHorizontalArrow() && !(this.ctrlKey || this.metaKey || this.altKey);\n }\n }, {\n key: 'isVerticalArrow',\n value: function isVerticalArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].UP || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DOWN;\n }\n }, {\n key: 'isLeftArrow',\n value: function isLeftArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT;\n }\n }, {\n key: 'isRightArrow',\n value: function isRightArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT;\n }\n }, {\n key: 'isHome',\n value: function isHome() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].HOME;\n }\n }, {\n key: 'isEnd',\n value: function isEnd() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].END;\n }\n }, {\n key: 'isSpace',\n value: function isSpace() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SPACE;\n }\n }, {\n key: 'isTab',\n value: function isTab() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].TAB;\n }\n }, {\n key: 'isEnter',\n value: function isEnter() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ENTER;\n }\n\n /**\n * If the shift key is depressed.\n * For example, while holding down meta+shift, pressing the \"v\"\n * key would result in an event whose `Key` had `isShift()` with a truthy value,\n * because the shift key is down when pressing the \"v\".\n * @see {isShiftKey} which checks if the key is actually the shift key itself.\n * @return {bool}\n */\n }, {\n key: 'isShift',\n value: function isShift() {\n return this.shiftKey;\n }\n\n /*\n * If the key is the actual shift key. This is false when the shift key\n * is held down and the source `event` is not the shift key.\n * @see {isShift}\n * @return {bool}\n */\n }, {\n key: 'isShiftKey',\n value: function isShiftKey() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SHIFT;\n }\n\n /*\n * If the key is the actual alt key (aka \"option\" on mac). This is false when the alt key\n * is held down and the source `event` is not the alt key.\n * @return {bool}\n */\n }, {\n key: 'isAltKey',\n value: function isAltKey() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ALT;\n }\n\n /*\n * If the key is the actual ctrl key. This is false when the ctrl key\n * is held down and the source `event` is not the ctrl key.\n * @return {bool}\n */\n }, {\n key: 'isCtrlKey',\n value: function isCtrlKey() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].CTRL;\n }\n }, {\n key: 'hasModifier',\n value: function hasModifier(modifier) {\n return modifier & this.modifierMask;\n }\n }, {\n key: 'hasAnyModifier',\n value: function hasAnyModifier() {\n return !!this.modifierMask;\n }\n }, {\n key: 'isPrintable',\n\n /**\n * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position\n * and http://stackoverflow.com/a/12467610/137784\n */\n value: function isPrintable() {\n if (this.ctrlKey || this.metaKey) {\n return false;\n }\n\n var code = this.keyCode;\n\n // Firefox calls keypress events for arrow keys, but they should not be\n // considered printable\n if (this.isArrow()) {\n return false;\n }\n\n return code !== 0 || this.toString().length > 0 || code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || // number keys\n this.isSpace() || this.isTab() || this.isEnter() || code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || // letter keys\n code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9 || // numpad keys\n code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || // punctuation\n code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['\"'] ||\n // FIXME the IME action seems to get lost when we issue an `editor.deleteSelection`\n // before it (in Chrome)\n code === _mobiledocKitUtilsKeycodes['default'].IME;\n }\n }, {\n key: 'direction',\n get: function get() {\n switch (true) {\n case this.isDelete():\n return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n case this.isHorizontalArrow():\n return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n }\n }\n }, {\n key: 'ctrlKey',\n get: function get() {\n return MODIFIERS.CTRL & this.modifierMask;\n }\n }, {\n key: 'metaKey',\n get: function get() {\n return MODIFIERS.META & this.modifierMask;\n }\n }, {\n key: 'shiftKey',\n get: function get() {\n return MODIFIERS.SHIFT & this.modifierMask;\n }\n }, {\n key: 'altKey',\n get: function get() {\n return MODIFIERS.ALT & this.modifierMask;\n }\n }], [{\n key: 'fromEvent',\n value: function fromEvent(event) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass a Key event to Key.fromEvent', event && isKeyEvent(event));\n return new Key(event);\n }\n }]);\n\n return Key;\n })();\n\n exports['default'] = Key;\n});","define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n BACKSPACE: 8,\n SPACE: 32,\n ENTER: 13,\n SHIFT: 16,\n ESC: 27,\n DELETE: 46,\n '0': 48,\n '9': 57,\n A: 65,\n Z: 90,\n a: 97,\n z: 122,\n 'NUMPAD_0': 186,\n 'NUMPAD_9': 111,\n ';': 186,\n '.': 190,\n '`': 192,\n '[': 219,\n '\"': 222,\n\n // Input Method Editor uses multiple keystrokes to display characters.\n // Example on mac: press option-i then i. This fires 2 key events in Chrome\n // with keyCode 229 and displays ˆ and then î.\n // See http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html#fixed-virtual-key-codes\n IME: 229,\n\n TAB: 9,\n PAGEUP: 33,\n PAGEDOWN: 34,\n END: 35,\n HOME: 36,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n INS: 45,\n META: 91,\n ALT: 18,\n CTRL: 17\n };\n});","define(\"mobiledoc-kit/utils/linked-item\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var LinkedItem = function LinkedItem() {\n _classCallCheck(this, LinkedItem);\n\n this.next = null;\n this.prev = null;\n };\n\n exports[\"default\"] = LinkedItem;\n});","define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var PARENT_PROP = '__parent';\n\n var LinkedList = (function () {\n function LinkedList(options) {\n _classCallCheck(this, LinkedList);\n\n this.head = null;\n this.tail = null;\n this.length = 0;\n\n if (options) {\n var adoptItem = options.adoptItem;\n var freeItem = options.freeItem;\n\n this._adoptItem = adoptItem;\n this._freeItem = freeItem;\n }\n }\n\n _createClass(LinkedList, [{\n key: 'adoptItem',\n value: function adoptItem(item) {\n item[PARENT_PROP] = this;\n this.length++;\n if (this._adoptItem) {\n this._adoptItem(item);\n }\n }\n }, {\n key: 'freeItem',\n value: function freeItem(item) {\n item[PARENT_PROP] = null;\n this.length--;\n if (this._freeItem) {\n this._freeItem(item);\n }\n }\n }, {\n key: 'prepend',\n value: function prepend(item) {\n this.insertBefore(item, this.head);\n }\n }, {\n key: 'append',\n value: function append(item) {\n this.insertBefore(item, null);\n }\n }, {\n key: 'insertAfter',\n value: function insertAfter(item, prevItem) {\n var nextItem = prevItem ? prevItem.next : this.head;\n this.insertBefore(item, nextItem);\n }\n }, {\n key: '_ensureItemIsNotAlreadyInList',\n value: function _ensureItemIsNotAlreadyInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item.next && !item.prev && this.head !== item);\n }\n }, {\n key: 'insertBefore',\n value: function insertBefore(item, nextItem) {\n this._ensureItemIsNotInList(item);\n this.adoptItem(item);\n\n var insertPos = undefined;\n if (nextItem && nextItem.prev) {\n insertPos = 'middle';\n } else if (nextItem) {\n insertPos = 'start';\n } else {\n insertPos = 'end';\n }\n\n switch (insertPos) {\n case 'start':\n if (this.head) {\n item.next = this.head;\n this.head.prev = item;\n }\n this.head = item;\n\n break;\n case 'middle':\n var prevItem = nextItem.prev;\n item.next = nextItem;\n item.prev = prevItem;\n nextItem.prev = item;\n prevItem.next = item;\n\n break;\n case 'end':\n var tail = this.tail;\n item.prev = tail;\n\n if (tail) {\n tail.next = item;\n } else {\n this.head = item;\n }\n this.tail = item;\n\n break;\n }\n }\n }, {\n key: 'remove',\n value: function remove(item) {\n if (!item[PARENT_PROP]) {\n return;\n }\n this._ensureItemIsInThisList(item);\n this.freeItem(item);\n\n var prev = item.prev;\n var next = item.next;\n\n item.prev = null;\n item.next = null;\n\n if (prev) {\n prev.next = next;\n } else {\n this.head = next;\n }\n\n if (next) {\n next.prev = prev;\n } else {\n this.tail = prev;\n }\n }\n }, {\n key: 'forEach',\n value: function forEach(callback) {\n var item = this.head;\n var index = 0;\n while (item) {\n callback(item, index++);\n item = item.next;\n }\n }\n }, {\n key: 'map',\n value: function map(callback) {\n var result = [];\n this.forEach(function (i) {\n return result.push(callback(i));\n });\n return result;\n }\n }, {\n key: 'walk',\n value: function walk(startItem, endItem, callback) {\n var item = startItem || this.head;\n while (item) {\n callback(item);\n if (item === endItem) {\n break;\n }\n item = item.next;\n }\n }\n }, {\n key: 'readRange',\n value: function readRange(startItem, endItem) {\n var items = [];\n this.walk(startItem, endItem, function (item) {\n items.push(item);\n });\n return items;\n }\n }, {\n key: 'toArray',\n value: function toArray() {\n return this.readRange();\n }\n }, {\n key: 'detect',\n value: function detect(callback) {\n var item = arguments.length <= 1 || arguments[1] === undefined ? this.head : arguments[1];\n var reverse = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n while (item) {\n if (callback(item)) {\n return item;\n }\n item = reverse ? item.prev : item.next;\n }\n }\n }, {\n key: 'any',\n value: function any(callback) {\n return !!this.detect(callback);\n }\n }, {\n key: 'every',\n value: function every(callback) {\n var item = this.head;\n while (item) {\n if (!callback(item)) {\n return false;\n }\n item = item.next;\n }\n return true;\n }\n }, {\n key: 'objectAt',\n value: function objectAt(targetIndex) {\n var index = -1;\n return this.detect(function () {\n index++;\n return targetIndex === index;\n });\n }\n }, {\n key: 'splice',\n value: function splice(targetItem, removalCount, newItems) {\n var _this = this;\n\n var item = targetItem;\n var nextItem = item.next;\n var count = 0;\n while (item && count < removalCount) {\n count++;\n nextItem = item.next;\n this.remove(item);\n item = nextItem;\n }\n newItems.forEach(function (newItem) {\n _this.insertBefore(newItem, nextItem);\n });\n }\n }, {\n key: 'removeBy',\n value: function removeBy(conditionFn) {\n var item = this.head;\n while (item) {\n var nextItem = item.next;\n\n if (conditionFn(item)) {\n this.remove(item);\n }\n\n item = nextItem;\n }\n }\n }, {\n key: '_ensureItemIsNotInList',\n value: function _ensureItemIsNotInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item[PARENT_PROP]);\n }\n }, {\n key: '_ensureItemIsInThisList',\n value: function _ensureItemIsInThisList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot remove item that is in another list', item[PARENT_PROP] === this);\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.length === 0;\n }\n }]);\n\n return LinkedList;\n })();\n\n exports['default'] = LinkedList;\n});","define(\"mobiledoc-kit/utils/log-manager\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Logger = (function () {\n function Logger(type, manager) {\n _classCallCheck(this, Logger);\n\n this.type = type;\n this.manager = manager;\n }\n\n _createClass(Logger, [{\n key: \"isEnabled\",\n value: function isEnabled() {\n return this.manager.isEnabled(this.type);\n }\n }, {\n key: \"log\",\n value: function log() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n args.unshift(\"[\" + this.type + \"]\");\n if (this.isEnabled()) {\n var _window$console;\n\n (_window$console = window.console).log.apply(_window$console, args);\n }\n }\n }]);\n\n return Logger;\n })();\n\n var LogManager = (function () {\n function LogManager() {\n _classCallCheck(this, LogManager);\n\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n\n _createClass(LogManager, [{\n key: \"for\",\n value: function _for(type) {\n return new Logger(type, this);\n }\n }, {\n key: \"enableAll\",\n value: function enableAll() {\n this.allEnabled = true;\n }\n }, {\n key: \"enableTypes\",\n value: function enableTypes(types) {\n this.enabledTypes = this.enabledTypes.concat(types);\n }\n }, {\n key: \"disable\",\n value: function disable() {\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n }, {\n key: \"isEnabled\",\n value: function isEnabled(type) {\n return this.allEnabled || this.enabledTypes.indexOf(type) !== -1;\n }\n }]);\n\n return LogManager;\n })();\n\n exports[\"default\"] = LogManager;\n});","define('mobiledoc-kit/utils/markuperable', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var Markerupable = (function () {\n function Markerupable() {\n _classCallCheck(this, Markerupable);\n }\n\n _createClass(Markerupable, [{\n key: 'clearMarkups',\n value: function clearMarkups() {\n this.markups = [];\n }\n }, {\n key: 'addMarkup',\n value: function addMarkup(markup) {\n this.markups.push(markup);\n }\n }, {\n key: 'addMarkupAtIndex',\n value: function addMarkupAtIndex(markup, index) {\n this.markups.splice(index, 0, markup);\n }\n }, {\n key: 'removeMarkup',\n value: function removeMarkup(markupOrMarkupCallback) {\n var _this = this;\n\n var callback = undefined;\n if (typeof markupOrMarkupCallback === 'function') {\n callback = markupOrMarkupCallback;\n } else {\n (function () {\n var markup = markupOrMarkupCallback;\n callback = function (_markup) {\n return _markup === markup;\n };\n })();\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.markups, callback), function (m) {\n return _this._removeMarkup(m);\n });\n }\n }, {\n key: '_removeMarkup',\n value: function _removeMarkup(markup) {\n var index = this.markups.indexOf(markup);\n if (index !== -1) {\n this.markups.splice(index, 1);\n }\n }\n }, {\n key: 'hasMarkup',\n value: function hasMarkup(tagNameOrMarkup) {\n return !!this.getMarkup(tagNameOrMarkup);\n }\n }, {\n key: 'getMarkup',\n value: function getMarkup(tagNameOrMarkup) {\n var _this2 = this;\n\n if (typeof tagNameOrMarkup === 'string') {\n var _ret2 = (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagNameOrMarkup);\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup.tagName === tagName;\n })\n };\n })();\n\n if (typeof _ret2 === 'object') return _ret2.v;\n } else {\n var _ret3 = (function () {\n var targetMarkup = tagNameOrMarkup;\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup === targetMarkup;\n })\n };\n })();\n\n if (typeof _ret3 === 'object') return _ret3.v;\n }\n }\n }, {\n key: 'openedMarkups',\n get: function get() {\n var count = 0;\n if (this.prev) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.prev.markups);\n }\n\n return this.markups.slice(count);\n }\n }, {\n key: 'closedMarkups',\n get: function get() {\n var count = 0;\n if (this.next) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.next.markups);\n }\n\n return this.markups.slice(count);\n }\n }]);\n\n return Markerupable;\n })();\n\n exports['default'] = Markerupable;\n});","define(\"mobiledoc-kit/utils/merge\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function mergeWithOptions(original, updates, options) {\n options = options || {};\n for (var prop in updates) {\n if (options.hasOwnProperty(prop)) {\n original[prop] = options[prop];\n } else if (updates.hasOwnProperty(prop)) {\n original[prop] = updates[prop];\n }\n }\n return original;\n }\n\n /**\n * Merges properties of one object into another\n * @private\n */\n function merge(original, updates) {\n return mergeWithOptions(original, updates);\n }\n\n exports.mergeWithOptions = mergeWithOptions;\n exports.merge = merge;\n});","define('mobiledoc-kit/utils/mixin', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = mixin;\n var CONSTRUCTOR_FN_NAME = 'constructor';\n\n function mixin(target, source) {\n target = target.prototype;\n // Fallback to just `source` to allow mixing in a plain object (pojo)\n source = source.prototype || source;\n\n Object.getOwnPropertyNames(source).forEach(function (name) {\n if (name !== CONSTRUCTOR_FN_NAME) {\n var descriptor = Object.getOwnPropertyDescriptor(source, name);\n\n Object.defineProperty(target, name, descriptor);\n }\n });\n }\n});","define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) {\n 'use strict';\n\n var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];\n\n function MobiledocError() {\n var tmp = Error.apply(this, arguments);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.\n for (var idx = 0; idx < errorProps.length; idx++) {\n this[errorProps[idx]] = tmp[errorProps[idx]];\n }\n }\n\n MobiledocError.prototype = Object.create(Error.prototype);\n\n exports['default'] = MobiledocError;\n});","define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) {\n /* global JSON */\n 'use strict';\n\n exports.getContentFromPasteEvent = getContentFromPasteEvent;\n exports.setClipboardData = setClipboardData;\n exports.parsePostFromPaste = parsePostFromPaste;\n exports.parsePostFromDrop = parsePostFromDrop;\n var MIME_TEXT_PLAIN = 'text/plain';\n exports.MIME_TEXT_PLAIN = MIME_TEXT_PLAIN;\n var MIME_TEXT_HTML = 'text/html';\n exports.MIME_TEXT_HTML = MIME_TEXT_HTML;\n var NONSTANDARD_IE_TEXT_TYPE = 'Text';\n\n exports.NONSTANDARD_IE_TEXT_TYPE = NONSTANDARD_IE_TEXT_TYPE;\n var MOBILEDOC_REGEX = new RegExp(/data\\-mobiledoc='(.*?)'>/);\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromHTML(html, builder, plugins) {\n var post = undefined;\n\n if (MOBILEDOC_REGEX.test(html)) {\n var mobiledocString = html.match(MOBILEDOC_REGEX)[1];\n var mobiledoc = JSON.parse(mobiledocString);\n post = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n } else {\n post = new _mobiledocKitParsersHtml['default'](builder, { plugins: plugins }).parse(html);\n }\n\n return post;\n }\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromText(text, builder, plugins) {\n var parser = new _mobiledocKitParsersText['default'](builder, { plugins: plugins });\n var post = parser.parse(text);\n return post;\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n\n function getContentFromPasteEvent(event, window) {\n var html = '',\n text = '';\n\n var clipboardData = event.clipboardData;\n\n if (clipboardData && clipboardData.getData) {\n html = clipboardData.getData(MIME_TEXT_HTML);\n text = clipboardData.getData(MIME_TEXT_PLAIN);\n } else if (window.clipboardData && window.clipboardData.getData) {\n // IE\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n html = window.clipboardData.getData(NONSTANDARD_IE_TEXT_TYPE);\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n function getContentFromDropEvent(event, logger) {\n var html = '',\n text = '';\n\n try {\n html = event.dataTransfer.getData(MIME_TEXT_HTML);\n text = event.dataTransfer.getData(MIME_TEXT_PLAIN);\n } catch (e) {\n // FIXME IE11 does not include any data in the 'text/html' or 'text/plain'\n // mimetypes. It throws an error 'Invalid argument' when attempting to read\n // these properties.\n if (logger) {\n logger.log('Error getting drop data: ', e);\n }\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @param {CopyEvent|CutEvent}\n * @param {Editor}\n * @param {Window}\n * @private\n */\n\n function setClipboardData(event, _ref, window) {\n var mobiledoc = _ref.mobiledoc;\n var html = _ref.html;\n var text = _ref.text;\n\n if (mobiledoc && html) {\n html = '
    ' + html + '
    ';\n }\n\n var clipboardData = event.clipboardData;\n var nonstandardClipboardData = window.clipboardData;\n\n if (clipboardData && clipboardData.setData) {\n clipboardData.setData(MIME_TEXT_HTML, html);\n clipboardData.setData(MIME_TEXT_PLAIN, text);\n } else if (nonstandardClipboardData && nonstandardClipboardData.setData) {\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n nonstandardClipboardData.setData(NONSTANDARD_IE_TEXT_TYPE, html);\n }\n }\n\n /**\n * @param {PasteEvent}\n * @param {{builder: Builder, _parserPlugins: Array}} options\n * @return {Post}\n * @private\n */\n\n function parsePostFromPaste(pasteEvent, _ref2) {\n var builder = _ref2.builder;\n var plugins = _ref2._parserPlugins;\n\n var _ref3 = arguments.length <= 2 || arguments[2] === undefined ? { targetFormat: 'html' } : arguments[2];\n\n var targetFormat = _ref3.targetFormat;\n\n var _getContentFromPasteEvent = getContentFromPasteEvent(pasteEvent, window);\n\n var html = _getContentFromPasteEvent.html;\n var text = _getContentFromPasteEvent.text;\n\n if (targetFormat === 'html' && html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n\n /**\n * @param {DropEvent}\n * @param {Editor} editor\n * @param {Object} [options={}] Can pass a logger\n * @return {Post}\n * @private\n */\n\n function parsePostFromDrop(dropEvent, editor) {\n var _ref4 = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var logger = _ref4.logger;\n var builder = editor.builder;\n var plugins = editor._parserPlugins;\n\n var _getContentFromDropEvent = getContentFromDropEvent(dropEvent, logger);\n\n var html = _getContentFromDropEvent.html;\n var text = _getContentFromDropEvent.text;\n\n if (html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n});","define(\"mobiledoc-kit/utils/placeholder-image-src\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var placeholderImageSrc = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAMFBMVEXp7vG6vsHm6+63u77Hy868wMPe4+bO09bh5unr8fTR1djAxMfM0NPX3N/c4eTBxcjXRf5TAAACh0lEQVR4nO3b6ZKqMBSFUSQMYZL3f9tbBq/NEEDiqUqOfusn1ZXKbjcQlGQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC6RkbsGHuabChEtHmiGYfS3EQYM+Sxw/gMQvmcNnYaj6oTDHi73WPn2eqnj9B8zo3TJXcq5uNjXmVff86VwSR3JtryMa1BYqi7S1hJDCVpSigyLcGhJJEwzlCSNtPKrbVhVwsdCfOhH7uuaG3ARV9DwsaOzxt3N1yPqCHhvXytTUz92VDpmE/LLhZwl++R6Sds6sUa/PL6K/2E2fIhw1xdRKefsFolrPc+xNx/N0k/4fpBsdhL2HfeiN+TsDCms8dDpeRyS3P3QDl6Iqaf8L0rTf+80m6Lmn7Ct+4Wxf+/2RY1/YRv3PHz/u+fsCmqgoTnq7Z+8SGviqoh4dnKu1ieqauiakh4/PQ0r6ivqDoSHj0B97eNRVG1JNxV+L4bnxdVecJtRTdFVZ7QU9F1UXUn9FZ0VVRlCav5ob2KLouqKmFjy676u2HsVnRRVFUJq3J+8KCi86IqSthMvyl209Hjijqm3RsqAZ5pNfa5PJ2KelJRjQmr1/r7cfy0ouoSNvOfvbvhvKLaEr4qOin9kTQnrN7LpDZhE/Zmhp6Eq4p+YcKgiipKGFhRRQkDK6ooYfgLbiSMioQkJGF8P5XwHv4O+7AaKiXzaeXh1kMl5AffTUxiKEm/krD94BR8Gdxl1fceSlR58ZhXKbEpyD2amNiBtmrJLTMHL1LF8/rpXkSZXEmz8K8uvAFFNm6Iq0aBLUFOmeCuJ6exrcCmoLpN7kYx891bSAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgh/wDdr8peyRHLogAAAAASUVORK5CYII=\";\n\n exports[\"default\"] = placeholderImageSrc;\n});","define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function clearSelection() {\n window.getSelection().removeAllRanges();\n }\n\n function textNodeRects(node) {\n var range = document.createRange();\n range.setEnd(node, node.nodeValue.length);\n range.setStart(node, 0);\n return range.getClientRects();\n }\n\n function findOffsetInTextNode(node, coords) {\n var len = node.nodeValue.length;\n var range = document.createRange();\n for (var i = 0; i < len; i++) {\n range.setEnd(node, i + 1);\n range.setStart(node, i);\n var rect = range.getBoundingClientRect();\n if (rect.top === rect.bottom) {\n continue;\n }\n if (rect.left <= coords.left && rect.right >= coords.left && rect.top <= coords.top && rect.bottom >= coords.top) {\n return { node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };\n }\n }\n return { node: node, offset: 0 };\n }\n\n /*\n * @param {Object} coords with `top` and `left`\n * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js\n * @return {Object} {node, offset}\n */\n function findOffsetInNode(_x, _x2) {\n var _again = true;\n\n _function: while (_again) {\n var node = _x,\n coords = _x2;\n _again = false;\n\n var closest = undefined,\n dyClosest = 1e8,\n coordsClosest = undefined,\n offset = 0;\n for (var child = node.firstChild; child; child = child.nextSibling) {\n var rects = undefined;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child)) {\n rects = child.getClientRects();\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(child)) {\n rects = textNodeRects(child);\n } else {\n continue;\n }\n\n for (var i = 0; i < rects.length; i++) {\n var rect = rects[i];\n if (rect.left <= coords.left && rect.right >= coords.left) {\n var dy = rect.top > coords.top ? rect.top - coords.top : rect.bottom < coords.top ? coords.top - rect.bottom : 0;\n if (dy < dyClosest) {\n closest = child;\n dyClosest = dy;\n coordsClosest = dy ? { left: coords.left, top: rect.top } : coords;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child) && !child.firstChild) {\n offset = i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);\n }\n continue;\n }\n }\n if (!closest && (coords.top >= rect.bottom || coords.top >= rect.top && coords.left >= rect.right)) {\n offset = i + 1;\n }\n }\n }\n if (!closest) {\n return { node: node, offset: offset };\n }\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(closest)) {\n return findOffsetInTextNode(closest, coordsClosest);\n }\n if (closest.firstChild) {\n _x = closest;\n _x2 = coordsClosest;\n _again = true;\n closest = dyClosest = coordsClosest = offset = child = rects = i = rect = dy = undefined;\n continue _function;\n }\n return { node: node, offset: offset };\n }\n }\n\n function constrainNodeTo(node, parentNode, existingOffset) {\n var compare = parentNode.compareDocumentPosition(node);\n if (compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n // the node is inside parentNode, do nothing\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_CONTAINS) {\n // the node contains parentNode. This shouldn't happen.\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_PRECEDING) {\n // node is before parentNode. return start of deepest first child\n var child = parentNode.firstChild;\n while (child.firstChild) {\n child = child.firstChild;\n }\n return { node: child, offset: 0 };\n } else if (compare & Node.DOCUMENT_POSITION_FOLLOWING) {\n // node is after parentNode. return end of deepest last child\n var child = parentNode.lastChild;\n while (child.lastChild) {\n child = child.lastChild;\n }\n\n var offset = (0, _mobiledocKitUtilsDomUtils.isTextNode)(child) ? child.textContent.length : 1;\n return { node: child, offset: offset };\n } else {\n return { node: node, offset: existingOffset };\n }\n }\n\n /*\n * Returns a new selection that is constrained within parentNode.\n * If the anchorNode or focusNode are outside the parentNode, they are replaced with the beginning\n * or end of the parentNode's children\n */\n function constrainSelectionTo(selection, parentNode) {\n var _constrainNodeTo = constrainNodeTo(selection.anchorNode, parentNode, selection.anchorOffset);\n\n var anchorNode = _constrainNodeTo.node;\n var anchorOffset = _constrainNodeTo.offset;\n\n var _constrainNodeTo2 = constrainNodeTo(selection.focusNode, parentNode, selection.focusOffset);\n\n var focusNode = _constrainNodeTo2.node;\n var focusOffset = _constrainNodeTo2.offset;\n\n return { anchorNode: anchorNode, anchorOffset: anchorOffset, focusNode: focusNode, focusOffset: focusOffset };\n }\n\n function comparePosition(_x3) {\n var _again2 = true;\n\n _function2: while (_again2) {\n var selection = _x3;\n _again2 = false;\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n var headNode = undefined,\n tailNode = undefined,\n headOffset = undefined,\n tailOffset = undefined,\n direction = undefined;\n\n var position = anchorNode.compareDocumentPosition(focusNode);\n\n // IE may select return focus and anchor nodes far up the DOM tree instead of\n // picking the deepest, most specific possible node. For example in\n //\n //
    abcdef
    \n //\n // with a cursor between c and d, IE might say the focusNode is
    with\n // an offset of 1. However the anchorNode for a selection might still be\n // 2 if there was a selection.\n //\n // This code walks down the DOM tree until a good comparison of position can be\n // made.\n //\n if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n if (focusOffset < focusNode.childNodes.length) {\n focusNode = focusNode.childNodes[focusOffset];\n focusOffset = 0;\n } else {\n // This situation happens on IE when triple-clicking to select.\n // Set the focus to the very last character inside the node.\n while (focusNode.lastChild) {\n focusNode = focusNode.lastChild;\n }\n focusOffset = focusNode.textContent.length;\n }\n\n _x3 = {\n focusNode: focusNode,\n focusOffset: focusOffset,\n anchorNode: anchorNode, anchorOffset: anchorOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = undefined;\n continue _function2;\n } else if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n var offset = anchorOffset - 1;\n if (offset < 0) {\n offset = 0;\n }\n _x3 = {\n anchorNode: anchorNode.childNodes[offset],\n anchorOffset: 0,\n focusNode: focusNode, focusOffset: focusOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = offset = undefined;\n continue _function2;\n\n // The meat of translating anchor and focus nodes to head and tail nodes\n } else if (position & Node.DOCUMENT_POSITION_FOLLOWING) {\n headNode = anchorNode;tailNode = focusNode;\n headOffset = anchorOffset;tailOffset = focusOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n headNode = focusNode;tailNode = anchorNode;\n headOffset = focusOffset;tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else {\n // same node\n headNode = tailNode = anchorNode;\n headOffset = anchorOffset;\n tailOffset = focusOffset;\n if (tailOffset < headOffset) {\n // Swap the offset order\n headOffset = focusOffset;\n tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else if (headOffset < tailOffset) {\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else {\n direction = null;\n }\n }\n\n return { headNode: headNode, headOffset: headOffset, tailNode: tailNode, tailOffset: tailOffset, direction: direction };\n }\n }\n\n exports.clearSelection = clearSelection;\n exports.comparePosition = comparePosition;\n exports.findOffsetInNode = findOffsetInNode;\n exports.constrainSelectionTo = constrainSelectionTo;\n});","define(\"mobiledoc-kit/utils/set\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Set = (function () {\n function Set() {\n var _this = this;\n\n var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, Set);\n\n this.items = [];\n items.forEach(function (i) {\n return _this.add(i);\n });\n }\n\n _createClass(Set, [{\n key: \"add\",\n value: function add(item) {\n if (!this.has(item)) {\n this.items.push(item);\n }\n }\n }, {\n key: \"has\",\n value: function has(item) {\n return this.items.indexOf(item) !== -1;\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this.items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this.items.length;\n }\n }]);\n\n return Set;\n })();\n\n exports[\"default\"] = Set;\n});","define('mobiledoc-kit/utils/string-utils', ['exports'], function (exports) {\n /*\n * @param {String} string\n * @return {String} a dasherized string. 'modelIndex' -> 'model-index', etc\n */\n 'use strict';\n\n exports.dasherize = dasherize;\n exports.capitalize = capitalize;\n exports.startsWith = startsWith;\n exports.endsWith = endsWith;\n\n function dasherize(string) {\n return string.replace(/[A-Z]/g, function (match, offset) {\n var lower = match.toLowerCase();\n\n return offset === 0 ? lower : '-' + lower;\n });\n }\n\n function capitalize(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n }\n\n function startsWith(string, character) {\n return string.charAt(0) === character;\n }\n\n function endsWith(string, endString) {\n var index = string.lastIndexOf(endString);\n return index !== -1 && index === string.length - endString.length;\n }\n});","define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports['default'] = toRange;\n\n function toRange(rangeLike) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass non-blank object to \"toRange\"', !!rangeLike);\n\n if (rangeLike instanceof _mobiledocKitUtilsCursorRange['default']) {\n return rangeLike;\n } else if (rangeLike instanceof _mobiledocKitUtilsCursorPosition['default']) {\n return rangeLike.toRange();\n }\n\n (0, _mobiledocKitUtilsAssert['default'])('Incorrect structure for rangeLike: ' + rangeLike, false);\n }\n});","define('mobiledoc-kit/version', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = '##VERSION##';\n});","define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var DELAY = 200;\n\n var Tooltip = (function (_View) {\n _inherits(Tooltip, _View);\n\n function Tooltip(options) {\n var _this = this;\n\n _classCallCheck(this, Tooltip);\n\n var rootElement = options.rootElement;\n\n var timeout = undefined;\n options.classNames = ['__mobiledoc-tooltip'];\n _get(Object.getPrototypeOf(Tooltip.prototype), 'constructor', this).call(this, options);\n\n this.addEventListener(rootElement, 'mouseover', function (e) {\n var target = (0, _mobiledocKitUtilsElementUtils.getEventTargetMatchingTag)(options.showForTag, e.target, rootElement);\n if (target && target.isContentEditable) {\n timeout = setTimeout(function () {\n _this.showLink(target.href, target);\n }, DELAY);\n }\n });\n\n this.addEventListener(rootElement, 'mouseout', function (e) {\n clearTimeout(timeout);\n var toElement = e.toElement || e.relatedTarget;\n if (toElement && toElement.className !== _this.element.className) {\n _this.hide();\n }\n });\n }\n\n _createClass(Tooltip, [{\n key: 'showMessage',\n value: function showMessage(message, element) {\n var tooltipElement = this.element;\n tooltipElement.innerHTML = message;\n this.show();\n (0, _mobiledocKitUtilsElementUtils.positionElementCenteredBelow)(tooltipElement, element);\n }\n }, {\n key: 'showLink',\n value: function showLink(link, element) {\n var message = '' + link + '';\n this.showMessage(message, element);\n }\n }]);\n\n return Tooltip;\n })(_mobiledocKitViewsView['default']);\n\n exports['default'] = Tooltip;\n});","define('mobiledoc-kit/views/view', ['exports', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var View = (function () {\n function View() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, View);\n\n options.tagName = options.tagName || 'div';\n options.container = options.container || document.body;\n\n this.element = document.createElement(options.tagName);\n this.container = options.container;\n this.isShowing = false;\n\n var classNames = options.classNames || [];\n classNames.forEach(function (name) {\n return (0, _mobiledocKitUtilsDomUtils.addClassName)(_this.element, name);\n });\n this._eventListeners = [];\n }\n\n _createClass(View, [{\n key: 'addEventListener',\n value: function addEventListener(element, type, listener) {\n element.addEventListener(type, listener);\n this._eventListeners.push([element, type, listener]);\n }\n }, {\n key: 'removeAllEventListeners',\n value: function removeAllEventListeners() {\n this._eventListeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var element = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n element.removeEventListener(type, listener);\n });\n }\n }, {\n key: 'show',\n value: function show() {\n if (!this.isShowing) {\n this.container.appendChild(this.element);\n this.isShowing = true;\n return true;\n }\n }\n }, {\n key: 'hide',\n value: function hide() {\n if (this.isShowing) {\n this.container.removeChild(this.element);\n this.isShowing = false;\n return true;\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.removeAllEventListeners();\n this.hide();\n this.isDestroyed = true;\n }\n }]);\n\n return View;\n })();\n\n exports['default'] = View;\n});","define('mobiledoc-text-renderer/cards/image', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n name: 'image-card',\n type: 'text',\n render: function render() {}\n };\n});","define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n function registerGlobal(window) {\n window.MobiledocTextRenderer = _mobiledocTextRendererRendererFactory['default'];\n }\n\n exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default'];\n exports['default'] = _mobiledocTextRendererRendererFactory['default'];\n});","define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var cards = _ref.cards;\n var atoms = _ref.atoms;\n var cardOptions = _ref.cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n\n _classCallCheck(this, RendererFactory);\n\n cards = cards || [];\n validateCards(cards);\n atoms = atoms || [];\n validateAtoms(atoms);\n cardOptions = cardOptions || {};\n\n this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION:\n return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render();\n case undefined:\n case null:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var sections = _sectionData[1];\n\n this.root = [];\n this.sections = sections;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n\n // for the text renderer, a missing card is a no-op\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var type = _ref32[0];\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 3);\n\n var text = _m[2];\n\n str += text;\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {};\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION_0_3 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_1;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n\n validateVersion(version);\n\n this.root = [];\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var index = _ref32[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this4 = this;\n\n var env = {\n name: atom.name,\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || '';\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var _this5 = this;\n\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 4);\n\n var type = _m[0];\n var value = _m[3];\n\n switch (type) {\n case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n str += value;\n break;\n case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n str += _this5._renderAtom(value);\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {\n // for the text renderer, a missing card is a no-op\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref5) {\n var value = _ref5.value;\n\n return value || '';\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-text-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'text';\n});","define(\"mobiledoc-text-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACreA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5wCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACh3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1TA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/TA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9nBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5WA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;","file":"mobiledoc-kit.js"} \ No newline at end of file +{"version":3,"sources":["mobiledoc-dom-renderer/cards/image.js","mobiledoc-dom-renderer/index.js","mobiledoc-dom-renderer/renderer-factory.js","mobiledoc-dom-renderer/renderers/0-2.js","mobiledoc-dom-renderer/renderers/0-3.js","mobiledoc-dom-renderer/utils/array-utils.js","mobiledoc-dom-renderer/utils/dom.js","mobiledoc-dom-renderer/utils/marker-types.js","mobiledoc-dom-renderer/utils/render-type.js","mobiledoc-dom-renderer/utils/render-utils.js","mobiledoc-dom-renderer/utils/sanitization-utils.js","mobiledoc-dom-renderer/utils/section-types.js","mobiledoc-dom-renderer/utils/tag-names.js","mobiledoc-kit/cards/image.js","mobiledoc-kit/editor/edit-history.js","mobiledoc-kit/editor/edit-state.js","mobiledoc-kit/editor/editor.js","mobiledoc-kit/editor/event-manager.js","mobiledoc-kit/editor/key-commands.js","mobiledoc-kit/editor/mutation-handler.js","mobiledoc-kit/editor/post.js","mobiledoc-kit/editor/post/post-inserter.js","mobiledoc-kit/editor/selection-change-observer.js","mobiledoc-kit/editor/selection-manager.js","mobiledoc-kit/editor/text-input-handler.js","mobiledoc-kit/editor/text-input-handlers.js","mobiledoc-kit/editor/ui.js","mobiledoc-kit/index.js","mobiledoc-kit/models/_attributable.js","mobiledoc-kit/models/_markerable.js","mobiledoc-kit/models/_section.js","mobiledoc-kit/models/atom-node.js","mobiledoc-kit/models/atom.js","mobiledoc-kit/models/card-node.js","mobiledoc-kit/models/card.js","mobiledoc-kit/models/image.js","mobiledoc-kit/models/lifecycle-callbacks.js","mobiledoc-kit/models/list-item.js","mobiledoc-kit/models/list-section.js","mobiledoc-kit/models/marker.js","mobiledoc-kit/models/markup-section.js","mobiledoc-kit/models/markup.js","mobiledoc-kit/models/post-node-builder.js","mobiledoc-kit/models/post.js","mobiledoc-kit/models/render-node.js","mobiledoc-kit/models/render-tree.js","mobiledoc-kit/models/types.js","mobiledoc-kit/parsers/dom.js","mobiledoc-kit/parsers/html.js","mobiledoc-kit/parsers/mobiledoc/0-2.js","mobiledoc-kit/parsers/mobiledoc/0-3-1.js","mobiledoc-kit/parsers/mobiledoc/0-3-2.js","mobiledoc-kit/parsers/mobiledoc/0-3.js","mobiledoc-kit/parsers/mobiledoc/index.js","mobiledoc-kit/parsers/section.js","mobiledoc-kit/parsers/text.js","mobiledoc-kit/renderers/editor-dom.js","mobiledoc-kit/renderers/mobiledoc/0-2.js","mobiledoc-kit/renderers/mobiledoc/0-3-1.js","mobiledoc-kit/renderers/mobiledoc/0-3-2.js","mobiledoc-kit/renderers/mobiledoc/0-3.js","mobiledoc-kit/renderers/mobiledoc/index.js","mobiledoc-kit/utils/array-utils.js","mobiledoc-kit/utils/assert.js","mobiledoc-kit/utils/browser.js","mobiledoc-kit/utils/characters.js","mobiledoc-kit/utils/compiler.js","mobiledoc-kit/utils/copy.js","mobiledoc-kit/utils/cursor.js","mobiledoc-kit/utils/cursor/position.js","mobiledoc-kit/utils/cursor/range.js","mobiledoc-kit/utils/deprecate.js","mobiledoc-kit/utils/dom-utils.js","mobiledoc-kit/utils/element-map.js","mobiledoc-kit/utils/element-utils.js","mobiledoc-kit/utils/environment.js","mobiledoc-kit/utils/fixed-queue.js","mobiledoc-kit/utils/key.js","mobiledoc-kit/utils/keycodes.js","mobiledoc-kit/utils/keys.js","mobiledoc-kit/utils/linked-item.js","mobiledoc-kit/utils/linked-list.js","mobiledoc-kit/utils/log-manager.js","mobiledoc-kit/utils/markuperable.js","mobiledoc-kit/utils/merge.js","mobiledoc-kit/utils/mixin.js","mobiledoc-kit/utils/mobiledoc-error.js","mobiledoc-kit/utils/object-utils.js","mobiledoc-kit/utils/parse-utils.js","mobiledoc-kit/utils/placeholder-image-src.js","mobiledoc-kit/utils/selection-utils.js","mobiledoc-kit/utils/set.js","mobiledoc-kit/utils/string-utils.js","mobiledoc-kit/utils/to-range.js","mobiledoc-kit/version.js","mobiledoc-kit/views/tooltip.js","mobiledoc-kit/views/view.js","mobiledoc-text-renderer/cards/image.js","mobiledoc-text-renderer/index.js","mobiledoc-text-renderer/renderer-factory.js","mobiledoc-text-renderer/renderers/0-2.js","mobiledoc-text-renderer/renderers/0-3.js","mobiledoc-text-renderer/utils/marker-types.js","mobiledoc-text-renderer/utils/render-type.js","mobiledoc-text-renderer/utils/section-types.js"],"sourcesContent":["define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: function render(_ref) {\n var payload = _ref.payload;\n var dom = _ref.env.dom;\n\n var img = dom.createElement('img');\n img.src = payload.src;\n return img;\n }\n };\n});","define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];\n\n function registerGlobal(window) {\n window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];\n }\n\n exports['default'] = _mobiledocDomRendererRendererFactory['default'];\n});","define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderers/0-2', 'mobiledoc-dom-renderer/renderers/0-3', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderers02, _mobiledocDomRendererRenderers03, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime DOM renderer\n * renders a mobiledoc to DOM\n *\n * input: mobiledoc\n * output: DOM\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be of type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var _ref$cards = _ref.cards;\n var cards = _ref$cards === undefined ? [] : _ref$cards;\n var _ref$atoms = _ref.atoms;\n var atoms = _ref$atoms === undefined ? [] : _ref$atoms;\n var _ref$cardOptions = _ref.cardOptions;\n var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n var _ref$markupElementRenderer = _ref.markupElementRenderer;\n var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer;\n var _ref$sectionElementRenderer = _ref.sectionElementRenderer;\n var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer;\n var dom = _ref.dom;\n var _ref$markupSanitizer = _ref.markupSanitizer;\n var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer;\n\n _classCallCheck(this, RendererFactory);\n\n validateCards(cards);\n validateAtoms(atoms);\n\n if (!dom) {\n if (typeof window === 'undefined') {\n throw new Error('A `dom` option must be provided to the renderer when running without window.document');\n }\n dom = window.document;\n }\n\n this.options = {\n cards: cards,\n atoms: atoms,\n cardOptions: cardOptions,\n unknownCardHandler: unknownCardHandler,\n unknownAtomHandler: unknownAtomHandler,\n markupElementRenderer: markupElementRenderer,\n sectionElementRenderer: sectionElementRenderer,\n dom: dom,\n markupSanitizer: markupSanitizer\n };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocDomRendererRenderers02.MOBILEDOC_VERSION:\n case undefined:\n case null:\n return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render();\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-dom-renderer/renderers/0-2', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, options) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = options.cards;\n var cardOptions = options.cardOptions;\n var unknownCardHandler = options.unknownCardHandler;\n var markupElementRenderer = options.markupElementRenderer;\n var sectionElementRenderer = options.sectionElementRenderer;\n var dom = options.dom;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var markerTypes = _sectionData[0];\n var sections = _sectionData[1];\n\n this.dom = dom;\n this.root = dom.createDocumentFragment();\n this.markerTypes = markerTypes;\n this.sections = sections;\n this.cards = cards;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n this._renderedChildNodes = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = [];\n var node = this.root.firstChild;\n while (node) {\n this._renderedChildNodes.push(node);\n node = node.nextSibling;\n }\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 3);\n\n var openTypes = _marker[0];\n var closeCount = _marker[1];\n var text = _marker[2];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, text));\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var name = _ref42[1];\n var payload = _ref42[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils', 'mobiledoc-dom-renderer/utils/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils, _mobiledocDomRendererUtilsMarkerTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION_0_3_0 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n switch (version) {\n case MOBILEDOC_VERSION_0_3_0:\n case MOBILEDOC_VERSION_0_3_1:\n case MOBILEDOC_VERSION_0_3_2:\n return;\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var markupElementRenderer = state.markupElementRenderer;\n var sectionElementRenderer = state.sectionElementRenderer;\n var dom = state.dom;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n var markerTypes = mobiledoc.markups;\n\n validateVersion(version);\n\n this.dom = dom;\n this.root = this.dom.createDocumentFragment();\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.markerTypes = markerTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 4);\n\n var type = _marker[0];\n var openTypes = _marker[1];\n var closeCount = _marker[2];\n var value = _marker[3];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n switch (type) {\n case _mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, value));\n break;\n case _mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n currentElement.appendChild(this._renderAtom(value));\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var index = _ref42[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this5 = this;\n\n var env = {\n name: atom.name,\n isInEditor: false,\n dom: this.dom,\n onTeardown: function onTeardown(callback) {\n return _this5._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || (0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, '');\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 4);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n var _ref52$3 = _ref52[3];\n var attributes = _ref52$3 === undefined ? [] : _ref52$3;\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var attrsObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attributes);\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom, attrsObj);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref7) {\n var name = _ref7.env.name;\n\n throw new Error('Atom \"' + name + '\" not found but no unknownAtomHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-dom-renderer/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.includes = includes;\n exports.kvArrayToObject = kvArrayToObject;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n\n function includes(array, detectValue) {\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n if (value === detectValue) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n\n function kvArrayToObject(array) {\n if (!Array.isArray(array)) {\n return {};\n }\n\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n /**\n * @param {Object} {key1:value1, key2:value2, ...}\n * @return {Array} array of key1,value1,key2,value2,...\n * @private\n */\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n});","define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) {\n 'use strict';\n\n exports.createTextNode = createTextNode;\n exports.normalizeTagName = normalizeTagName;\n function addHTMLSpaces(text) {\n var nbsp = ' ';\n return text.replace(/ /g, ' ' + nbsp);\n }\n\n function createTextNode(dom, text) {\n return dom.createTextNode(addHTMLSpaces(text));\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n});","define(\"mobiledoc-dom-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'dom';\n});","define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) {\n 'use strict';\n\n exports.defaultSectionElementRenderer = defaultSectionElementRenderer;\n exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer;\n var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n function _isValidAttribute(attr) {\n return VALID_ATTRIBUTES.indexOf(attr) !== -1;\n }\n\n function handleMarkupSectionAttribute(element, attributeKey, attributeValue) {\n if (!_isValidAttribute(attributeKey)) {\n throw new Error('Cannot use attribute: ' + attributeKey);\n }\n\n element.setAttribute(attributeKey, attributeValue);\n }\n\n function defaultSectionElementRenderer(tagName, dom) {\n var attrsObj = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var element = undefined;\n if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) {\n element = dom.createElement(tagName);\n\n Object.keys(attrsObj).forEach(function (k) {\n handleMarkupSectionAttribute(element, k, attrsObj[k]);\n });\n } else {\n element = dom.createElement('div');\n element.setAttribute('class', tagName);\n }\n\n return element;\n }\n\n function sanitizeAttribute(tagName, attrName, attrValue) {\n if (tagName === 'a' && attrName === 'href') {\n return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attrValue);\n } else {\n return attrValue;\n }\n }\n\n function defaultMarkupElementRenderer(tagName, dom, attrsObj) {\n var element = dom.createElement(tagName);\n Object.keys(attrsObj).forEach(function (attrName) {\n var attrValue = attrsObj[attrName];\n attrValue = sanitizeAttribute(tagName, attrName, attrValue);\n element.setAttribute(attrName, attrValue);\n });\n return element;\n }\n});","define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {\n 'use strict';\n\n exports.sanitizeHref = sanitizeHref;\n exports.reduceAttributes = reduceAttributes;\n\n var PROTOCOL_REGEXP = /^([a-z0-9.+-]+:)/i;\n\n var badProtocols = ['javascript:', // jshint ignore:line\n 'vbscript:' // jshint ignore:line\n ];\n\n function getProtocol(url) {\n var matches = url && url.match(PROTOCOL_REGEXP);\n var protocol = matches && matches[0] || ':';\n return protocol;\n }\n\n function sanitizeHref(url) {\n var protocol = getProtocol(url).toLowerCase();\n if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) {\n return 'unsafe:' + url;\n }\n return url;\n }\n\n /**\n * @param attributes array\n * @return obj with normalized attribute names (lowercased)\n */\n\n function reduceAttributes(attributes) {\n var obj = {};\n for (var i = 0; i < attributes.length; i += 2) {\n var key = attributes[i];\n var val = attributes[i + 1];\n obj[key.toLowerCase()] = val;\n }\n return obj;\n }\n});","define(\"mobiledoc-dom-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});","define('mobiledoc-dom-renderer/utils/tag-names', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsDom) {\n 'use strict';\n\n exports.isValidSectionTagName = isValidSectionTagName;\n exports.isMarkupSectionElementName = isMarkupSectionElementName;\n exports.isValidMarkerType = isValidMarkerType;\n\n var MARKUP_SECTION_TAG_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pull-quote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_SECTION_ELEMENT_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var LIST_SECTION_TAG_NAMES = ['ul', 'ol'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_TYPES = ['b', 'i', 'strong', 'em', 'a', 'u', 'sub', 'sup', 's', 'code'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function isValidSectionTagName(tagName, sectionType) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n\n switch (sectionType) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return contains(MARKUP_SECTION_TAG_NAMES, tagName);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return contains(LIST_SECTION_TAG_NAMES, tagName);\n default:\n throw new Error('Cannot validate tagName for unknown section type \"' + sectionType + '\"');\n }\n }\n\n function isMarkupSectionElementName(tagName) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n return contains(MARKUP_SECTION_ELEMENT_NAMES, tagName);\n }\n\n function isValidMarkerType(type) {\n type = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(type);\n return contains(MARKUP_TYPES, type);\n }\n});","define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder-image-src'], function (exports, _mobiledocKitUtilsPlaceholderImageSrc) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: 'dom',\n\n render: function render(_ref) {\n var payload = _ref.payload;\n\n var img = document.createElement('img');\n img.src = payload.src || _mobiledocKitUtilsPlaceholderImageSrc['default'];\n return img;\n }\n };\n});","define('mobiledoc-kit/editor/edit-history', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/utils/fixed-queue'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitUtilsFixedQueue) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function findLeafSectionAtIndex(post, index) {\n var section = undefined;\n post.walkAllLeafSections(function (_section, _index) {\n if (index === _index) {\n section = _section;\n }\n });\n return section;\n }\n\n var Snapshot = (function () {\n function Snapshot(takenAt, editor) {\n var editAction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n _classCallCheck(this, Snapshot);\n\n this.mobiledoc = editor.serialize();\n this.editor = editor;\n this.editAction = editAction;\n this.takenAt = takenAt;\n\n this.snapshotRange();\n }\n\n _createClass(Snapshot, [{\n key: 'snapshotRange',\n value: function snapshotRange() {\n var _editor = this.editor;\n var range = _editor.range;\n var cursor = _editor.cursor;\n\n if (cursor.hasCursor() && !range.isBlank) {\n var head = range.head;\n var tail = range.tail;\n\n this.range = {\n head: [head.leafSectionIndex, head.offset],\n tail: [tail.leafSectionIndex, tail.offset]\n };\n }\n }\n }, {\n key: 'getRange',\n value: function getRange(post) {\n if (this.range) {\n var _range = this.range;\n var head = _range.head;\n var tail = _range.tail;\n var _head = head;\n\n var _head2 = _slicedToArray(_head, 2);\n\n var headLeafSectionIndex = _head2[0];\n var headOffset = _head2[1];\n var _tail = tail;\n\n var _tail2 = _slicedToArray(_tail, 2);\n\n var tailLeafSectionIndex = _tail2[0];\n var tailOffset = _tail2[1];\n\n var headSection = findLeafSectionAtIndex(post, headLeafSectionIndex);\n var tailSection = findLeafSectionAtIndex(post, tailLeafSectionIndex);\n\n head = headSection.toPosition(headOffset);\n tail = tailSection.toPosition(tailOffset);\n\n return head.toRange(tail);\n }\n }\n }, {\n key: 'groupsWith',\n value: function groupsWith(groupingTimeout, editAction, takenAt) {\n return editAction !== null && this.editAction === editAction && this.takenAt + groupingTimeout > takenAt;\n }\n }]);\n\n return Snapshot;\n })();\n\n exports.Snapshot = Snapshot;\n\n var EditHistory = (function () {\n function EditHistory(editor, queueLength, groupingTimeout) {\n _classCallCheck(this, EditHistory);\n\n this.editor = editor;\n this._undoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n this._redoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n\n this._pendingSnapshot = null;\n this._groupingTimeout = groupingTimeout;\n }\n\n _createClass(EditHistory, [{\n key: 'snapshot',\n value: function snapshot() {\n // update the current snapshot with the range read from DOM\n if (this._pendingSnapshot) {\n this._pendingSnapshot.snapshotRange();\n }\n }\n }, {\n key: 'storeSnapshot',\n value: function storeSnapshot() {\n var editAction = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];\n\n var now = Date.now();\n // store pending snapshot\n var pendingSnapshot = this._pendingSnapshot;\n if (pendingSnapshot) {\n if (!pendingSnapshot.groupsWith(this._groupingTimeout, editAction, now)) {\n this._undoStack.push(pendingSnapshot);\n }\n this._redoStack.clear();\n }\n\n // take new pending snapshot to store next time `storeSnapshot` is called\n this._pendingSnapshot = new Snapshot(now, this.editor, editAction);\n }\n }, {\n key: 'stepBackward',\n value: function stepBackward(postEditor) {\n // Throw away the pending snapshot\n this._pendingSnapshot = null;\n\n var snapshot = this._undoStack.pop();\n if (snapshot) {\n this._redoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n }\n }, {\n key: 'stepForward',\n value: function stepForward(postEditor) {\n var snapshot = this._redoStack.pop();\n if (snapshot) {\n this._undoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n postEditor.cancelSnapshot();\n }\n }, {\n key: '_restoreFromSnapshot',\n value: function _restoreFromSnapshot(snapshot, postEditor) {\n var mobiledoc = snapshot.mobiledoc;\n var editor = this.editor;\n var builder = editor.builder;\n var post = editor.post;\n\n var restoredPost = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(restoredPost);\n\n // resurrect snapshotted range if it exists\n var newRange = snapshot.getRange(post);\n if (newRange) {\n postEditor.setRange(newRange);\n }\n }\n }]);\n\n return EditHistory;\n })();\n\n exports['default'] = EditHistory;\n});","define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * Used by {@link Editor} to manage its current state (cursor, active markups\n * and active sections).\n * @private\n */\n\n var EditState = (function () {\n function EditState(editor) {\n _classCallCheck(this, EditState);\n\n this.editor = editor;\n\n var defaultState = {\n range: _mobiledocKitUtilsCursorRange['default'].blankRange(),\n activeMarkups: [],\n activeSections: [],\n activeSectionTagNames: [],\n activeSectionAttributes: {}\n };\n\n this.prevState = this.state = defaultState;\n }\n\n _createClass(EditState, [{\n key: 'updateRange',\n value: function updateRange(newRange) {\n this.prevState = this.state;\n this.state = this._readState(newRange);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.editor = null;\n this.prevState = this.state = null;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'rangeDidChange',\n value: function rangeDidChange() {\n var range = this.state.range;\n var prevRange = this.prevState.range;\n\n return !prevRange.isEqual(range);\n }\n\n /**\n * @return {Boolean} Whether the input mode (active markups or active section tag names)\n * has changed.\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange() {\n var state = this.state;\n var prevState = this.prevState;\n\n return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)((0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes));\n }\n\n /**\n * @return {Range}\n */\n }, {\n key: 'toggleMarkupState',\n\n /**\n * Update the editor's markup state. This is used when, e.g.,\n * a user types meta+B when the editor has a cursor but no selected text;\n * in this case the editor needs to track that it has an active \"b\" markup\n * and apply it to the next text the user types.\n */\n value: function toggleMarkupState(markup) {\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(this.activeMarkups, markup)) {\n this._removeActiveMarkup(markup);\n } else {\n this._addActiveMarkup(markup);\n }\n }\n }, {\n key: '_readState',\n value: function _readState(range) {\n var state = {\n range: range,\n activeMarkups: this._readActiveMarkups(range),\n activeSections: this._readActiveSections(range)\n };\n // Section objects are 'live', so to check that they changed, we\n // need to map their tagNames now (and compare to mapped tagNames later).\n // In addition, to catch changes from ul -> ol, we keep track of the\n // un-nested tag names (otherwise we'd only see li -> li change)\n state.activeSectionTagNames = state.activeSections.map(function (s) {\n return s.isNested ? s.parent.tagName : s.tagName;\n });\n state.activeSectionAttributes = this._readSectionAttributes(state.activeSections);\n return state;\n }\n }, {\n key: '_readActiveSections',\n value: function _readActiveSections(range) {\n var head = range.head;\n var tail = range.tail;\n var post = this.editor.post;\n\n if (range.isBlank) {\n return [];\n } else {\n return post.sections.readRange(head.section, tail.section);\n }\n }\n }, {\n key: '_readActiveMarkups',\n value: function _readActiveMarkups(range) {\n var post = this.editor.post;\n\n return post.markupsInRange(range);\n }\n }, {\n key: '_readSectionAttributes',\n value: function _readSectionAttributes(sections) {\n return sections.reduce(function (sectionAttributes, s) {\n var attributes = s.isNested ? s.parent.attributes : s.attributes;\n Object.keys(attributes || {}).forEach(function (attrName) {\n var camelizedAttrName = attrName.replace(/^data-md-/, '');\n var attrValue = attributes[attrName];\n sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || [];\n if (!(0, _mobiledocKitUtilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) {\n sectionAttributes[camelizedAttrName].push(attrValue);\n }\n });\n return sectionAttributes;\n }, {});\n }\n }, {\n key: '_removeActiveMarkup',\n value: function _removeActiveMarkup(markup) {\n var index = this.state.activeMarkups.indexOf(markup);\n this.state.activeMarkups.splice(index, 1);\n }\n }, {\n key: '_addActiveMarkup',\n value: function _addActiveMarkup(markup) {\n this.state.activeMarkups.push(markup);\n }\n }, {\n key: 'range',\n get: function get() {\n return this.state.range;\n }\n\n /**\n * @return {Section[]}\n */\n }, {\n key: 'activeSections',\n get: function get() {\n return this.state.activeSections;\n }\n\n /**\n * @return {Object}\n */\n }, {\n key: 'activeSectionAttributes',\n get: function get() {\n return this.state.activeSectionAttributes;\n }\n\n /**\n * @return {Markup[]}\n */\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this.state.activeMarkups;\n }\n }]);\n\n return EditState;\n })();\n\n exports['default'] = EditState;\n});","define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/element-utils', 'mobiledoc-kit/utils/cursor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/environment', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/text-input-handlers', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/editor/mutation-handler', 'mobiledoc-kit/editor/edit-history', 'mobiledoc-kit/editor/event-manager', 'mobiledoc-kit/editor/edit-state', 'mobiledoc-dom-renderer', 'mobiledoc-text-renderer', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/log-manager', 'mobiledoc-kit/utils/to-range', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitViewsTooltip, _mobiledocKitEditorPost, _mobiledocKitCardsImage, _mobiledocKitUtilsKey, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersDom, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree, _mobiledocKitRenderersMobiledoc, _mobiledocKitUtilsMerge, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsElementUtils, _mobiledocKitUtilsCursor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsEnvironment, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorTextInputHandlers, _mobiledocKitEditorKeyCommands, _mobiledocKitModelsCard, _mobiledocKitUtilsAssert, _mobiledocKitEditorMutationHandler, _mobiledocKitEditorEditHistory, _mobiledocKitEditorEventManager, _mobiledocKitEditorEditState, _mobiledocDomRenderer, _mobiledocTextRenderer, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsLogManager, _mobiledocKitUtilsToRange, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // This export may later be deprecated, but re-export it from the renderer here\n // for consumers that may depend on it.\n Object.defineProperty(exports, 'EDITOR_ELEMENT_CLASS_NAME', {\n enumerable: true,\n get: function get() {\n return _mobiledocKitRenderersEditorDom.EDITOR_ELEMENT_CLASS_NAME;\n }\n });\n\n var defaults = {\n placeholder: 'Write here...',\n spellcheck: true,\n autofocus: true,\n showLinkTooltips: true,\n undoDepth: 5,\n undoBlockTimeout: 5000, // ms for an undo event\n cards: [],\n atoms: [],\n cardOptions: {},\n unknownCardHandler: function unknownCardHandler(_ref) {\n var env = _ref.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown card encountered: ' + env.name);\n },\n unknownAtomHandler: function unknownAtomHandler(_ref2) {\n var env = _ref2.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown atom encountered: ' + env.name);\n },\n mobiledoc: null,\n html: null\n };\n\n var CALLBACK_QUEUES = {\n DID_UPDATE: 'didUpdate',\n WILL_RENDER: 'willRender',\n DID_RENDER: 'didRender',\n WILL_DELETE: 'willDelete',\n DID_DELETE: 'didDelete',\n WILL_HANDLE_NEWLINE: 'willHandleNewline',\n CURSOR_DID_CHANGE: 'cursorDidChange',\n DID_REPARSE: 'didReparse',\n POST_DID_CHANGE: 'postDidChange',\n INPUT_MODE_DID_CHANGE: 'inputModeDidChange'\n };\n\n /**\n * The Editor is a core component of mobiledoc-kit. After instantiating\n * an editor, use {@link Editor#render} to display the editor on the web page.\n *\n * An editor uses a {@link Post} internally to represent the displayed document.\n * The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc\n * is the transportable \"over-the-wire\" format (JSON) that is suited for persisting\n * and sharing between editors and renderers (for display, e.g.), whereas the Post\n * model is better suited for programmatic editing.\n *\n * The editor will call registered callbacks for certain state changes. These are:\n * * {@link Editor#cursorDidChange} -- The cursor position or selection changed.\n * * {@link Editor#postDidChange} -- The contents of the post changed due to user input or\n * programmatic editing. This hook can be used with {@link Editor#serialize}\n * to auto-save a post as it is being edited.\n * * {@link Editor#inputModeDidChange} -- The active section(s) or markup(s) at the current cursor\n * position or selection have changed. This hook can be used with\n * {@link Editor#activeMarkups} and {@link Editor#activeSections} to implement\n * a custom toolbar.\n * * {@link Editor#onTextInput} -- Register callbacks when the user enters text\n * that matches a given string or regex.\n * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before\n * applying changes from {@link Editor#toggleMarkup}\n */\n\n var Editor = (function () {\n /**\n * @param {Object} [options]\n * @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.\n * Supersedes `options.html`.\n * @param {String|DOM} [options.html] The html (as a string or DOM fragment)\n * to parse and load into the editor.\n * Will be ignored if `options.mobiledoc` is also passed.\n * @param {Array} [options.parserPlugins=[]]\n * @param {Array} [options.cards=[]] The cards that the editor may render.\n * @param {Array} [options.atoms=[]] The atoms that the editor may render.\n * @param {Function} [options.unknownCardHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown card.\n * @param {Function} [options.unknownAtomHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown atom.\n * @param {String} [options.placeholder] Default text to show before user starts typing.\n * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck\n * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered.\n * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links\n * @param {number} [options.undoDepth=5] How many undo levels will be available.\n * Set to 0 to disable undo/redo functionality.\n * @return {Editor}\n * @public\n */\n\n function Editor() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, Editor);\n\n (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType);\n this._views = [];\n this.isEditable = true;\n this._parserPlugins = options.parserPlugins || [];\n\n // FIXME: This should merge onto this.options\n (0, _mobiledocKitUtilsMerge.mergeWithOptions)(this, defaults, options);\n this.cards.push(_mobiledocKitCardsImage['default']);\n\n _mobiledocKitEditorKeyCommands.DEFAULT_KEY_COMMANDS.forEach(function (kc) {\n return _this.registerKeyCommand(kc);\n });\n\n this._logManager = new _mobiledocKitUtilsLogManager['default']();\n this._parser = new _mobiledocKitParsersDom['default'](this.builder);\n var cards = this.cards;\n var atoms = this.atoms;\n var unknownCardHandler = this.unknownCardHandler;\n var unknownAtomHandler = this.unknownAtomHandler;\n var cardOptions = this.cardOptions;\n\n this._renderer = new _mobiledocKitRenderersEditorDom['default'](this, cards, atoms, unknownCardHandler, unknownAtomHandler, cardOptions);\n\n this.post = this.loadPost();\n this._renderTree = new _mobiledocKitModelsRenderTree['default'](this.post);\n\n this._editHistory = new _mobiledocKitEditorEditHistory['default'](this, this.undoDepth, this.undoBlockTimeout);\n this._eventManager = new _mobiledocKitEditorEventManager['default'](this);\n this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this);\n this._editState = new _mobiledocKitEditorEditState['default'](this);\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n this._beforeHooks = { toggleMarkup: [] };\n\n _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) {\n return _this.onTextInput(handler);\n });\n\n this.hasRendered = false;\n }\n\n /**\n * Turns on verbose logging for the editor.\n * @param {Array} [logTypes=[]] If present, only the given log types will be logged.\n * @public\n */\n\n _createClass(Editor, [{\n key: 'enableLogging',\n value: function enableLogging() {\n var logTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n if (logTypes.length === 0) {\n this._logManager.enableAll();\n } else {\n this._logManager.enableTypes(logTypes);\n }\n }\n\n /**\n * Disable all logging\n * @public\n */\n }, {\n key: 'disableLogging',\n value: function disableLogging() {\n this._logManager.disable();\n }\n\n /**\n * @private\n */\n }, {\n key: 'loggerFor',\n value: function loggerFor(type) {\n return this._logManager['for'](type);\n }\n\n /**\n * The editor's instance of a post node builder.\n * @type {PostNodeBuilder}\n */\n }, {\n key: 'loadPost',\n value: function loadPost() {\n var mobiledoc = this.mobiledoc;\n var html = this.html;\n\n if (mobiledoc) {\n return _mobiledocKitParsersMobiledoc['default'].parse(this.builder, mobiledoc);\n } else if (html) {\n if (typeof html === 'string') {\n var options = { plugins: this._parserPlugins };\n return new _mobiledocKitParsersHtml['default'](this.builder, options).parse(this.html);\n } else {\n var dom = html;\n return this._parser.parse(dom);\n }\n } else {\n return this.builder.createPost();\n }\n }\n }, {\n key: 'rerender',\n value: function rerender() {\n var _this2 = this;\n\n var postRenderNode = this.post.renderNode;\n\n // if we haven't rendered this post's renderNode before, mark it dirty\n if (!postRenderNode.element) {\n (0, _mobiledocKitUtilsAssert['default'])('Must call `render` before `rerender` can be called', this.hasRendered);\n postRenderNode.element = this.element;\n postRenderNode.markDirty();\n }\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_RENDER);\n this._mutationHandler.suspendObservation(function () {\n _this2._renderer.render(_this2._renderTree);\n });\n this.runCallbacks(CALLBACK_QUEUES.DID_RENDER);\n }\n\n /**\n * @param {Element} element The DOM element to render into.\n * Its contents will be replaced by the editor's rendered post.\n * @public\n */\n }, {\n key: 'render',\n value: function render(element) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot render an editor twice. Use `rerender` to update the ' + 'rendering of an existing editor instance.', !this.hasRendered);\n\n element.spellcheck = this.spellcheck;\n\n (0, _mobiledocKitUtilsDomUtils.clearChildNodes)(element);\n\n this.element = element;\n\n if (this.showLinkTooltips) {\n this._addTooltip();\n }\n\n // A call to `run` will trigger the didUpdatePostCallbacks hooks with a\n // postEditor.\n this.run(function () {});\n\n // Only set `hasRendered` to true after calling `run` to ensure that\n // no cursorDidChange or other callbacks get fired before the editor is\n // done rendering\n this.hasRendered = true;\n this.rerender();\n\n this._mutationHandler.init();\n this._eventManager.init();\n\n if (this.isEditable === false) {\n this.disableEditing();\n } else {\n this.enableEditing();\n }\n\n if (this.autofocus) {\n this.selectRange(this.post.headPosition());\n }\n }\n }, {\n key: '_addTooltip',\n value: function _addTooltip() {\n this.addView(new _mobiledocKitViewsTooltip['default']({\n rootElement: this.element,\n showForTag: 'a'\n }));\n }\n }, {\n key: 'registerKeyCommand',\n\n /**\n * @param {Object} keyCommand The key command to register. It must specify a\n * modifier key (meta, ctrl, etc), a string representing the ascii key, and\n * a `run` method that will be passed the editor instance when the key command\n * is invoked\n * @public\n */\n value: function registerKeyCommand(rawKeyCommand) {\n var keyCommand = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)(rawKeyCommand);\n (0, _mobiledocKitUtilsAssert['default'])('Key Command is not valid', (0, _mobiledocKitEditorKeyCommands.validateKeyCommand)(keyCommand));\n this.keyCommands.unshift(keyCommand);\n }\n\n /**\n * @param {String} name If the keyCommand event has a name attribute it can be removed.\n * @public\n */\n }, {\n key: 'unregisterKeyCommands',\n value: function unregisterKeyCommands(name) {\n for (var i = this.keyCommands.length - 1; i > -1; i--) {\n var keyCommand = this.keyCommands[i];\n\n if (keyCommand.name === name) {\n this.keyCommands.splice(i, 1);\n }\n }\n }\n\n /**\n * Convenience for {@link PostEditor#deleteAtPosition}. Deletes and puts the\n * cursor in the new position.\n * @public\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position, direction, _ref3) {\n var unit = _ref3.unit;\n\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteAtPosition(position, direction, { unit: unit });\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * Convenience for {@link PostEditor#deleteRange}. Deletes and puts the\n * cursor in the new position.\n * @param {Range} range\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * @private\n */\n }, {\n key: 'performDelete',\n value: function performDelete() {\n var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? { direction: _mobiledocKitUtilsKey.DIRECTION.BACKWARD, unit: 'char' } : arguments[0];\n\n var direction = _ref4.direction;\n var unit = _ref4.unit;\n var range = this.range;\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_DELETE, [range, direction, unit]);\n if (range.isCollapsed) {\n this.deleteAtPosition(range.head, direction, { unit: unit });\n } else {\n this.deleteRange(range);\n }\n this.runCallbacks(CALLBACK_QUEUES.DID_DELETE, [range, direction, unit]);\n }\n }, {\n key: 'handleNewline',\n value: function handleNewline(event) {\n var _this3 = this;\n\n if (!this.hasCursor()) {\n return;\n }\n\n event.preventDefault();\n\n var range = this.range;\n\n this.run(function (postEditor) {\n var cursorSection = undefined;\n if (!range.isCollapsed) {\n var nextPosition = postEditor.deleteRange(range);\n cursorSection = nextPosition.section;\n if (cursorSection && cursorSection.isBlank) {\n postEditor.setRange(cursorSection.headPosition());\n return;\n }\n }\n\n // Above logic might delete redundant range, so callback must run after it.\n var defaultPrevented = false;\n var event = { preventDefault: function preventDefault() {\n defaultPrevented = true;\n } };\n _this3.runCallbacks(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, [event]);\n if (defaultPrevented) {\n return;\n }\n\n cursorSection = postEditor.splitSection(range.head)[1];\n postEditor.setRange(cursorSection.headPosition());\n });\n }\n\n /**\n * Notify the editor that the post did change, and run associated\n * callbacks.\n * @private\n */\n }, {\n key: '_postDidChange',\n value: function _postDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.POST_DID_CHANGE);\n }\n\n /**\n * Selects the given range or position. If given a collapsed range or a position, this positions the cursor\n * at the range's position. Otherwise a selection is created in the editor\n * surface encompassing the range.\n * @param {Range|Position} range\n */\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n this.cursor.selectRange(range);\n this.range = range;\n }\n }, {\n key: '_readRangeFromDOM',\n value: function _readRangeFromDOM() {\n this.range = this.cursor.offsets;\n }\n }, {\n key: 'setPlaceholder',\n value: function setPlaceholder(placeholder) {\n (0, _mobiledocKitUtilsElementUtils.setData)(this.element, 'placeholder', placeholder);\n }\n }, {\n key: '_reparsePost',\n value: function _reparsePost() {\n var post = this._parser.parse(this.element);\n this.run(function (postEditor) {\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(post);\n postEditor.setRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n });\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n }, {\n key: '_reparseSections',\n value: function _reparseSections() {\n var _this4 = this;\n\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var currentRange = undefined;\n sections.forEach(function (section) {\n _this4._parser.reparseSection(section, _this4._renderTree);\n });\n this._removeDetachedSections();\n\n if (this._renderTree.isDirty) {\n currentRange = this.range;\n }\n\n // force the current snapshot's range to remain the same rather than\n // rereading it from DOM after the new character is applied and the browser\n // updates the cursor position\n var range = this._editHistory._pendingSnapshot.range;\n this.run(function () {\n _this4._editHistory._pendingSnapshot.range = range;\n });\n this.rerender();\n if (currentRange) {\n this.selectRange(currentRange);\n }\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n\n // FIXME this should be able to be removed now -- if any sections are detached,\n // it's due to a bug in the code.\n }, {\n key: '_removeDetachedSections',\n value: function _removeDetachedSections() {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.post.sections, function (s) {\n return !s.renderNode.isAttached();\n }), function (s) {\n return s.renderNode.scheduleForRemoval();\n });\n }\n\n /**\n * The sections from the cursor's selection start to the selection end\n * @type {Section[]}\n */\n }, {\n key: 'detectMarkupInRange',\n value: function detectMarkupInRange(range, markupTagName) {\n var markups = this.post.markupsInRange(range);\n return (0, _mobiledocKitUtilsArrayUtils.detect)(markups, function (markup) {\n return markup.hasTag(markupTagName);\n });\n }\n\n /**\n * @type {Markup[]}\n * @public\n */\n }, {\n key: 'hasActiveMarkup',\n\n /**\n * @param {Markup|String} markup A markup instance, or a string (e.g. \"b\")\n * @return {boolean}\n */\n value: function hasActiveMarkup(markup) {\n var matchesFn = undefined;\n if (typeof markup === 'string') {\n (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(markup);\n matchesFn = function (m) {\n return m.tagName === tagName;\n };\n })();\n } else {\n matchesFn = function (m) {\n return m === markup;\n };\n }\n\n return !!(0, _mobiledocKitUtilsArrayUtils.detect)(this.activeMarkups, matchesFn);\n }\n\n /**\n * @param {String} version The mobiledoc version to serialize to.\n * @return {Mobiledoc} Serialized mobiledoc\n * @public\n */\n }, {\n key: 'serialize',\n value: function serialize() {\n var version = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION : arguments[0];\n\n return this.serializePost(this.post, 'mobiledoc', { version: version });\n }\n\n /**\n * Serialize the editor's post to the requested format.\n * Note that only mobiledoc format is lossless. If cards or atoms are present\n * in the post, the html and text formats will omit them in output because\n * the editor does not have access to the html and text versions of the\n * cards/atoms.\n * @param {string} format The format to serialize ('mobiledoc', 'text', 'html')\n * @return {Object|String} The editor's post, serialized to {format}\n * @public\n */\n }, {\n key: 'serializeTo',\n value: function serializeTo(format) {\n var post = this.post;\n return this.serializePost(post, format);\n }\n\n /**\n * @param {Post}\n * @param {String} format Same as {serializeTo}\n * @param {Object} [options]\n * @param {String} [options.version=MOBILEDOC_VERSION] version to serialize to\n * @return {Object|String}\n * @private\n */\n }, {\n key: 'serializePost',\n value: function serializePost(post, format) {\n var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var validFormats = ['mobiledoc', 'html', 'text'];\n (0, _mobiledocKitUtilsAssert['default'])('Unrecognized serialization format ' + format, (0, _mobiledocKitUtilsArrayUtils.contains)(validFormats, format));\n\n if (format === 'mobiledoc') {\n var version = options.version || _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n return _mobiledocKitRenderersMobiledoc['default'].render(post, version);\n } else {\n var rendered = undefined;\n var mobiledoc = this.serializePost(post, 'mobiledoc');\n var unknownCardHandler = function unknownCardHandler() {};\n var unknownAtomHandler = function unknownAtomHandler() {};\n var rendererOptions = { unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n\n switch (format) {\n case 'html':\n {\n var result = undefined;\n if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) {\n rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc);\n result = '
    ' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
    ';\n } else {\n // Fallback to text serialization\n result = this.serializePost(post, 'text', options);\n }\n return result;\n }\n case 'text':\n rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc);\n return rendered.result;\n }\n }\n }\n }, {\n key: 'addView',\n value: function addView(view) {\n this._views.push(view);\n }\n }, {\n key: 'removeAllViews',\n value: function removeAllViews() {\n this._views.forEach(function (v) {\n return v.destroy();\n });\n this._views = [];\n }\n\n /**\n * Whether the editor has a cursor (or a selected range).\n * It is possible for the editor to be focused but not have a selection.\n * In this case, key events will fire but the editor will not be able to\n * determine a cursor position, so they will be ignored.\n * @return {boolean}\n * @public\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.cursor.hasCursor();\n }\n\n /**\n * Tears down the editor's attached event listeners and views.\n * @public\n */\n }, {\n key: 'destroy',\n value: function destroy() {\n this.isDestroyed = true;\n if (this._hasSelection()) {\n this.cursor.clearSelection();\n }\n if (this._hasFocus()) {\n this.element.blur(); // FIXME This doesn't blur the element on IE11\n }\n this._mutationHandler.destroy();\n this._eventManager.destroy();\n this.removeAllViews();\n this._renderer.destroy();\n this._editState.destroy();\n }\n\n /**\n * Keep the user from directly editing the post using the keyboard and mouse.\n * Modification via the programmatic API is still permitted.\n * @see Editor#enableEditing\n * @public\n */\n }, {\n key: 'disableEditing',\n value: function disableEditing() {\n this.isEditable = false;\n if (this.hasRendered) {\n this._eventManager.stop();\n this.element.setAttribute('contentEditable', false);\n this.setPlaceholder('');\n this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n }\n }\n\n /**\n * Allow the user to directly interact with editing a post via keyboard and mouse input.\n * Editor instances are editable by default. Use this method to re-enable\n * editing after disabling it.\n * @see Editor#disableEditing\n * @public\n */\n }, {\n key: 'enableEditing',\n value: function enableEditing() {\n this.isEditable = true;\n if (this.hasRendered) {\n this._eventManager.start();\n this.element.setAttribute('contentEditable', true);\n this.setPlaceholder(this.placeholder);\n }\n }\n\n /**\n * Change a cardSection into edit mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in edit mode when it gets rendered.\n * @param {CardSection} cardSection\n * @public\n */\n }, {\n key: 'editCard',\n value: function editCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.EDIT);\n }\n\n /**\n * Change a cardSection into display mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in display mode when it gets rendered.\n * @param {CardSection} cardSection\n * @return undefined\n * @public\n */\n }, {\n key: 'displayCard',\n value: function displayCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.DISPLAY);\n }\n\n /**\n * Run a new post editing session. Yields a block with a new {@link PostEditor}\n * instance. This instance can be used to interact with the post abstract.\n * Rendering will be deferred until after the callback is completed.\n *\n * Usage:\n * ```\n * let markerRange = this.range;\n * editor.run((postEditor) => {\n * postEditor.deleteRange(markerRange);\n * // editing surface not updated yet\n * postEditor.schedule(() => {\n * console.log('logs during rerender flush');\n * });\n * // logging not yet flushed\n * });\n * // editing surface now updated.\n * // logging now flushed\n * ```\n *\n * @param {Function} callback Called with an instance of\n * {@link PostEditor} as its argument.\n * @return {Mixed} The return value of `callback`.\n * @public\n */\n }, {\n key: 'run',\n value: function run(callback) {\n var postEditor = new _mobiledocKitEditorPost['default'](this);\n postEditor.begin();\n this._editHistory.snapshot();\n var result = callback(postEditor);\n this.runCallbacks(CALLBACK_QUEUES.DID_UPDATE, [postEditor]);\n postEditor.complete();\n this._readRangeFromDOM();\n\n if (postEditor._shouldCancelSnapshot) {\n this._editHistory._pendingSnapshot = null;\n }\n this._editHistory.storeSnapshot(postEditor.editActionTaken);\n\n return result;\n }\n\n /**\n * @param {Function} callback Called with `postEditor` as its argument.\n * @public\n */\n }, {\n key: 'didUpdatePost',\n value: function didUpdatePost(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_UPDATE, callback);\n }\n\n /**\n * @param {Function} callback Called when the post has changed, either via\n * user input or programmatically. Use with {@link Editor#serialize} to\n * retrieve the post in portable mobiledoc format.\n */\n }, {\n key: 'postDidChange',\n value: function postDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.POST_DID_CHANGE, callback);\n }\n\n /**\n * Register a handler that will be invoked by the editor after the user enters\n * matching text.\n * @param {Object} inputHandler\n * @param {String} inputHandler.name Required. Used by identifying handlers.\n * @param {String} [inputHandler.text] Required if `match` is not provided\n * @param {RegExp} [inputHandler.match] Required if `text` is not provided\n * @param {Function} inputHandler.run This callback is invoked with the {@link Editor}\n * instance and an array of matches. If `text` was provided,\n * the matches array will equal [`text`], and if a `match`\n * regex was provided the matches array will be the result of\n * `match.exec` on the matching text. The callback is called\n * after the matching text has been inserted.\n * @public\n */\n }, {\n key: 'onTextInput',\n value: function onTextInput(inputHandler) {\n this._eventManager.registerInputHandler(inputHandler);\n }\n\n /**\n * Unregister all text input handlers\n *\n * @public\n */\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._eventManager.unregisterAllTextInputHandlers();\n }\n\n /**\n * Unregister text input handler by name\n * @param {String} name The name of handler to be removed\n *\n * @public\n */\n }, {\n key: 'unregisterTextInputHandler',\n value: function unregisterTextInputHandler(name) {\n this._eventManager.unregisterInputHandler(name);\n }\n\n /**\n * @param {Function} callback Called when the editor's state (active markups or\n * active sections) has changed, either via user input or programmatically\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'willRender',\n value: function willRender(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'didRender',\n value: function didRender(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before deleting.\n * @public\n */\n }, {\n key: 'willDelete',\n value: function willDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after deleting.\n * @public\n */\n }, {\n key: 'didDelete',\n value: function didDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before handling new line.\n * @public\n */\n }, {\n key: 'willHandleNewline',\n value: function willHandleNewline(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called every time the cursor\n * position (or selection) changes.\n * @public\n */\n }, {\n key: 'cursorDidChange',\n value: function cursorDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.CURSOR_DID_CHANGE, callback);\n }\n }, {\n key: '_rangeDidChange',\n value: function _rangeDidChange() {\n if (this.hasRendered) {\n this.runCallbacks(CALLBACK_QUEUES.CURSOR_DID_CHANGE);\n }\n }\n }, {\n key: '_inputModeDidChange',\n value: function _inputModeDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE);\n }\n }, {\n key: '_insertEmptyMarkupSectionAtCursor',\n value: function _insertEmptyMarkupSectionAtCursor() {\n var _this5 = this;\n\n this.run(function (postEditor) {\n var section = postEditor.builder.createMarkupSection('p');\n postEditor.insertSectionBefore(_this5.post.sections, section);\n postEditor.setRange(section.toRange());\n });\n }\n\n /**\n * @callback editorBeforeCallback\n * @param { Object } details\n * @param { Markup } details.markup\n * @param { Range } details.range\n * @param { boolean } details.willAdd Whether the markup will be applied\n */\n\n /**\n * Register a callback that will be run before {@link Editor#toggleMarkup} is applied.\n * If any callback returns literal `false`, the toggling of markup will be canceled.\n * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and\n * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks.\n * @param {editorBeforeCallback}\n */\n }, {\n key: 'beforeToggleMarkup',\n value: function beforeToggleMarkup(callback) {\n this._beforeHooks.toggleMarkup.push(callback);\n }\n\n /**\n * Toggles the given markup at the editor's current {@link Range}.\n * If the range is collapsed this changes the editor's state so that the\n * next characters typed will be affected. If there is text selected\n * (aka a non-collapsed range), the selections' markup will be toggled.\n * If the editor is not focused and has no active range, nothing happens.\n * Hooks added using #beforeToggleMarkup will be run before toggling,\n * and if any of them returns literal false, toggling the markup will be canceled\n * and no change will be applied.\n * @param {String} markup E.g. \"b\", \"em\", \"a\"\n * @param {Object} [attributes={}] E.g. {href: \"http://bustle.com\"}\n * @public\n * @see PostEditor#toggleMarkup\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markup) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n markup = this.builder.createMarkup(markup, attributes);\n var range = this.range;\n\n var willAdd = !this.detectMarkupInRange(range, markup.tagName);\n var shouldCancel = this._runBeforeHooks('toggleMarkup', { markup: markup, range: range, willAdd: willAdd });\n if (shouldCancel) {\n return;\n }\n\n if (range.isCollapsed) {\n this._editState.toggleMarkupState(markup);\n this._inputModeDidChange();\n\n // when clicking a button to toggle markup, the button can end up being focused,\n // so ensure the editor is focused\n this._ensureFocus();\n } else {\n this.run(function (postEditor) {\n return postEditor.toggleMarkup(markup, range);\n });\n }\n }\n\n // If the editor has a selection but is not focused, focus it\n }, {\n key: '_ensureFocus',\n value: function _ensureFocus() {\n if (this._hasSelection() && !this._hasFocus()) {\n this.focus();\n }\n }\n }, {\n key: 'focus',\n value: function focus() {\n this.element.focus();\n }\n\n /**\n * Whether there is a selection inside the editor's element.\n * It's possible to have a selection but not have focus.\n * @see #_hasFocus\n * @return {Boolean}\n */\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var cursor = this.cursor;\n\n return this.hasRendered && (cursor._hasCollapsedSelection() || cursor._hasSelection());\n }\n\n /**\n * Whether the editor's element is focused\n * It's possible to be focused but have no selection\n * @see #_hasSelection\n * @return {Boolean}\n */\n }, {\n key: '_hasFocus',\n value: function _hasFocus() {\n return document.activeElement === this.element;\n }\n\n /**\n * Toggles the tagName for the current active section(s). This will skip\n * non-markerable sections. E.g. if the editor's range includes a \"P\" MarkupSection\n * and a CardSection, only the MarkupSection will be toggled.\n * @param {String} tagName The new tagname to change to.\n * @public\n * @see PostEditor#toggleSection\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(tagName) {\n var _this6 = this;\n\n this.run(function (postEditor) {\n return postEditor.toggleSection(tagName, _this6.range);\n });\n }\n\n /**\n * Sets an attribute for the current active section(s).\n *\n * @param {String} key The attribute. The only valid attribute is 'text-align'.\n * @param {String} value The value of the attribute.\n * @public\n * @see PostEditor#setAttribute\n */\n }, {\n key: 'setAttribute',\n value: function setAttribute(key, value) {\n var _this7 = this;\n\n this.run(function (postEditor) {\n return postEditor.setAttribute(key, value, _this7.range);\n });\n }\n\n /**\n * Removes an attribute from the current active section(s).\n *\n * @param {String} key The attribute. The only valid attribute is 'text-align'.\n * @public\n * @see PostEditor#removeAttribute\n */\n }, {\n key: 'removeAttribute',\n value: function removeAttribute(key) {\n var _this8 = this;\n\n this.run(function (postEditor) {\n return postEditor.removeAttribute(key, _this8.range);\n });\n }\n\n /**\n * Finds and runs the first matching key command for the event\n *\n * If multiple commands are bound to a key combination, the\n * first matching one is run.\n *\n * If a command returns `false` then the next matching command\n * is run instead.\n *\n * @param {Event} event The keyboard event triggered by the user\n * @return {Boolean} true when a command was successfully run\n * @private\n */\n }, {\n key: 'handleKeyCommand',\n value: function handleKeyCommand(event) {\n var keyCommands = (0, _mobiledocKitEditorKeyCommands.findKeyCommands)(this.keyCommands, event);\n for (var i = 0; i < keyCommands.length; i++) {\n var keyCommand = keyCommands[i];\n if (keyCommand.run(this) !== false) {\n event.preventDefault();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Inserts the text at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n *\n * @param {String} text\n * @public\n */\n }, {\n key: 'insertText',\n value: function insertText(text) {\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n var activeMarkups = this.activeMarkups;\n var range = this.range;\n var position = this.range.head;\n\n this.run(function (postEditor) {\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertTextWithMarkup(position, text, activeMarkups);\n });\n }\n\n /**\n * Inserts an atom at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n * @param {String} atomName\n * @param {String} [atomText='']\n * @param {Object} [atomPayload={}]\n * @return {Atom} The inserted atom.\n * @public\n */\n }, {\n key: 'insertAtom',\n value: function insertAtom(atomName) {\n var atomText = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var atomPayload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var atom = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.head;\n\n atom = postEditor.builder.createAtom(atomName, atomText, atomPayload);\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertMarkers(position, [atom]);\n });\n return atom;\n }\n\n /**\n * Inserts a card at the section after the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion. If the cursor is in\n * a blank section, it will be replaced with a card section.\n * The editor's cursor will be placed at the end of the inserted card.\n * @param {String} cardName\n * @param {Object} [cardPayload={}]\n * @param {Boolean} [inEditMode=false] Whether the card should be inserted in edit mode.\n * @return {Card} The inserted Card section.\n * @public\n */\n }, {\n key: 'insertCard',\n value: function insertCard(cardName) {\n var _this9 = this;\n\n var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var card = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.tail;\n card = postEditor.builder.createCardSection(cardName, cardPayload);\n if (inEditMode) {\n _this9.editCard(card);\n }\n\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n var section = position.section;\n if (section.isNested) {\n section = section.parent;\n }\n\n if (section.isBlank) {\n postEditor.replaceSection(section, card);\n } else {\n var collection = _this9.post.sections;\n postEditor.insertSectionBefore(collection, card, section.next);\n }\n\n // It is important to explicitly set the range to the end of the card.\n // Otherwise it is possible to create an inconsistent state in the\n // browser. For instance, if the user clicked a button that\n // called `editor.insertCard`, the editor surface may retain\n // the selection but lose focus, and the next keystroke by the user\n // will cause an unexpected DOM mutation (which can wipe out the\n // card).\n // See: https://github.com/bustle/mobiledoc-kit/issues/286\n postEditor.setRange(card.tailPosition());\n });\n return card;\n }\n\n /**\n * @param {integer} x x-position in viewport\n * @param {integer} y y-position in viewport\n * @return {Position|null}\n */\n }, {\n key: 'positionAtPoint',\n value: function positionAtPoint(x, y) {\n return _mobiledocKitUtilsCursorPosition['default'].atPoint(x, y, this);\n }\n\n /**\n * @private\n */\n }, {\n key: '_setCardMode',\n value: function _setCardMode(cardSection, mode) {\n var renderNode = cardSection.renderNode;\n if (renderNode && renderNode.isRendered) {\n var cardNode = renderNode.cardNode;\n cardNode[mode]();\n } else {\n cardSection.setInitialMode(mode);\n }\n }\n }, {\n key: 'triggerEvent',\n value: function triggerEvent(context, eventName, event) {\n this._eventManager._trigger(context, eventName, event);\n }\n }, {\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n if (this.isDestroyed) {\n // TODO warn that callback attempted after editor was destroyed\n return;\n }\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n\n /**\n * Runs each callback for the given hookName.\n * Only the hookName 'toggleMarkup' is currently supported\n * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled\n * @private\n */\n }, {\n key: '_runBeforeHooks',\n value: function _runBeforeHooks(hookName) {\n var hooks = this._beforeHooks[hookName] || [];\n\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n for (var i = 0; i < hooks.length; i++) {\n if (hooks[i].apply(hooks, args) === false) {\n return true;\n }\n }\n }\n }, {\n key: 'builder',\n get: function get() {\n if (!this._builder) {\n this._builder = new _mobiledocKitModelsPostNodeBuilder['default']();\n }\n return this._builder;\n }\n }, {\n key: 'keyCommands',\n get: function get() {\n if (!this._keyCommands) {\n this._keyCommands = [];\n }\n return this._keyCommands;\n }\n }, {\n key: 'cursor',\n get: function get() {\n return new _mobiledocKitUtilsCursor['default'](this);\n }\n\n /**\n * Return the current range for the editor (may be cached).\n * @return {Range}\n */\n }, {\n key: 'range',\n get: function get() {\n return this._editState.range;\n },\n set: function set(newRange) {\n this._editState.updateRange(newRange);\n\n if (this._editState.rangeDidChange()) {\n this._rangeDidChange();\n }\n\n if (this._editState.inputModeDidChange()) {\n this._inputModeDidChange();\n }\n }\n }, {\n key: 'activeSections',\n get: function get() {\n return this._editState.activeSections;\n }\n }, {\n key: 'activeSection',\n get: function get() {\n var activeSections = this.activeSections;\n\n return activeSections[activeSections.length - 1];\n }\n }, {\n key: 'activeSectionAttributes',\n get: function get() {\n return this._editState.activeSectionAttributes;\n }\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this._editState.activeMarkups;\n }\n }]);\n\n return Editor;\n })();\n\n exports['default'] = Editor;\n});","define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/parse-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/editor/text-input-handler', 'mobiledoc-kit/editor/selection-manager', 'mobiledoc-kit/utils/browser'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitUtilsParseUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitEditorTextInputHandler, _mobiledocKitEditorSelectionManager, _mobiledocKitUtilsBrowser) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var ELEMENT_EVENT_TYPES = ['keydown', 'keyup', 'cut', 'copy', 'paste', 'keypress', 'drop'];\n\n var EventManager = (function () {\n function EventManager(editor) {\n _classCallCheck(this, EventManager);\n\n this.editor = editor;\n this.logger = editor.loggerFor('event-manager');\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor);\n this._listeners = [];\n this.modifierKeys = {\n shift: false\n };\n\n this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this));\n this.started = true;\n }\n\n _createClass(EventManager, [{\n key: 'init',\n value: function init() {\n var _this = this;\n\n var element = this.editor.element;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot init EventManager without element', !!element);\n\n ELEMENT_EVENT_TYPES.forEach(function (type) {\n _this._addListener(element, type);\n });\n\n this._selectionManager.start();\n }\n }, {\n key: 'start',\n value: function start() {\n this.started = true;\n }\n }, {\n key: 'stop',\n value: function stop() {\n this.started = false;\n }\n }, {\n key: 'registerInputHandler',\n value: function registerInputHandler(inputHandler) {\n this._textInputHandler.register(inputHandler);\n }\n }, {\n key: 'unregisterInputHandler',\n value: function unregisterInputHandler(name) {\n this._textInputHandler.unregister(name);\n }\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._textInputHandler.destroy();\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](this.editor);\n }\n }, {\n key: '_addListener',\n value: function _addListener(context, type) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Missing listener for ' + type, !!this[type]);\n\n var listener = function listener(event) {\n return _this2._handleEvent(type, event);\n };\n context.addEventListener(type, listener);\n this._listeners.push([context, type, listener]);\n }\n }, {\n key: '_removeListeners',\n value: function _removeListeners() {\n this._listeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var context = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n context.removeEventListener(type, listener);\n });\n this._listeners = [];\n }\n\n // This is primarily useful for programmatically simulating events on the\n // editor from the tests.\n }, {\n key: '_trigger',\n value: function _trigger(context, type, event) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this._listeners, function (_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var _context = _ref32[0];\n var _type = _ref32[1];\n\n return _context === context && _type === type;\n }), function (_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var context = _ref42[0];\n var listener = _ref42[2];\n\n listener.call(context, event);\n });\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._textInputHandler.destroy();\n this._selectionManager.destroy();\n this._removeListeners();\n }\n }, {\n key: '_handleEvent',\n value: function _handleEvent(type, event) {\n var element = event.target;\n\n if (!this.started) {\n // abort handling this event\n return true;\n }\n\n if (!this.isElementAddressable(element)) {\n // abort handling this event\n return true;\n }\n\n this[type](event);\n }\n }, {\n key: 'isElementAddressable',\n value: function isElementAddressable(element) {\n return this.editor.cursor.isAddressable(element);\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange(selection /*, prevSelection */) {\n var shouldNotify = true;\n var anchorNode = selection.anchorNode;\n\n if (!this.isElementAddressable(anchorNode)) {\n if (!this.editor.range.isBlank) {\n // Selection changed from something addressable to something\n // not-addressable -- e.g., blur event, user clicked outside editor,\n // etc\n shouldNotify = true;\n } else {\n // selection changes wholly outside the editor should not trigger\n // change notifications\n shouldNotify = false;\n }\n }\n\n if (shouldNotify) {\n this.editor._readRangeFromDOM();\n }\n }\n }, {\n key: 'keypress',\n value: function keypress(event) {\n var editor = this.editor;\n var _textInputHandler = this._textInputHandler;\n\n if (!editor.hasCursor()) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n if (!key.isPrintable()) {\n return;\n } else {\n event.preventDefault();\n }\n\n _textInputHandler.handle(key.toString());\n }\n }, {\n key: 'keydown',\n value: function keydown(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n if (!editor.isEditable) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: true });\n\n if (editor.handleKeyCommand(event)) {\n return;\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var range = editor.range;\n\n switch (true) {\n // FIXME This should be restricted to only card/atom boundaries\n case key.isHorizontalArrowWithoutModifiersOtherThanShift():\n {\n var newRange = undefined;\n if (key.isShift()) {\n newRange = range.extend(key.direction * 1);\n } else {\n newRange = range.move(key.direction);\n }\n\n editor.selectRange(newRange);\n event.preventDefault();\n break;\n }\n case key.isDelete():\n {\n var direction = key.direction;\n\n var unit = 'char';\n if (key.altKey && _mobiledocKitUtilsBrowser['default'].isMac()) {\n unit = 'word';\n } else if (key.ctrlKey && !_mobiledocKitUtilsBrowser['default'].isMac()) {\n unit = 'word';\n }\n editor.performDelete({ direction: direction, unit: unit });\n event.preventDefault();\n break;\n }\n case key.isEnter():\n this._textInputHandler.handleNewLine();\n editor.handleNewline(event);\n break;\n case key.isTab():\n // Handle tab here because it does not fire a `keypress` event\n event.preventDefault();\n this._textInputHandler.handle(key.toString());\n break;\n }\n }\n }, {\n key: 'keyup',\n value: function keyup(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: false });\n }\n }, {\n key: 'cut',\n value: function cut(event) {\n event.preventDefault();\n\n this.copy(event);\n this.editor.performDelete();\n }\n }, {\n key: 'copy',\n value: function copy(event) {\n event.preventDefault();\n\n var editor = this.editor;\n var _editor = this.editor;\n var range = _editor.range;\n var post = _editor.post;\n\n post = post.trimTo(range);\n\n var data = {\n html: editor.serializePost(post, 'html'),\n text: editor.serializePost(post, 'text'),\n mobiledoc: editor.serializePost(post, 'mobiledoc')\n };\n\n (0, _mobiledocKitUtilsParseUtils.setClipboardData)(event, data, window);\n }\n }, {\n key: 'paste',\n value: function paste(event) {\n event.preventDefault();\n\n var editor = this.editor;\n\n var range = editor.range;\n\n if (!range.isCollapsed) {\n editor.performDelete();\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var position = editor.range.head;\n var targetFormat = this.modifierKeys.shift ? 'text' : 'html';\n var pastedPost = (0, _mobiledocKitUtilsParseUtils.parsePostFromPaste)(event, editor, { targetFormat: targetFormat });\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, pastedPost);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: 'drop',\n value: function drop(event) {\n event.preventDefault();\n\n var x = event.clientX;\n var y = event.clientY;\n var editor = this.editor;\n\n var position = editor.positionAtPoint(x, y);\n if (!position) {\n this.logger.log('Could not find drop position');\n return;\n }\n\n var post = (0, _mobiledocKitUtilsParseUtils.parsePostFromDrop)(event, editor, { logger: this.logger });\n if (!post) {\n this.logger.log('Could not determine post from drop event');\n return;\n }\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, post);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: '_updateModifiersFromKey',\n value: function _updateModifiersFromKey(key, _ref5) {\n var isDown = _ref5.isDown;\n\n if (key.isShiftKey()) {\n this.modifierKeys.shift = isDown;\n }\n }\n }]);\n\n return EventManager;\n })();\n\n exports['default'] = EventManager;\n});","define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/browser', 'mobiledoc-kit/editor/ui'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsBrowser, _mobiledocKitEditorUi) {\n 'use strict';\n\n exports.buildKeyCommand = buildKeyCommand;\n exports.validateKeyCommand = validateKeyCommand;\n exports.findKeyCommands = findKeyCommands;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function selectAll(editor) {\n var post = editor.post;\n\n editor.selectRange(post.toRange());\n }\n\n function gotoStartOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.headPosition());\n });\n }\n\n function gotoEndOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.tailPosition());\n });\n }\n\n function deleteToEndOfSection(editor) {\n var range = editor.range;\n\n if (range.isCollapsed) {\n var _range = range;\n var head = _range.head;\n var section = _range.head.section;\n\n range = head.toRange(section.tailPosition());\n }\n editor.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n var DEFAULT_KEY_COMMANDS = [{\n str: 'META+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'CTRL+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'META+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'CTRL+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'META+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+K',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return deleteToEndOfSection(editor);\n } else if (_mobiledocKitUtilsBrowser['default'].isWin()) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n }\n }, {\n str: 'CTRL+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoStartOfLine(editor);\n } else {\n selectAll(editor);\n }\n }\n }, {\n str: 'META+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n selectAll(editor);\n }\n }\n }, {\n str: 'CTRL+E',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoEndOfLine(editor);\n }\n }\n }, {\n str: 'META+K',\n run: function run(editor) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n\n }, {\n str: 'META+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.undoLastChange();\n });\n }\n }, {\n str: 'META+SHIFT+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.redoLastChange();\n });\n }\n }, {\n str: 'CTRL+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.undoLastChange();\n });\n }\n }, {\n str: 'CTRL+SHIFT+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.redoLastChange();\n });\n }\n }];\n\n exports.DEFAULT_KEY_COMMANDS = DEFAULT_KEY_COMMANDS;\n function modifierNamesToMask(modiferNames) {\n var defaultVal = 0;\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(modiferNames, function (sum, name) {\n var modifier = _mobiledocKitUtilsKey.MODIFIERS[name.toUpperCase()];\n (0, _mobiledocKitUtilsAssert['default'])('No modifier named \"' + name + '\" found', !!modifier);\n return sum + modifier;\n }, defaultVal);\n }\n\n function characterToCode(character) {\n var upperCharacter = character.toUpperCase();\n var special = (0, _mobiledocKitUtilsKey.specialCharacterToCode)(upperCharacter);\n if (special) {\n return special;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Only 1 character can be used in a key command str (got \"' + character + '\")', character.length === 1);\n return upperCharacter.charCodeAt(0);\n }\n }\n\n function buildKeyCommand(keyCommand) {\n var str = keyCommand.str;\n\n if (!str) {\n return keyCommand;\n }\n (0, _mobiledocKitUtilsAssert['default'])('[deprecation] Key commands no longer use the `modifier` property', !keyCommand.modifier);\n\n var _str$split$reverse = str.split('+').reverse();\n\n var _str$split$reverse2 = _toArray(_str$split$reverse);\n\n var character = _str$split$reverse2[0];\n\n var modifierNames = _str$split$reverse2.slice(1);\n\n keyCommand.modifierMask = modifierNamesToMask(modifierNames);\n keyCommand.code = characterToCode(character);\n\n return keyCommand;\n }\n\n function validateKeyCommand(keyCommand) {\n return !!keyCommand.code && !!keyCommand.run;\n }\n\n function findKeyCommands(keyCommands, keyEvent) {\n var key = _mobiledocKitUtilsKey['default'].fromEvent(keyEvent);\n\n return (0, _mobiledocKitUtilsArrayUtils.filter)(keyCommands, function (_ref) {\n var modifierMask = _ref.modifierMask;\n var code = _ref.code;\n\n return key.keyCode === code && key.modifierMask === modifierMask;\n });\n }\n});","define('mobiledoc-kit/editor/mutation-handler', ['exports', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsSet, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MUTATION = {\n NODES_CHANGED: 'childList',\n CHARACTER_DATA: 'characterData'\n };\n\n var MutationHandler = (function () {\n function MutationHandler(editor) {\n var _this = this;\n\n _classCallCheck(this, MutationHandler);\n\n this.editor = editor;\n this.logger = editor.loggerFor('mutation-handler');\n this.renderTree = null;\n this._isObserving = false;\n\n this._observer = new MutationObserver(function (mutations) {\n _this._handleMutations(mutations);\n });\n }\n\n _createClass(MutationHandler, [{\n key: 'init',\n value: function init() {\n this.startObserving();\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stopObserving();\n this._observer = null;\n }\n }, {\n key: 'suspendObservation',\n value: function suspendObservation(callback) {\n this.stopObserving();\n callback();\n this.startObserving();\n }\n }, {\n key: 'stopObserving',\n value: function stopObserving() {\n if (this._isObserving) {\n this._isObserving = false;\n this._observer.disconnect();\n }\n }\n }, {\n key: 'startObserving',\n value: function startObserving() {\n if (!this._isObserving) {\n var editor = this.editor;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot observe un-rendered editor', editor.hasRendered);\n\n this._isObserving = true;\n this.renderTree = editor._renderTree;\n\n this._observer.observe(editor.element, {\n characterData: true,\n childList: true,\n subtree: true\n });\n }\n }\n }, {\n key: 'reparsePost',\n value: function reparsePost() {\n this.editor._reparsePost();\n }\n }, {\n key: 'reparseSections',\n value: function reparseSections(sections) {\n this.editor._reparseSections(sections);\n }\n\n /**\n * for each mutation:\n * * find the target nodes:\n * * if nodes changed, target nodes are:\n * * added nodes\n * * the target from which removed nodes were removed\n * * if character data changed\n * * target node is the mutation event's target (text node)\n * * filter out nodes that are no longer attached (parentNode is null)\n * * for each remaining node:\n * * find its section, add to sections-to-reparse\n * * if no section, reparse all (and break)\n */\n }, {\n key: '_handleMutations',\n value: function _handleMutations(mutations) {\n var reparsePost = false;\n var sections = new _mobiledocKitUtilsSet['default']();\n\n for (var i = 0; i < mutations.length; i++) {\n if (reparsePost) {\n break;\n }\n\n var nodes = this._findTargetNodes(mutations[i]);\n\n for (var j = 0; j < nodes.length; j++) {\n var node = nodes[j];\n var renderNode = this._findRenderNodeFromNode(node);\n if (renderNode) {\n if (renderNode.reparsesMutationOfChildNode(node)) {\n var section = this._findSectionFromRenderNode(renderNode);\n if (section) {\n sections.add(section);\n } else {\n reparsePost = true;\n }\n }\n } else {\n reparsePost = true;\n break;\n }\n }\n }\n\n if (reparsePost) {\n this.logger.log('reparsePost (' + mutations.length + ' mutations)');\n this.reparsePost();\n } else if (sections.length) {\n this.logger.log('reparse ' + sections.length + ' sections (' + mutations.length + ' mutations)');\n this.reparseSections(sections.toArray());\n }\n }\n }, {\n key: '_findTargetNodes',\n value: function _findTargetNodes(mutation) {\n var nodes = [];\n\n switch (mutation.type) {\n case MUTATION.CHARACTER_DATA:\n nodes.push(mutation.target);\n break;\n case MUTATION.NODES_CHANGED:\n (0, _mobiledocKitUtilsArrayUtils.forEach)(mutation.addedNodes, function (n) {\n return nodes.push(n);\n });\n if (mutation.removedNodes.length) {\n nodes.push(mutation.target);\n }\n break;\n }\n\n var element = this.editor.element;\n var attachedNodes = (0, _mobiledocKitUtilsArrayUtils.filter)(nodes, function (node) {\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, node);\n });\n return attachedNodes;\n }\n }, {\n key: '_findSectionRenderNodeFromNode',\n value: function _findSectionRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node, function (rn) {\n return rn.postNode.isSection;\n });\n }\n }, {\n key: '_findRenderNodeFromNode',\n value: function _findRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node);\n }\n }, {\n key: '_findSectionFromRenderNode',\n value: function _findSectionFromRenderNode(renderNode) {\n var sectionRenderNode = this._findSectionRenderNodeFromNode(renderNode.element);\n return sectionRenderNode && sectionRenderNode.postNode;\n }\n }]);\n\n return MutationHandler;\n })();\n\n exports['default'] = MutationHandler;\n});","define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/editor/post/post-inserter', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/to-range'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils, _mobiledocKitEditorPostPostInserter, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsToRange) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n function isListSectionTagName(tagName) {\n return tagName === 'ul' || tagName === 'ol';\n }\n\n var CALLBACK_QUEUES = {\n BEFORE_COMPLETE: 'beforeComplete',\n COMPLETE: 'complete',\n AFTER_COMPLETE: 'afterComplete'\n };\n\n // There are only two events that we're concerned about for Undo, that is inserting text and deleting content.\n // These are the only two states that go on a \"run\" and create a combined undo, everything else has it's own\n // deadicated undo.\n var EDIT_ACTIONS = {\n INSERT_TEXT: 1,\n DELETE: 2\n };\n\n /**\n * The PostEditor is used to modify a post. It should not be instantiated directly.\n * Instead, a new instance of a PostEditor is created by the editor and passed\n * as the argument to the callback in {@link Editor#run}.\n *\n * Usage:\n * ```\n * editor.run((postEditor) => {\n * // postEditor is an instance of PostEditor that can operate on the\n * // editor's post\n * });\n * ```\n */\n\n var PostEditor = (function () {\n /**\n * @private\n */\n\n function PostEditor(editor) {\n var _this = this;\n\n _classCallCheck(this, PostEditor);\n\n this.editor = editor;\n this.builder = this.editor.builder;\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n this._didComplete = false;\n this.editActionTaken = null;\n\n this._renderRange = function () {\n return _this.editor.selectRange(_this._range);\n };\n this._postDidChange = function () {\n return _this.editor._postDidChange();\n };\n this._rerender = function () {\n return _this.editor.rerender();\n };\n }\n\n _createClass(PostEditor, [{\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n }, {\n key: 'begin',\n value: function begin() {\n // cache the editor's range\n this._range = this.editor.range;\n }\n\n /**\n * Schedules to select the given range on the editor after the postEditor\n * has completed its work. This also updates the postEditor's active range\n * (so that multiple calls to range-changing methods on the postEditor will\n * update the correct range).\n *\n * Usage:\n * let range = editor.range;\n * editor.run(postEditor => {\n * let nextPosition = postEditor.deleteRange(range);\n *\n * // Will position the editor's cursor at `nextPosition` after\n * // the postEditor finishes work and the editor rerenders.\n * postEditor.setRange(nextPosition);\n * });\n * @param {Range|Position} range\n * @public\n */\n }, {\n key: 'setRange',\n value: function setRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n // TODO validate that the range is valid\n // (does not contain marked-for-removal head or tail sections?)\n this._range = range;\n this.scheduleAfterRender(this._renderRange, true);\n }\n\n /**\n * Delete a range from the post\n *\n * Usage:\n * ```\n * let { range } = editor;\n * editor.run((postEditor) => {\n * let nextPosition = postEditor.deleteRange(range);\n * postEditor.setRange(nextPosition);\n * });\n * ```\n * @param {Range} range Cursor Range object with head and tail Positions\n * @return {Position} The position where the cursor would go after deletion\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass MobiledocKit Range to `deleteRange`\", range instanceof _mobiledocKitUtilsCursorRange['default']);\n\n this.editActionTaken = EDIT_ACTIONS.DELETE;\n\n var head = range.head;\n var headSection = range.head.section;\n var tail = range.tail;\n var tailSection = range.tail.section;\n var post = this.editor.post;\n\n if (headSection === tailSection) {\n return this.cutSection(headSection, head, tail);\n }\n\n var nextSection = headSection.nextLeafSection();\n\n var nextPos = this.cutSection(headSection, head, headSection.tailPosition());\n // cutSection can replace the section, so re-read headSection here\n headSection = nextPos.section;\n\n // Remove sections in the middle of the range\n while (nextSection !== tailSection) {\n var tmp = nextSection;\n nextSection = nextSection.nextLeafSection();\n this.removeSection(tmp);\n }\n\n var tailPos = this.cutSection(tailSection, tailSection.headPosition(), tail);\n // cutSection can replace the section, so re-read tailSection here\n tailSection = tailPos.section;\n\n if (tailSection.isBlank) {\n this.removeSection(tailSection);\n } else {\n // If head and tail sections are markerable, join them\n // Note: They may not be the same section type. E.g. this may join\n // a tail section that was a list item onto a markup section, or vice versa.\n // (This is the desired behavior.)\n if (headSection.isMarkerable && tailSection.isMarkerable) {\n headSection.join(tailSection);\n this._markDirty(headSection);\n this.removeSection(tailSection);\n } else if (headSection.isBlank) {\n this.removeSection(headSection);\n nextPos = tailPos;\n }\n }\n\n if (post.isBlank) {\n post.sections.append(this.builder.createMarkupSection('p'));\n nextPos = post.headPosition();\n }\n\n return nextPos;\n }\n\n /**\n * Note: This method may replace `section` with a different section.\n *\n * \"Cut\" out the part of the section inside `headOffset` and `tailOffset`.\n * If section is markerable this splits markers that straddle the head or tail (if necessary),\n * and removes markers that are wholly inside the offsets.\n * If section is a card, this may replace it with a blank markup section if the\n * positions contain the entire card.\n *\n * @param {Section} section\n * @param {Position} head\n * @param {Position} tail\n * @return {Position}\n * @private\n */\n }, {\n key: 'cutSection',\n value: function cutSection(section, head, tail) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass head position and tail position to `cutSection`', head instanceof _mobiledocKitUtilsCursorPosition['default'] && tail instanceof _mobiledocKitUtilsCursorPosition['default']);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass positions within same section to `cutSection`', head.section === tail.section);\n\n if (section.isBlank || head.isEqual(tail)) {\n return head;\n }\n if (section.isCardSection) {\n if (head.isHead() && tail.isTail()) {\n var newSection = this.builder.createMarkupSection();\n this.replaceSection(section, newSection);\n return newSection.headPosition();\n } else {\n return tail;\n }\n }\n\n var range = head.toRange(tail);\n this.splitMarkers(range).forEach(function (m) {\n return _this2.removeMarker(m);\n });\n\n return head;\n }\n }, {\n key: '_coalesceMarkers',\n value: function _coalesceMarkers(section) {\n if (section.isMarkerable) {\n this._removeBlankMarkers(section);\n this._joinSimilarMarkers(section);\n }\n }\n }, {\n key: '_removeBlankMarkers',\n value: function _removeBlankMarkers(section) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }), function (m) {\n return _this3.removeMarker(m);\n });\n }\n\n // joins markers that have identical markups\n }, {\n key: '_joinSimilarMarkers',\n value: function _joinSimilarMarkers(section) {\n var marker = section.markers.head;\n var nextMarker = undefined;\n while (marker && marker.next) {\n nextMarker = marker.next;\n\n if (marker.canJoin(nextMarker)) {\n nextMarker.value = marker.value + nextMarker.value;\n this._markDirty(nextMarker);\n this.removeMarker(marker);\n }\n\n marker = nextMarker;\n }\n }\n }, {\n key: 'removeMarker',\n value: function removeMarker(marker) {\n this._scheduleForRemoval(marker);\n if (marker.section) {\n this._markDirty(marker.section);\n marker.section.markers.remove(marker);\n }\n }\n }, {\n key: '_scheduleForRemoval',\n value: function _scheduleForRemoval(postNode) {\n var _this4 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.scheduleForRemoval();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n var removedAdjacentToList = postNode.prev && postNode.prev.isListSection || postNode.next && postNode.next.isListSection;\n if (removedAdjacentToList) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this4._joinContiguousListSections();\n });\n }\n }\n }, {\n key: '_joinContiguousListSections',\n value: function _joinContiguousListSections() {\n var _this5 = this;\n\n var post = this.editor.post;\n\n var range = this._range;\n var prev = undefined;\n var groups = [];\n var currentGroup = undefined;\n\n // FIXME do we need to force a re-render of the range if changed sections\n // are contained within the range?\n var updatedHead = null;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n if (prev && prev.isListSection && section.isListSection && prev.tagName === section.tagName) {\n\n currentGroup = currentGroup || [prev];\n currentGroup.push(section);\n } else {\n if (currentGroup) {\n groups.push(currentGroup);\n }\n currentGroup = null;\n }\n prev = section;\n });\n\n if (currentGroup) {\n groups.push(currentGroup);\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(groups, function (group) {\n var list = group[0];\n (0, _mobiledocKitUtilsArrayUtils.forEach)(group, function (listSection) {\n if (listSection === list) {\n return;\n }\n\n var currentHead = range.head;\n var prevPosition = undefined;\n\n // FIXME is there a currentHead if there is no range?\n // is the current head a list item in the section\n if (!range.isBlank && currentHead.section.isListItem && currentHead.section.parent === listSection) {\n prevPosition = list.tailPosition();\n }\n _this5._joinListSections(list, listSection);\n if (prevPosition) {\n updatedHead = prevPosition.move(FORWARD);\n }\n });\n });\n\n if (updatedHead) {\n this.setRange(updatedHead);\n }\n }\n }, {\n key: '_joinListSections',\n value: function _joinListSections(baseList, nextList) {\n baseList.join(nextList);\n this._markDirty(baseList);\n this.removeSection(nextList);\n }\n }, {\n key: '_markDirty',\n value: function _markDirty(postNode) {\n var _this6 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.markDirty();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n if (postNode.section) {\n this._markDirty(postNode.section);\n }\n if (postNode.isMarkerable) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this6._coalesceMarkers(postNode);\n });\n }\n }\n\n /**\n * @param {Position} position object with {section, offset} the marker and offset to delete from\n * @param {Number} direction The direction to delete in (default is BACKWARD)\n * @return {Position} for positioning the cursor\n * @public\n * @deprecated after v0.10.3\n */\n }, {\n key: 'deleteFrom',\n value: function deleteFrom(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n (0, _mobiledocKitUtilsDeprecate['default'])(\"`postEditor#deleteFrom is deprecated. Use `deleteAtPosition(position, direction=BACKWARD, {unit}={unit: 'char'})` instead\");\n return this.deleteAtPosition(position, direction, { unit: 'char' });\n }\n\n /**\n * Delete 1 `unit` (can be 'char' or 'word') in the given `direction` at the given\n * `position`. In almost all cases this will be equivalent to deleting the range formed\n * by expanding the position 1 unit in the given direction. The exception is when deleting\n * backward from the beginning of a list item, which reverts the list item into a markup section\n * instead of joining it with its previous list item (if any).\n *\n * Usage:\n *\n * let position = section.tailPosition();\n * // Section has text of \"Howdy!\"\n * editor.run((postEditor) => {\n * postEditor.deleteAtPosition(position);\n * });\n * // section has text of \"Howdy\"\n *\n * @param {Position} position The position to delete at\n * @param {Direction} [direction=DIRECTION.BACKWARD] direction The direction to delete in\n * @param {Object} [options]\n * @param {String} [options.unit=\"char\"] The unit of deletion (\"word\" or \"char\")\n * @return {Position}\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n var _ref = arguments.length <= 2 || arguments[2] === undefined ? { unit: 'char' } : arguments[2];\n\n var unit = _ref.unit;\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n return this._deleteAtPositionBackward(position, unit);\n } else {\n return this._deleteAtPositionForward(position, unit);\n }\n }\n }, {\n key: '_deleteAtPositionBackward',\n value: function _deleteAtPositionBackward(position, unit) {\n if (position.isHead() && position.section.isListItem) {\n this.toggleSection('p', position);\n return this._range.head;\n } else {\n var prevPosition = unit === 'word' ? position.moveWord(BACKWARD) : position.move(BACKWARD);\n var range = prevPosition.toRange(position);\n return this.deleteRange(range);\n }\n }\n }, {\n key: '_deleteAtPositionForward',\n value: function _deleteAtPositionForward(position, unit) {\n var nextPosition = unit === 'word' ? position.moveWord(FORWARD) : position.move(FORWARD);\n var range = position.toRange(nextPosition);\n return this.deleteRange(range);\n }\n\n /**\n * Split markers at two positions, once at the head, and if necessary once\n * at the tail.\n *\n * Usage:\n * ```\n * let range = editor.range;\n * editor.run((postEditor) => {\n * postEditor.splitMarkers(range);\n * });\n * ```\n * The return value will be marker object completely inside the offsets\n * provided. Markers outside of the split may also have been modified.\n *\n * @param {Range} markerRange\n * @return {Array} of markers that are inside the split\n * @private\n */\n }, {\n key: 'splitMarkers',\n value: function splitMarkers(range) {\n var post = this.editor.post;\n var head = range.head;\n var tail = range.tail;\n\n this.splitSectionMarkerAtOffset(head.section, head.offset);\n this.splitSectionMarkerAtOffset(tail.section, tail.offset);\n\n return post.markersContainedByRange(range);\n }\n }, {\n key: 'splitSectionMarkerAtOffset',\n value: function splitSectionMarkerAtOffset(section, offset) {\n var _this7 = this;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (m) {\n return _this7.removeMarker(m);\n });\n }\n\n /**\n * Split the section at the position.\n *\n * Usage:\n * ```\n * let position = editor.cursor.offsets.head;\n * editor.run((postEditor) => {\n * postEditor.splitSection(position);\n * });\n * // Will result in the creation of two new sections\n * // replacing the old one at the cursor position\n * ```\n * The return value will be the two new sections. One or both of these\n * sections can be blank (contain only a blank marker), for example if the\n * headMarkerOffset is 0.\n *\n * @param {Position} position\n * @return {Array} new sections, one for the first half and one for the second (either one can be null)\n * @public\n */\n }, {\n key: 'splitSection',\n value: function splitSection(position) {\n var _this8 = this;\n\n var section = position.section;\n\n if (section.isCardSection) {\n return this._splitCardSection(section, position);\n } else if (section.isListItem) {\n var isLastAndBlank = section.isBlank && !section.next;\n if (isLastAndBlank) {\n // if is last, replace the item with a blank markup section\n var _parent = section.parent;\n var collection = this.editor.post.sections;\n var blank = this.builder.createMarkupSection();\n this.removeSection(section);\n this.insertSectionBefore(collection, blank, _parent.next);\n\n return [null, blank];\n } else {\n var _splitListItem2 = this._splitListItem(section, position);\n\n var _splitListItem22 = _slicedToArray(_splitListItem2, 2);\n\n var pre = _splitListItem22[0];\n var post = _splitListItem22[1];\n\n return [pre, post];\n }\n } else {\n var splitSections = section.splitAtPosition(position);\n splitSections.forEach(function (s) {\n return _this8._coalesceMarkers(s);\n });\n this._replaceSection(section, splitSections);\n\n return splitSections;\n }\n }\n\n /**\n * @param {Section} cardSection\n * @param {Position} position to split at\n * @return {Section[]} 2-item array of pre and post-split sections\n * @private\n */\n }, {\n key: '_splitCardSection',\n value: function _splitCardSection(cardSection, position) {\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cards section must be split at offset 0 or 1', offset === 0 || offset === 1);\n\n var newSection = this.builder.createMarkupSection();\n var nextSection = undefined;\n var surroundingSections = undefined;\n\n if (offset === 0) {\n nextSection = cardSection;\n surroundingSections = [newSection, cardSection];\n } else {\n nextSection = cardSection.next;\n surroundingSections = [cardSection, newSection];\n }\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, newSection, nextSection);\n\n return surroundingSections;\n }\n\n /**\n * @param {Section} section\n * @param {Section} newSection\n * @return null\n * @public\n */\n }, {\n key: 'replaceSection',\n value: function replaceSection(section, newSection) {\n if (!section) {\n // FIXME should a falsy section be a valid argument?\n this.insertSectionBefore(this.editor.post.sections, newSection, null);\n } else {\n this._replaceSection(section, [newSection]);\n }\n }\n }, {\n key: 'moveSectionBefore',\n value: function moveSectionBefore(collection, renderedSection, beforeSection) {\n var newSection = renderedSection.clone();\n this.removeSection(renderedSection);\n this.insertSectionBefore(collection, newSection, beforeSection);\n return newSection;\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionUp',\n value: function moveSectionUp(renderedSection) {\n var isFirst = !renderedSection.prev;\n if (isFirst) {\n return renderedSection;\n }\n\n var collection = renderedSection.parent.sections;\n var beforeSection = renderedSection.prev;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionDown',\n value: function moveSectionDown(renderedSection) {\n var isLast = !renderedSection.next;\n if (isLast) {\n return renderedSection;\n }\n\n var beforeSection = renderedSection.next.next;\n var collection = renderedSection.parent.sections;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * Insert an array of markers at the given position. If the position is in\n * a non-markerable section (like a card section), this method throws an error.\n *\n * @param {Position} position\n * @param {Marker[]} markers\n * @return {Position} The position that represents the end of the inserted markers.\n * @public\n */\n }, {\n key: 'insertMarkers',\n value: function insertMarkers(position, markers) {\n var _this9 = this;\n\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert markers at non-markerable position', section.isMarkerable);\n\n this.editActionTaken = EDIT_ACTIONS.INSERT_TEXT;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (marker) {\n return _this9._scheduleForRemoval(marker);\n });\n\n var prevMarker = section.markerBeforeOffset(offset);\n markers.forEach(function (marker) {\n section.markers.insertAfter(marker, prevMarker);\n offset += marker.length;\n prevMarker = marker;\n });\n\n this._coalesceMarkers(section);\n this._markDirty(section);\n\n var nextPosition = section.toPosition(offset);\n this.setRange(nextPosition);\n return nextPosition;\n }\n\n /**\n * Inserts text with the given markups, ignoring the existing markups at\n * the position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @param {Markup[]} markups\n * @return {Position} position at the end of the inserted text\n */\n }, {\n key: 'insertTextWithMarkup',\n value: function insertTextWithMarkup(position, text) {\n var markups = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var marker = this.builder.createMarker(text, markups);\n return this.insertMarkers(position, [marker]);\n }\n\n /**\n * Insert the text at the given position\n * Inherits the markups already at that position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @return {Position} position at the end of the inserted text.\n */\n }, {\n key: 'insertText',\n value: function insertText(position, text) {\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var markups = position.marker && position.marker.markups;\n markups = markups || [];\n return this.insertTextWithMarkup(position, text, markups);\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this10 = this;\n\n var nextSection = section.next;\n var collection = section.parent.sections;\n\n var nextNewSection = newSections[0];\n if (nextNewSection.isMarkupSection && section.isListItem) {\n // put the new section after the ListSection (section.parent)\n // instead of after the ListItem\n collection = section.parent.parent.sections;\n nextSection = section.parent.next;\n }\n\n newSections.forEach(function (s) {\n return _this10.insertSectionBefore(collection, s, nextSection);\n });\n this.removeSection(section);\n }\n\n /**\n * Given a markerRange (for example `editor.range`) mark all markers\n * inside it as a given markup. The markup must be provided as a post\n * abstract node.\n *\n * Usage:\n *\n * let range = editor.range;\n * let strongMarkup = editor.builder.createMarkup('strong');\n * editor.run((postEditor) => {\n * postEditor.addMarkupToRange(range, strongMarkup);\n * });\n * // Will result some markers possibly being split, and the markup\n * // being applied to all markers between the split.\n *\n * @param {Range} range\n * @param {Markup} markup A markup post abstract node\n * @public\n */\n }, {\n key: 'addMarkupToRange',\n value: function addMarkupToRange(range, markup) {\n var _this11 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n var markers = this.splitMarkers(range);\n if (markers.length) {\n (function () {\n // We insert the new markup at a consistent index across the range.\n // If we just push on the end of the list, it can end up in different positions\n // of the markup stack. This results in unnecessary closing and re-opening of\n // the markup each time it changes position.\n // If we just push it at the beginning of the list, this causes unnecessary closing\n // and re-opening of surrounding tags.\n // So, we look for any tags open across the whole range, and push into the stack\n // at the end of those.\n // Prompted by https://github.com/bustle/mobiledoc-kit/issues/360\n\n var markupsOpenAcrossRange = (0, _mobiledocKitUtilsArrayUtils.reduce)(markers, function (soFar, marker) {\n return (0, _mobiledocKitUtilsArrayUtils.commonItems)(soFar, marker.markups);\n }, markers[0].markups);\n var indexToInsert = markupsOpenAcrossRange.length;\n\n markers.forEach(function (marker) {\n marker.addMarkupAtIndex(markup, indexToInsert);\n _this11._markDirty(marker);\n });\n })();\n }\n }\n\n /**\n * Given a markerRange (for example `editor.range`) remove the given\n * markup from all contained markers.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let markup = markerRange.headMarker.markups[0];\n * editor.run(postEditor => {\n * postEditor.removeMarkupFromRange(range, markup);\n * });\n * // Will result in some markers possibly being split, and the markup\n * // being removed from all markers between the split.\n * ```\n * @param {Range} range Object with offsets\n * @param {Markup|Function} markupOrCallback A markup post abstract node or\n * a function that returns true when passed a markup that should be removed\n * @private\n */\n }, {\n key: 'removeMarkupFromRange',\n value: function removeMarkupFromRange(range, markupOrMarkupCallback) {\n var _this12 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n this.splitMarkers(range).forEach(function (marker) {\n marker.removeMarkup(markupOrMarkupCallback);\n _this12._markDirty(marker);\n });\n }\n\n /**\n * Toggle the given markup in the given range (or at the position given). If the range/position\n * has the markup, the markup will be removed. If nothing in the range/position\n * has the markup, the markup will be added to everything in the range/position.\n *\n * Usage:\n * ```\n * // Remove any 'strong' markup if it exists in the selection, otherwise\n * // make it all 'strong'\n * editor.run(postEditor => postEditor.toggleMarkup('strong'));\n *\n * // add/remove a link to 'bustle.com' to the selection\n * editor.run(postEditor => {\n * const linkMarkup = postEditor.builder.createMarkup('a', {href: 'http://bustle.com'});\n * postEditor.toggleMarkup(linkMarkup);\n * });\n * ```\n * @param {Markup|String} markupOrString Either a markup object created using\n * the builder (useful when adding a markup with attributes, like an 'a' markup),\n * or, if a string, the tag name of the markup (e.g. 'strong', 'em') to toggle.\n * @param {Range|Position} range in which to toggle. Defaults to current editor range.\n * @public\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markupOrMarkupString) {\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n var markup = typeof markupOrMarkupString === 'string' ? this.builder.createMarkup(markupOrMarkupString) : markupOrMarkupString;\n\n var hasMarkup = this.editor.detectMarkupInRange(range, markup.tagName);\n // FIXME: This implies only a single markup in a range. This may not be\n // true for links (which are not the same object instance like multiple\n // strong tags would be).\n if (hasMarkup) {\n this.removeMarkupFromRange(range, hasMarkup);\n } else {\n this.addMarkupToRange(range, markup);\n }\n\n this.setRange(range);\n }\n\n /**\n * Toggles the tagName of the active section or sections in the given range/position.\n * If every section has the tag name, they will all be reset to default sections.\n * Otherwise, every section will be changed to the requested type\n *\n * @param {String} sectionTagName A valid markup section or\n * list section tag name (e.g. 'blockquote', 'h2', 'ul')\n * @param {Range|Position} range The range over which to toggle.\n * Defaults to the current editor range.\n * @public\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(sectionTagName) {\n var _this13 = this;\n\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName);\n var post = this.editor.post;\n\n var everySectionHasTagName = true;\n post.walkMarkerableSections(range, function (section) {\n if (!_this13._isSameSectionType(section, sectionTagName)) {\n everySectionHasTagName = false;\n }\n });\n\n var tagName = everySectionHasTagName ? 'p' : sectionTagName;\n var sectionTransformations = [];\n post.walkMarkerableSections(range, function (section) {\n var changedSection = _this13.changeSectionTagName(section, tagName);\n sectionTransformations.push({\n from: section,\n to: changedSection\n });\n });\n\n var nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations);\n this.setRange(nextRange);\n }\n }, {\n key: '_determineNextRangeAfterToggleSection',\n value: function _determineNextRangeAfterToggleSection(range, sectionTransformations) {\n if (sectionTransformations.length) {\n var changedHeadSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref2) {\n var from = _ref2.from;\n\n return from === range.headSection;\n }).to;\n var changedTailSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref3) {\n var from = _ref3.from;\n\n return from === range.tailSection;\n }).to;\n\n if (changedHeadSection.isListSection || changedTailSection.isListSection) {\n // We don't know to which ListItem's the original sections point at, so\n // we don't have enough information to reconstruct the range when\n // dealing with lists.\n return sectionTransformations[0].to.headPosition().toRange();\n } else {\n return _mobiledocKitUtilsCursorRange['default'].create(changedHeadSection, range.headSectionOffset, changedTailSection, range.tailSectionOffset, range.direction);\n }\n } else {\n return range;\n }\n }\n }, {\n key: 'setAttribute',\n value: function setAttribute(key, value) {\n var range = arguments.length <= 2 || arguments[2] === undefined ? this._range : arguments[2];\n\n this._mutateAttribute(key, range, function (section, attribute) {\n if (section.getAttribute(attribute) !== value) {\n section.setAttribute(attribute, value);\n return true;\n }\n });\n }\n }, {\n key: 'removeAttribute',\n value: function removeAttribute(key) {\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n this._mutateAttribute(key, range, function (section, attribute) {\n if (section.hasAttribute(attribute)) {\n section.removeAttribute(attribute);\n return true;\n }\n });\n }\n }, {\n key: '_mutateAttribute',\n value: function _mutateAttribute(key, range, cb) {\n var _this14 = this;\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n var post = this.editor.post;\n\n var attribute = 'data-md-' + key;\n\n post.walkMarkerableSections(range, function (section) {\n if (section.isListItem) {\n section = section.parent;\n }\n\n if (cb(section, attribute) === true) {\n _this14._markDirty(section);\n }\n });\n\n this.setRange(range);\n }\n }, {\n key: '_isSameSectionType',\n value: function _isSameSectionType(section, sectionTagName) {\n return section.isListItem ? section.parent.tagName === sectionTagName : section.tagName === sectionTagName;\n }\n\n /**\n * @param {Markerable} section\n * @private\n */\n }, {\n key: 'changeSectionTagName',\n value: function changeSectionTagName(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot pass non-markerable section to `changeSectionTagName`', section.isMarkerable);\n\n if (isListSectionTagName(newTagName)) {\n return this._changeSectionToListItem(section, newTagName);\n } else if (section.isListItem) {\n return this._changeSectionFromListItem(section, newTagName);\n } else {\n section.tagName = newTagName;\n this._markDirty(section);\n return section;\n }\n }\n\n /**\n * Splits the item at the position given.\n * If the position is at the start or end of the item, the pre- or post-item\n * will contain a single empty (\"\") marker.\n * @param {ListItem} item\n * @param {Position} position\n * @return {Array} the pre-item and post-item on either side of the split\n * @private\n */\n }, {\n key: '_splitListItem',\n value: function _splitListItem(item, position) {\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list item at position that does not include item', item === section);\n\n item.splitMarkerAtOffset(offset);\n var prevMarker = item.markerBeforeOffset(offset);\n var preItem = this.builder.createListItem(),\n postItem = this.builder.createListItem();\n\n var currentItem = preItem;\n item.markers.forEach(function (marker) {\n currentItem.markers.append(marker.clone());\n if (marker === prevMarker) {\n currentItem = postItem;\n }\n });\n this._replaceSection(item, [preItem, postItem]);\n return [preItem, postItem];\n }\n\n /**\n * Splits the list at the position given.\n * @return {Array} pre-split list and post-split list, either of which could\n * be blank (0-item list) if the position is at the start or end of the list.\n *\n * Note: Contiguous list sections will be joined in the before_complete queue\n * of the postEditor.\n *\n * @private\n */\n }, {\n key: '_splitListAtPosition',\n value: function _splitListAtPosition(list, position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at position not in list', position.section.parent === list);\n\n var positionIsMiddle = !position.isHead() && !position.isTail();\n if (positionIsMiddle) {\n var item = position.section;\n\n var _splitListItem3 = this._splitListItem(item, position);\n\n var _splitListItem32 = _slicedToArray(_splitListItem3, 1);\n\n var pre = _splitListItem32[0];\n\n position = pre.tailPosition();\n }\n\n var preList = this.builder.createListSection(list.tagName);\n var postList = this.builder.createListSection(list.tagName);\n\n var preItem = position.section;\n var currentList = preList;\n list.items.forEach(function (item) {\n // If this item matches the start item and the position is at its start,\n // it should be appended to the postList instead of the preList\n if (item === preItem && position.isEqual(item.headPosition())) {\n currentList = postList;\n }\n currentList.items.append(item.clone());\n // If we just appended the preItem, append the remaining items to the postList\n if (item === preItem) {\n currentList = postList;\n }\n });\n\n this._replaceSection(list, [preList, postList]);\n return [preList, postList];\n }\n\n /**\n * @return Array of [prev, mid, next] lists. `prev` and `next` can\n * be blank, depending on the position of `item`. `mid` will always\n * be a 1-item list containing `item`. `prev` and `next` will be\n * removed in the before_complete queue if they are blank\n * (and still attached).\n *\n * @private\n */\n }, {\n key: '_splitListAtItem',\n value: function _splitListAtItem(list, item) {\n var _this15 = this;\n\n var next = list;\n var prev = this.builder.createListSection(next.tagName, [], next.attributes);\n var mid = this.builder.createListSection(next.tagName);\n\n var addToPrev = true;\n // must turn the LinkedList into an array so that we can remove items\n // as we iterate through it\n var items = next.items.toArray();\n items.forEach(function (i) {\n var listToAppend = undefined;\n if (i === item) {\n addToPrev = false;\n listToAppend = mid;\n } else if (addToPrev) {\n listToAppend = prev;\n } else {\n return; // break after iterating prev and mid parts of the list\n }\n listToAppend.join(i);\n _this15.removeSection(i);\n });\n var found = !addToPrev;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found);\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, mid, next);\n this.insertSectionBefore(collection, prev, mid);\n\n // Remove possibly blank prev/next lists\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n [prev, next].forEach(function (_list) {\n var isAttached = !!_list.parent;\n if (_list.isBlank && isAttached) {\n _this15.removeSection(_list);\n }\n });\n });\n\n return [prev, mid, next];\n }\n }, {\n key: '_changeSectionFromListItem',\n value: function _changeSectionFromListItem(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass list item to `_changeSectionFromListItem`', section.isListItem);\n\n var listSection = section.parent;\n var markupSection = this.builder.createMarkupSection(newTagName);\n markupSection.join(section);\n\n var _splitListAtItem2 = this._splitListAtItem(listSection, section);\n\n var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 2);\n\n var mid = _splitListAtItem22[1];\n\n this.replaceSection(mid, markupSection);\n return markupSection;\n }\n }, {\n key: '_changeSectionToListItem',\n value: function _changeSectionToListItem(section, newTagName) {\n var isAlreadyCorrectListItem = section.isListItem && section.parent.tagName === newTagName;\n\n if (isAlreadyCorrectListItem) {\n return section;\n }\n\n var listSection = this.builder.createListSection(newTagName);\n listSection.join(section);\n\n var sectionToReplace = undefined;\n if (section.isListItem) {\n var _splitListAtItem3 = this._splitListAtItem(section.parent, section);\n\n var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 2);\n\n var mid = _splitListAtItem32[1];\n\n sectionToReplace = mid;\n } else {\n sectionToReplace = section;\n }\n this.replaceSection(sectionToReplace, listSection);\n return listSection;\n }\n\n /**\n * Insert a given section before another one, updating the post abstract\n * and the rendered UI.\n *\n * Usage:\n * ```\n * let markerRange = editor.range;\n * let sectionWithCursor = markerRange.headMarker.section;\n * let section = editor.builder.createCardSection('my-image');\n * let collection = sectionWithCursor.parent.sections;\n * editor.run((postEditor) => {\n * postEditor.insertSectionBefore(collection, section, sectionWithCursor);\n * });\n * ```\n * @param {LinkedList} collection The list of sections to insert into\n * @param {Object} section The new section\n * @param {Object} beforeSection Optional The section \"before\" is relative to,\n * if falsy the new section will be appended to the collection\n * @public\n */\n }, {\n key: 'insertSectionBefore',\n value: function insertSectionBefore(collection, section, beforeSection) {\n collection.insertBefore(section, beforeSection);\n this._markDirty(section.parent);\n }\n\n /**\n * Insert the given section after the current active section, or, if no\n * section is active, at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSection',\n value: function insertSection(section) {\n var activeSection = this.editor.activeSection;\n var nextSection = activeSection && activeSection.next;\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, section, nextSection);\n }\n\n /**\n * Insert the given section at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSectionAtEnd',\n value: function insertSectionAtEnd(section) {\n this.insertSectionBefore(this.editor.post.sections, section, null);\n }\n\n /**\n * Insert the `post` at the given position in the editor's post.\n * @param {Position} position\n * @param {Post} post\n * @private\n */\n }, {\n key: 'insertPost',\n value: function insertPost(position, newPost) {\n var post = this.editor.post;\n var inserter = new _mobiledocKitEditorPostPostInserter['default'](this, post);\n var nextPosition = inserter.insert(position, newPost);\n return nextPosition;\n }\n\n /**\n * Remove a given section from the post abstract and the rendered UI.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let sectionWithCursor = range.head.section;\n * editor.run((postEditor) => {\n * postEditor.removeSection(sectionWithCursor);\n * });\n * ```\n * @param {Object} section The section to remove\n * @public\n */\n }, {\n key: 'removeSection',\n value: function removeSection(section) {\n var parent = section.parent;\n this._scheduleForRemoval(section);\n parent.sections.remove(section);\n\n if (parent.isListSection) {\n this._scheduleListRemovalIfEmpty(parent);\n }\n }\n }, {\n key: 'removeAllSections',\n value: function removeAllSections() {\n var _this16 = this;\n\n this.editor.post.sections.toArray().forEach(function (section) {\n _this16.removeSection(section);\n });\n }\n }, {\n key: 'migrateSectionsFromPost',\n value: function migrateSectionsFromPost(post) {\n var _this17 = this;\n\n post.sections.toArray().forEach(function (section) {\n post.sections.remove(section);\n _this17.insertSectionBefore(_this17.editor.post.sections, section, null);\n });\n }\n }, {\n key: '_scheduleListRemovalIfEmpty',\n value: function _scheduleListRemovalIfEmpty(listSection) {\n var _this18 = this;\n\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n // if the list is attached and blank after we do other rendering stuff,\n // remove it\n var isAttached = !!listSection.parent;\n if (isAttached && listSection.isBlank) {\n _this18.removeSection(listSection);\n }\n });\n }\n\n /**\n * A method for adding work the deferred queue\n *\n * @param {Function} callback to run during completion\n * @param {Boolean} [once=false] Whether to only schedule the callback once.\n * @public\n */\n }, {\n key: 'schedule',\n value: function schedule(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Work can only be scheduled before a post edit has completed', !this._didComplete);\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.COMPLETE, callback);\n }\n }\n\n /**\n * A method for adding work the deferred queue. The callback will only\n * be added to the queue once, even if `scheduleOnce` is called multiple times.\n * The function cannot be an anonymous function.\n *\n * @param {Function} callback to run during completion\n * @public\n */\n }, {\n key: 'scheduleOnce',\n value: function scheduleOnce(callback) {\n this.schedule(callback, true);\n }\n\n /**\n * Add a rerender job to the queue\n *\n * @public\n */\n }, {\n key: 'scheduleRerender',\n value: function scheduleRerender() {\n this.scheduleOnce(this._rerender);\n }\n\n /**\n * Schedule a notification that the post has been changed.\n * The notification will result in the editor firing its `postDidChange`\n * hook after the postEditor completes its work (at the end of {@link Editor#run}).\n *\n * @public\n */\n }, {\n key: 'scheduleDidUpdate',\n value: function scheduleDidUpdate() {\n this.scheduleOnce(this._postDidChange);\n }\n }, {\n key: 'scheduleAfterRender',\n value: function scheduleAfterRender(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n }\n }\n\n /**\n * Flush any work on the queue. {@link Editor#run} calls this method; it\n * should not be called directly.\n *\n * @private\n */\n }, {\n key: 'complete',\n value: function complete() {\n (0, _mobiledocKitUtilsAssert['default'])('Post editing can only be completed once', !this._didComplete);\n\n this.runCallbacks(CALLBACK_QUEUES.BEFORE_COMPLETE);\n this._didComplete = true;\n this.runCallbacks(CALLBACK_QUEUES.COMPLETE);\n this.runCallbacks(CALLBACK_QUEUES.AFTER_COMPLETE);\n }\n }, {\n key: 'undoLastChange',\n value: function undoLastChange() {\n this.editor._editHistory.stepBackward(this);\n }\n }, {\n key: 'redoLastChange',\n value: function redoLastChange() {\n this.editor._editHistory.stepForward(this);\n }\n }, {\n key: 'cancelSnapshot',\n value: function cancelSnapshot() {\n this._shouldCancelSnapshot = true;\n }\n }]);\n\n return PostEditor;\n })();\n\n exports['default'] = PostEditor;\n});","define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MARKERABLE = 'markerable',\n NESTED_MARKERABLE = 'nested_markerable',\n NON_MARKERABLE = 'non_markerable';\n\n var Visitor = (function () {\n function Visitor(inserter, cursorPosition) {\n _classCallCheck(this, Visitor);\n\n var postEditor = inserter.postEditor;\n var post = inserter.post;\n\n this.postEditor = postEditor;\n this._post = post;\n this.cursorPosition = cursorPosition;\n this.builder = this.postEditor.builder;\n\n this._hasInsertedFirstLeafSection = false;\n }\n\n _createClass(Visitor, [{\n key: 'visit',\n value: function visit(node) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit node of type ' + node.type, !!this[method]);\n this[method](node);\n }\n }, {\n key: '_canMergeSection',\n value: function _canMergeSection(section) {\n if (this._hasInsertedFirstLeafSection) {\n return false;\n } else {\n return this._isMarkerable && section.isMarkerable;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(node) {\n var _this = this;\n\n if (this.cursorSection.isBlank && !this._isNested) {\n // replace blank section with entire post\n var newSections = node.sections.map(function (s) {\n return s.clone();\n });\n this._replaceSection(this.cursorSection, newSections);\n } else {\n node.sections.forEach(function (section) {\n return _this.visit(section);\n });\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(node) {\n this[MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(node) {\n var _this2 = this;\n\n var hasNext = !!node.next;\n node.items.forEach(function (item) {\n return _this2.visit(item);\n });\n\n if (this._isNested && hasNext) {\n this._breakNestedAtCursor();\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(node) {\n this[NESTED_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: NON_MARKERABLE,\n value: function value(section) {\n if (this._isNested) {\n this._breakNestedAtCursor();\n } else if (!this.cursorSection.isBlank) {\n this._breakAtCursor();\n }\n\n this._insertLeafSection(section);\n }\n }, {\n key: MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n } else if (this._isNested && this._isMarkerable) {\n // If we are attaching a markerable section to a list item,\n // insert a linebreak then merge the section onto the resulting blank list item\n this._breakAtCursor();\n\n // Advance the cursor to the head of the blank list item\n var nextPosition = this.cursorSection.next.headPosition();\n this.cursorPosition = nextPosition;\n\n // Merge this section onto the list item\n this._mergeSection(section);\n } else {\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n }\n }, {\n key: NESTED_MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n return;\n }\n\n section = this._isNested ? section : this._wrapNestedSection(section);\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n\n // break out of a nested cursor position\n }, {\n key: '_breakNestedAtCursor',\n value: function _breakNestedAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call _breakNestedAtCursor if not nested', this._isNested);\n\n var parent = this.cursorSection.parent;\n var cursorAtEndOfList = this.cursorPosition.isEqual(parent.tailPosition());\n\n if (cursorAtEndOfList) {\n var blank = this.builder.createMarkupSection();\n this._insertSectionAfter(blank, parent);\n } else {\n var _breakListAtCursor2 = this._breakListAtCursor();\n\n var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 2);\n\n var blank = _breakListAtCursor22[1];\n\n this.cursorPosition = blank.tailPosition();\n }\n }\n }, {\n key: '_breakListAtCursor',\n value: function _breakListAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _splitParentSection if cursor position is not nested', this._isNested);\n\n var list = this.cursorSection.parent,\n position = this.cursorPosition,\n blank = this.builder.createMarkupSection();\n\n var _postEditor$_splitListAtPosition = this.postEditor._splitListAtPosition(list, position);\n\n var _postEditor$_splitListAtPosition2 = _slicedToArray(_postEditor$_splitListAtPosition, 2);\n\n var pre = _postEditor$_splitListAtPosition2[0];\n var post = _postEditor$_splitListAtPosition2[1];\n\n var collection = this._post.sections,\n reference = post;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n return [pre, blank, post];\n }\n }, {\n key: '_wrapNestedSection',\n value: function _wrapNestedSection(section) {\n var tagName = section.parent.tagName;\n var parent = this.builder.createListSection(tagName);\n parent.items.append(section.clone());\n return parent;\n }\n }, {\n key: '_mergeSection',\n value: function _mergeSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only merge markerable sections', this._isMarkerable && section.isMarkerable);\n this._hasInsertedFirstLeafSection = true;\n\n var markers = section.markers.map(function (m) {\n return m.clone();\n });\n var position = this.postEditor.insertMarkers(this.cursorPosition, markers);\n\n this.cursorPosition = position;\n }\n\n // Can be called to add a line break when in a nested section or a parent\n // section.\n }, {\n key: '_breakAtCursor',\n value: function _breakAtCursor() {\n if (this.cursorSection.isBlank) {\n return;\n } else if (this._isMarkerable) {\n this._breakMarkerableAtCursor();\n } else {\n this._breakNonMarkerableAtCursor();\n }\n }\n\n // Inserts a blank section before/after the cursor,\n // depending on cursor position.\n }, {\n key: '_breakNonMarkerableAtCursor',\n value: function _breakNonMarkerableAtCursor() {\n var collection = this._post.sections,\n blank = this.builder.createMarkupSection(),\n reference = this.cursorPosition.isHead() ? this.cursorSection : this.cursorSection.next;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n this.cursorPosition = blank.tailPosition();\n }\n }, {\n key: '_breakMarkerableAtCursor',\n value: function _breakMarkerableAtCursor() {\n var _postEditor$splitSection = this.postEditor.splitSection(this.cursorPosition);\n\n var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 1);\n\n var pre = _postEditor$splitSection2[0];\n\n this.cursorPosition = pre.tailPosition();\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot replace section that does not have parent.sections', section.parent && section.parent.sections);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass enumerable to _replaceSection', !!newSections.forEach);\n\n var collection = section.parent.sections;\n var reference = section.next;\n this.postEditor.removeSection(section);\n newSections.forEach(function (section) {\n _this3.postEditor.insertSectionBefore(collection, section, reference);\n });\n var lastSection = newSections[newSections.length - 1];\n\n this.cursorPosition = lastSection.tailPosition();\n }\n }, {\n key: '_insertSectionBefore',\n value: function _insertSectionBefore(section, reference) {\n var collection = this.cursorSection.parent.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n\n this.cursorPosition = section.tailPosition();\n }\n\n // Insert a section after the parent section.\n // E.g., add a markup section after a list section\n }, {\n key: '_insertSectionAfter',\n value: function _insertSectionAfter(section, parent) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _insertSectionAfter nested section', !parent.isNested);\n var reference = parent.next;\n var collection = this._post.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n this.cursorPosition = section.tailPosition();\n }\n }, {\n key: '_insertLeafSection',\n value: function _insertLeafSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only _insertLeafSection when cursor is at end of section', this.cursorPosition.isTail());\n\n this._hasInsertedFirstLeafSection = true;\n section = section.clone();\n\n if (this.cursorSection.isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert leaf non-markerable section when cursor is nested', !(section.isMarkerable && this._isNested));\n this._replaceSection(this.cursorSection, [section]);\n } else if (this.cursorSection.next && this.cursorSection.next.isBlank) {\n this._replaceSection(this.cursorSection.next, [section]);\n } else {\n var reference = this.cursorSection.next;\n this._insertSectionBefore(section, reference);\n }\n }\n }, {\n key: 'cursorPosition',\n get: function get() {\n return this._cursorPosition;\n },\n set: function set(position) {\n this._cursorPosition = position;\n this.postEditor.setRange(position);\n }\n }, {\n key: '_isMarkerable',\n get: function get() {\n return this.cursorSection.isMarkerable;\n }\n }, {\n key: 'cursorSection',\n get: function get() {\n return this.cursorPosition.section;\n }\n }, {\n key: 'cursorOffset',\n get: function get() {\n return this.cursorPosition.offset;\n }\n }, {\n key: '_isNested',\n get: function get() {\n return this.cursorSection.isNested;\n }\n }]);\n\n return Visitor;\n })();\n\n var Inserter = (function () {\n function Inserter(postEditor, post) {\n _classCallCheck(this, Inserter);\n\n this.postEditor = postEditor;\n this.post = post;\n }\n\n _createClass(Inserter, [{\n key: 'insert',\n value: function insert(cursorPosition, newPost) {\n var visitor = new Visitor(this, cursorPosition);\n if (!newPost.isBlank) {\n visitor.visit(newPost);\n }\n return visitor.cursorPosition;\n }\n }]);\n\n return Inserter;\n })();\n\n exports['default'] = Inserter;\n});","define(\"mobiledoc-kit/editor/selection-change-observer\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var instance = undefined;\n\n var SelectionChangeObserver = (function () {\n function SelectionChangeObserver() {\n _classCallCheck(this, SelectionChangeObserver);\n\n this.started = false;\n this.listeners = [];\n this.selection = {};\n }\n\n _createClass(SelectionChangeObserver, [{\n key: \"addListener\",\n value: function addListener(listener) {\n if (this.listeners.indexOf(listener) === -1) {\n this.listeners.push(listener);\n this.start();\n }\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n var index = this.listeners.indexOf(listener);\n if (index !== -1) {\n this.listeners.splice(index, 1);\n if (this.listeners.length === 0) {\n this.stop();\n }\n }\n }\n }, {\n key: \"start\",\n value: function start() {\n if (this.started) {\n return;\n }\n this.started = true;\n\n this.poll();\n }\n }, {\n key: \"stop\",\n value: function stop() {\n this.started = false;\n this.selection = {};\n }\n }, {\n key: \"notifyListeners\",\n value: function notifyListeners() /* newSelection, prevSelection */{\n var _arguments = arguments;\n\n this.listeners.forEach(function (listener) {\n listener.selectionDidChange.apply(listener, _arguments);\n });\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.stop();\n this.listeners = [];\n }\n }, {\n key: \"getSelection\",\n value: function getSelection() {\n var selection = window.getSelection();\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n return { anchorNode: anchorNode, focusNode: focusNode, anchorOffset: anchorOffset, focusOffset: focusOffset };\n }\n }, {\n key: \"poll\",\n value: function poll() {\n var _this = this;\n\n if (this.started) {\n this.update();\n this.runNext(function () {\n return _this.poll();\n });\n }\n }\n }, {\n key: \"runNext\",\n value: function runNext(fn) {\n window.requestAnimationFrame(fn);\n }\n }, {\n key: \"update\",\n value: function update() {\n var prevSelection = this.selection;\n var curSelection = this.getSelection();\n if (!this.selectionIsEqual(prevSelection, curSelection)) {\n this.selection = curSelection;\n this.notifyListeners(curSelection, prevSelection);\n }\n }\n }, {\n key: \"selectionIsEqual\",\n value: function selectionIsEqual(s1, s2) {\n return s1.anchorNode === s2.anchorNode && s1.anchorOffset === s2.anchorOffset && s1.focusNode === s2.focusNode && s1.focusOffset === s2.focusOffset;\n }\n }], [{\n key: \"getInstance\",\n value: function getInstance() {\n if (!instance) {\n instance = new SelectionChangeObserver();\n }\n return instance;\n }\n }, {\n key: \"addListener\",\n value: function addListener(listener) {\n SelectionChangeObserver.getInstance().addListener(listener);\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n SelectionChangeObserver.getInstance().removeListener(listener);\n }\n }]);\n\n return SelectionChangeObserver;\n })();\n\n exports[\"default\"] = SelectionChangeObserver;\n});","define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/editor/selection-change-observer'], function (exports, _mobiledocKitEditorSelectionChangeObserver) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SelectionManager = (function () {\n function SelectionManager(editor, callback) {\n _classCallCheck(this, SelectionManager);\n\n this.editor = editor;\n this.callback = callback;\n this.started = false;\n }\n\n _createClass(SelectionManager, [{\n key: 'start',\n value: function start() {\n if (this.started) {\n return;\n }\n\n _mobiledocKitEditorSelectionChangeObserver['default'].addListener(this);\n this.started = true;\n }\n }, {\n key: 'stop',\n value: function stop() {\n this.started = false;\n _mobiledocKitEditorSelectionChangeObserver['default'].removeListener(this);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stop();\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange() {\n if (this.started) {\n this.callback.apply(this, arguments);\n }\n }\n }]);\n\n return SelectionManager;\n })();\n\n exports['default'] = SelectionManager;\n});","define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsCharacters) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var TextInputHandler = (function () {\n function TextInputHandler(editor) {\n _classCallCheck(this, TextInputHandler);\n\n this.editor = editor;\n this._handlers = [];\n }\n\n _createClass(TextInputHandler, [{\n key: 'register',\n value: function register(handler) {\n (0, _mobiledocKitUtilsAssert['default'])('Input Handler is not valid', this._validateHandler(handler));\n this._handlers.push(handler);\n }\n }, {\n key: 'unregister',\n value: function unregister(name) {\n var handlers = this._handlers;\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i].name === name) {\n handlers.splice(i, 1);\n }\n }\n }\n }, {\n key: 'handle',\n value: function handle(string) {\n var editor = this.editor;\n\n editor.insertText(string);\n\n var matchedHandler = this._findHandler();\n if (matchedHandler) {\n var _matchedHandler = _slicedToArray(matchedHandler, 2);\n\n var handler = _matchedHandler[0];\n var matches = _matchedHandler[1];\n\n handler.run(editor, matches);\n }\n }\n }, {\n key: 'handleNewLine',\n value: function handleNewLine() {\n var editor = this.editor;\n\n var matchedHandler = this._findHandler(_mobiledocKitUtilsCharacters.ENTER);\n if (matchedHandler) {\n var _matchedHandler2 = _slicedToArray(matchedHandler, 2);\n\n var handler = _matchedHandler2[0];\n var matches = _matchedHandler2[1];\n\n handler.run(editor, matches);\n }\n }\n }, {\n key: '_findHandler',\n value: function _findHandler() {\n var string = arguments.length <= 0 || arguments[0] === undefined ? \"\" : arguments[0];\n var _editor$range = this.editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n var preText = section.textUntil(head) + string;\n\n for (var i = 0; i < this._handlers.length; i++) {\n var handler = this._handlers[i];\n var text = handler.text;\n var match = handler.match;\n\n if (text && (0, _mobiledocKitUtilsStringUtils.endsWith)(preText, text)) {\n return [handler, [text]];\n } else if (match && match.test(preText)) {\n return [handler, match.exec(preText)];\n }\n }\n }\n }, {\n key: '_validateHandler',\n value: function _validateHandler(handler) {\n (0, _mobiledocKitUtilsDeprecate['default'])('Registered input handlers require a \"name\" property so that they can be unregistered', !!handler.name);\n return !!handler.run && ( // has `run`\n !!handler.text || !!handler.match) && // and `text` or `match`\n !(!!handler.text && !!handler.match); // not both `text` and `match`\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._handlers = [];\n }\n }]);\n\n return TextInputHandler;\n })();\n\n exports['default'] = TextInputHandler;\n});","define('mobiledoc-kit/editor/text-input-handlers', ['exports'], function (exports) {\n /**\n * Convert section at the editor's cursor position into a list.\n * Does nothing if the cursor position is not at the start of the section,\n * or if the section is already a list item.\n *\n * @param {Editor} editor\n * @param {String} listTagName (\"ul\" or \"ol\")\n * @public\n */\n 'use strict';\n\n exports.replaceWithListSection = replaceWithListSection;\n exports.replaceWithHeaderSection = replaceWithHeaderSection;\n\n function replaceWithListSection(editor, listTagName) {\n var _editor$range = editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n if (section.isListItem) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var item = builder.createListItem();\n var listSection = builder.createListSection(listTagName, [item]);\n\n postEditor.replaceSection(section, listSection);\n postEditor.setRange(listSection.headPosition());\n });\n }\n\n /**\n * Convert section at the editor's cursor position into a header section.\n * Does nothing if the cursor position is not at the start of the section.\n *\n * @param {Editor} editor\n * @param {String} headingTagName ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')\n * @public\n */\n\n function replaceWithHeaderSection(editor, headingTagName) {\n var _editor$range2 = editor.range;\n var head = _editor$range2.head;\n var section = _editor$range2.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var newSection = builder.createMarkupSection(headingTagName);\n postEditor.replaceSection(section, newSection);\n postEditor.setRange(newSection.headPosition());\n });\n }\n\n var DEFAULT_TEXT_INPUT_HANDLERS = [{\n name: 'ul',\n // \"* \" -> ul\n match: /^\\* $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ul');\n }\n }, {\n name: 'ol',\n // \"1\" -> ol, \"1.\" -> ol\n match: /^1\\.? $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ol');\n }\n }, {\n name: 'heading',\n /*\n * \"# \" -> h1\n * \"## \" -> h2\n * \"### \" -> h3\n * \"#### \" -> h4\n * \"##### \" -> h5\n * \"###### \" -> h6\n */\n match: /^(#{1,6}) $/,\n run: function run(editor, matches) {\n var capture = matches[1];\n var headingTag = 'h' + capture.length;\n replaceWithHeaderSection(editor, headingTag);\n }\n }];\n exports.DEFAULT_TEXT_INPUT_HANDLERS = DEFAULT_TEXT_INPUT_HANDLERS;\n});","define('mobiledoc-kit/editor/ui', ['exports'], function (exports) {\n /**\n * @module UI\n */\n\n /**\n * @callback promptCallback\n * @param {String} url The URL to pass back to the editor for linking\n * to the selected text.\n */\n\n /**\n * @callback showPrompt\n * @param {String} message The text of the prompt.\n * @param {String} defaultValue The initial URL to display in the prompt.\n * @param {module:UI~promptCallback} callback Once your handler has accepted a URL,\n * it should pass it to `callback` so that the editor may link the\n * selected text.\n */\n\n /**\n * Exposes the core behavior for linking and unlinking text, and allows for\n * customization of the URL input handler.\n * @param {Editor} editor An editor instance to operate on. If a range is selected,\n * either prompt for a URL and add a link or un-link the\n * currently linked text.\n * @param {module:UI~showPrompt} [showPrompt] An optional custom input handler. Defaults\n * to using `window.prompt`.\n * @example\n * let myPrompt = (message, defaultURL, promptCallback) => {\n * let url = window.prompt(\"Overriding the defaults\", \"http://placekitten.com\");\n * promptCallback(url);\n * };\n *\n * editor.registerKeyCommand({\n * str: \"META+K\",\n * run(editor) {\n * toggleLink(editor, myPrompt);\n * }\n * });\n * @public\n */\n\n 'use strict';\n\n exports.toggleLink = toggleLink;\n var defaultShowPrompt = function defaultShowPrompt(message, defaultValue, callback) {\n return callback(window.prompt(message, defaultValue));\n };\n\n function toggleLink(editor) {\n var showPrompt = arguments.length <= 1 || arguments[1] === undefined ? defaultShowPrompt : arguments[1];\n\n if (editor.range.isCollapsed) {\n return;\n }\n\n var selectedText = editor.cursor.selectedText();\n var defaultUrl = '';\n if (selectedText.indexOf('http') !== -1) {\n defaultUrl = selectedText;\n }\n\n var range = editor.range;\n\n var hasLink = editor.detectMarkupInRange(range, 'a');\n\n if (hasLink) {\n editor.toggleMarkup('a');\n } else {\n showPrompt('Enter a URL', defaultUrl, function (url) {\n if (!url) {\n return;\n }\n\n editor.toggleMarkup('a', { href: url });\n });\n }\n }\n});","define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version', 'mobiledoc-kit/renderers/mobiledoc'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion, _mobiledocKitRenderersMobiledoc) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n var Mobiledoc = {\n Editor: _mobiledocKitEditorEditor['default'],\n UI: _mobiledocKitEditorUi,\n ImageCard: _mobiledocKitCardsImage['default'],\n Range: _mobiledocKitUtilsCursorRange['default'],\n Position: _mobiledocKitUtilsCursorPosition['default'],\n Error: _mobiledocKitUtilsMobiledocError['default'],\n VERSION: _mobiledocKitVersion['default'],\n MOBILEDOC_VERSION: _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION\n };\n\n function registerGlobal(global) {\n global.Mobiledoc = Mobiledoc;\n }\n\n exports.Editor = _mobiledocKitEditorEditor['default'];\n exports.UI = _mobiledocKitEditorUi;\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports.MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n exports['default'] = Mobiledoc;\n});","define('mobiledoc-kit/models/_attributable', ['exports', 'mobiledoc-kit/utils/object-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsObjectUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n exports.attributable = attributable;\n var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n /*\n * A \"mixin\" to add section attribute support\n * to markup and list sections.\n */\n\n function attributable(ctx) {\n ctx.attributes = {};\n\n ctx.hasAttribute = function (key) {\n return key in ctx.attributes;\n };\n\n ctx.setAttribute = function (key, value) {\n if (!(0, _mobiledocKitUtilsArrayUtils.contains)(VALID_ATTRIBUTES, key)) {\n throw new Error('Invalid attribute \"' + key + '\" was passed. Constrain attributes to the spec-compliant whitelist.');\n }\n ctx.attributes[key] = value;\n };\n ctx.removeAttribute = function (key) {\n delete ctx.attributes[key];\n };\n ctx.getAttribute = function (key) {\n return ctx.attributes[key];\n };\n ctx.eachAttribute = function (cb) {\n (0, _mobiledocKitUtilsObjectUtils.entries)(ctx.attributes).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var k = _ref2[0];\n var v = _ref2[1];\n return cb(k, v);\n });\n };\n }\n});","define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Markerable = (function (_Section) {\n _inherits(Markerable, _Section);\n\n function Markerable(type, tagName) {\n var _this = this;\n\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n _classCallCheck(this, Markerable);\n\n _get(Object.getPrototypeOf(Markerable.prototype), 'constructor', this).call(this, type);\n this.isMarkerable = true;\n this.tagName = tagName;\n this.markers = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(m) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only insert markers and atoms into markerable (was: ' + m.type + ')', m.isMarker || m.isAtom);\n m.section = m.parent = _this;\n },\n freeItem: function freeItem(m) {\n return m.section = m.parent = null;\n }\n });\n\n markers.forEach(function (m) {\n return _this.markers.append(m);\n });\n }\n\n _createClass(Markerable, [{\n key: 'canJoin',\n value: function canJoin(other) {\n return other.isMarkerable && other.type === this.type && other.tagName === this.tagName;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newMarkers = this.markers.map(function (m) {\n return m.clone();\n });\n return this.builder.createMarkerableSection(this.type, this.tagName, newMarkers);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get textUntil for a position not in this section', position.section === this);\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n var text = '';\n var currentMarker = this.markers.head;\n while (currentMarker) {\n if (currentMarker === marker) {\n text += currentMarker.textUntil(offsetInMarker);\n break;\n } else {\n text += currentMarker.text;\n currentMarker = currentMarker.next;\n }\n }\n return text;\n }\n\n /**\n * @param {Marker}\n * @param {Number} markerOffset The offset relative to the start of the marker\n *\n * @return {Number} The offset relative to the start of this section\n */\n }, {\n key: 'offsetOfMarker',\n value: function offsetOfMarker(marker) {\n var markerOffset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get offsetOfMarker for marker that is not child of this', marker.section === this);\n\n // FIXME it is possible, when we get a cursor position before having finished reparsing,\n // for markerOffset to be > marker.length. We shouldn't rely on this functionality.\n\n var offset = 0;\n var currentMarker = this.markers.head;\n while (currentMarker && currentMarker !== marker.next) {\n var _length = currentMarker === marker ? markerOffset : currentMarker.length;\n offset += _length;\n currentMarker = currentMarker.next;\n }\n\n return offset;\n }\n\n // puts clones of this.markers into beforeSection and afterSection,\n // all markers before the marker/offset split go in beforeSection, and all\n // after the marker/offset split go in afterSection\n // @return {Array} [beforeSection, afterSection], two new sections\n }, {\n key: '_redistributeMarkers',\n value: function _redistributeMarkers(beforeSection, afterSection, marker) {\n var offset = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3];\n\n var currentSection = beforeSection;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.markers, function (m) {\n if (m === marker) {\n var _marker$split = marker.split(offset);\n\n var _marker$split2 = _toArray(_marker$split);\n\n var beforeMarker = _marker$split2[0];\n\n var afterMarkers = _marker$split2.slice(1);\n\n beforeSection.markers.append(beforeMarker);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(afterMarkers, function (_m) {\n return afterSection.markers.append(_m);\n });\n currentSection = afterSection;\n } else {\n currentSection.markers.append(m.clone());\n }\n });\n\n return [beforeSection, afterSection];\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker() /*marker, offset=0*/{\n (0, _mobiledocKitUtilsAssert['default'])('splitAtMarker must be implemented by sub-class', false);\n }\n\n /**\n * Split this section's marker (if any) at the given offset, so that\n * there is now a marker boundary at that offset (useful for later applying\n * a markup to a range)\n * @param {Number} sectionOffset The offset relative to start of this section\n * @return {EditObject} An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank.\n * After calling `splitMarkerAtOffset(offset)`, there will always be a valid\n * result returned from `markerBeforeOffset(offset)`.\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset(sectionOffset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot splitMarkerAtOffset when offset is > length', sectionOffset <= this.length);\n var markerOffset = undefined;\n var len = 0;\n var currentMarker = this.markers.head;\n var edit = { added: [], removed: [] };\n\n if (!currentMarker) {\n var blankMarker = this.builder.createMarker();\n this.markers.prepend(blankMarker);\n edit.added.push(blankMarker);\n } else {\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n // nothing to do, there is a gap at the requested offset\n break;\n } else if (len > sectionOffset) {\n var _edit$added;\n\n markerOffset = currentMarker.length - (len - sectionOffset);\n var newMarkers = currentMarker.splitAtOffset(markerOffset);\n (_edit$added = edit.added).push.apply(_edit$added, _toConsumableArray(newMarkers));\n edit.removed.push(currentMarker);\n this.markers.splice(currentMarker, 1, newMarkers);\n break;\n } else {\n currentMarker = currentMarker.next;\n }\n }\n }\n\n return edit;\n }\n }, {\n key: 'splitAtPosition',\n value: function splitAtPosition(position) {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n return this.splitAtMarker(marker, offsetInMarker);\n }\n\n // returns the marker just before this offset.\n // It is an error to call this method with an offset that is in the middle\n // of a marker.\n }, {\n key: 'markerBeforeOffset',\n value: function markerBeforeOffset(sectionOffset) {\n var len = 0;\n var currentMarker = this.markers.head;\n\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n return currentMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('markerBeforeOffset called with sectionOffset not between markers', len < sectionOffset);\n currentMarker = currentMarker.next;\n }\n }\n }\n }, {\n key: 'markerPositionAtOffset',\n value: function markerPositionAtOffset(offset) {\n var currentOffset = 0;\n var currentMarker = undefined;\n var remaining = offset;\n this.markers.detect(function (marker) {\n currentOffset = Math.min(remaining, marker.length);\n remaining -= currentOffset;\n if (remaining === 0) {\n currentMarker = marker;\n return true; // break out of detect\n }\n });\n\n return { marker: currentMarker, offset: currentOffset };\n }\n }, {\n key: 'markersFor',\n\n /**\n * @return {Array} New markers that match the boundaries of the\n * range. Does not change the existing markers in this section.\n */\n value: function markersFor(headOffset, tailOffset) {\n var range = { head: { section: this, offset: headOffset },\n tail: { section: this, offset: tailOffset } };\n\n var markers = [];\n this._markersInRange(range, function (marker, _ref) {\n var markerHead = _ref.markerHead;\n var markerTail = _ref.markerTail;\n var isContained = _ref.isContained;\n\n var cloned = marker.clone();\n if (!isContained) {\n // cannot do marker.value.slice if the marker is an atom -- this breaks the atom's \"atomic\" value\n // If a marker is an atom `isContained` should always be true so\n // we shouldn't hit this code path. FIXME add tests\n cloned.value = marker.value.slice(markerHead, markerTail);\n }\n markers.push(cloned);\n });\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n this._markersInRange(range, function (marker) {\n marker.markups.forEach(function (m) {\n return markups.add(m);\n });\n });\n return markups.toArray();\n }\n\n // calls the callback with (marker, {markerHead, markerTail, isContained})\n // for each marker that is wholly or partially contained in the range.\n }, {\n key: '_markersInRange',\n value: function _markersInRange(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call #_markersInRange if range expands beyond this section', head.section === this && tail.section === this);\n var headOffset = head.offset;var tailOffset = tail.offset;\n\n var currentHead = 0,\n currentTail = 0,\n currentMarker = this.markers.head;\n\n while (currentMarker) {\n currentTail += currentMarker.length;\n\n if (currentTail > headOffset && currentHead < tailOffset) {\n var markerHead = Math.max(headOffset - currentHead, 0);\n var markerTail = currentMarker.length - Math.max(currentTail - tailOffset, 0);\n var isContained = markerHead === 0 && markerTail === currentMarker.length;\n\n callback(currentMarker, { markerHead: markerHead, markerTail: markerTail, isContained: isContained });\n }\n\n currentHead += currentMarker.length;\n currentMarker = currentMarker.next;\n\n if (currentHead > tailOffset) {\n break;\n }\n }\n }\n\n // mutates this by appending the other section's (cloned) markers to it\n }, {\n key: 'join',\n value: function join(otherSection) {\n var _this2 = this;\n\n var beforeMarker = this.markers.tail;\n var afterMarker = null;\n\n otherSection.markers.forEach(function (m) {\n if (!m.isBlank) {\n m = m.clone();\n _this2.markers.append(m);\n if (!afterMarker) {\n afterMarker = m;\n }\n }\n });\n\n return { beforeMarker: beforeMarker, afterMarker: afterMarker };\n }\n }, {\n key: 'isBlank',\n get: function get() {\n if (!this.markers.length) {\n return true;\n }\n return this.markers.every(function (m) {\n return m.isBlank;\n });\n }\n }, {\n key: 'text',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.value;\n }, '');\n }\n }, {\n key: 'length',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.length;\n }, 0);\n }\n }]);\n\n return Markerable;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Markerable;\n});","define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/cursor/position'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCursorPosition) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function unimplementedMethod(methodName, me) {\n (0, _mobiledocKitUtilsAssert['default'])('`' + methodName + '()` must be implemented by ' + me.constructor.name, false);\n }\n\n var Section = (function (_LinkedItem) {\n _inherits(Section, _LinkedItem);\n\n function Section(type) {\n _classCallCheck(this, Section);\n\n _get(Object.getPrototypeOf(Section.prototype), 'constructor', this).call(this);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create section without type', !!type);\n this.type = type;\n this.isSection = true;\n this.isMarkerable = false;\n this.isNested = false;\n this.isSection = true;\n this.isLeafSection = true;\n }\n\n _createClass(Section, [{\n key: 'isValidTagName',\n value: function isValidTagName() /* normalizedTagName */{\n unimplementedMethod('isValidTagName', this);\n }\n }, {\n key: 'clone',\n value: function clone() {\n unimplementedMethod('clone', this);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* otherSection */{\n unimplementedMethod('canJoin', this);\n }\n\n /**\n * @return {Position} The position at the start of this section\n * @public\n */\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.toPosition(0);\n }\n\n /**\n * @return {Position} The position at the end of this section\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.toPosition(this.length);\n }\n\n /**\n * @param {Number} offset\n * @return {Position} The position in this section at the given offset\n * @public\n */\n }, {\n key: 'toPosition',\n value: function toPosition(offset) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass number to `toPosition`\", typeof offset === 'number');\n (0, _mobiledocKitUtilsAssert['default'])(\"Cannot call `toPosition` with offset > length\", offset <= this.length);\n\n return new _mobiledocKitUtilsCursorPosition['default'](this, offset);\n }\n\n /**\n * @return {Range} A range from this section's head to tail positions\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'join',\n value: function join() {\n unimplementedMethod('join', this);\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* position */{\n return '';\n }\n\n /**\n * Markerable sections should override this method\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset() {\n var blankEdit = { added: [], removed: [] };\n return blankEdit;\n }\n }, {\n key: 'nextLeafSection',\n value: function nextLeafSection() {\n var next = this.next;\n if (next) {\n if (next.items) {\n return next.items.head;\n } else {\n return next;\n }\n } else {\n if (this.isNested) {\n return this.parent.nextLeafSection();\n }\n }\n }\n }, {\n key: 'immediatelyNextMarkerableSection',\n value: function immediatelyNextMarkerableSection() {\n var next = this.nextLeafSection();\n while (next && !next.isMarkerable) {\n next = next.nextLeafSection();\n }\n return next;\n }\n }, {\n key: 'previousLeafSection',\n value: function previousLeafSection() {\n var prev = this.prev;\n\n if (prev) {\n if (prev.items) {\n return prev.items.tail;\n } else {\n return prev;\n }\n } else {\n if (this.isNested) {\n return this.parent.previousLeafSection();\n }\n }\n }\n }, {\n key: 'tagName',\n set: function set(val) {\n var normalizedTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(val);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot set section tagName to ' + val, this.isValidTagName(normalizedTagName));\n this._tagName = normalizedTagName;\n },\n get: function get() {\n return this._tagName;\n }\n }, {\n key: 'length',\n get: function get() {\n return 0;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n unimplementedMethod('isBlank', this);\n }\n }]);\n\n return Section;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = Section;\n});","define('mobiledoc-kit/models/atom-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var AtomNode = (function () {\n function AtomNode(editor, atom, model, element, atomOptions) {\n _classCallCheck(this, AtomNode);\n\n this.editor = editor;\n this.atom = atom;\n this.model = model;\n this.atomOptions = atomOptions;\n this.element = element;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(AtomNode, [{\n key: 'render',\n value: function render() {\n if (!this._rendered) {\n var options = this.atomOptions;\n var env = this.env;\n var _model = this.model;\n var value = _model.value;\n var payload = _model.payload;\n\n // cache initial render\n this._rendered = this.atom.render({ options: options, env: env, value: value, payload: payload });\n }\n\n this._validateAndAppendRenderResult(this._rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.atom.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + name + '\" must return a DOM node (returned value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n }\n }, {\n key: 'env',\n get: function get() {\n var _this = this;\n\n return {\n name: this.atom.name,\n onTeardown: function onTeardown(callback) {\n return _this._teardownCallback = callback;\n },\n save: function save(value) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _this.model.value = value;\n _this.model.payload = payload;\n\n _this.editor._postDidChange();\n _this.teardown();\n _this.render();\n }\n };\n }\n }]);\n\n return AtomNode;\n })();\n\n exports['default'] = AtomNode;\n});","define('mobiledoc-kit/models/atom', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var ATOM_LENGTH = 1;\n\n var Atom = (function (_LinkedItem) {\n _inherits(Atom, _LinkedItem);\n\n function Atom(name, value, payload) {\n var _this = this;\n\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n _classCallCheck(this, Atom);\n\n _get(Object.getPrototypeOf(Atom.prototype), 'constructor', this).call(this);\n this.name = name;\n this.value = value;\n this.text = ''; // An atom never has text, but it does have a value\n (0, _mobiledocKitUtilsAssert['default'])('Atom must have value', value !== undefined && value !== null);\n this.payload = payload;\n this.type = _mobiledocKitModelsTypes.ATOM_TYPE;\n this.isMarker = false;\n this.isAtom = true;\n\n this.markups = [];\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Atom, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createAtom(this.name, this.value, this.payload, clonedMarkups);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* other */{\n return false;\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* offset */{\n return '';\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? offset : arguments[1];\n return (function () {\n var markers = [];\n\n if (endOffset === 0) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n markers.push(this.clone());\n\n if (offset === ATOM_LENGTH) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n return markers;\n }).apply(this, arguments);\n }\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n\n var builder = this.builder;\n\n var clone = this.clone();\n var blankMarker = builder.createMarker('');\n var pre = undefined,\n post = undefined;\n\n if (offset === 0) {\n pre = blankMarker;\n post = clone;\n } else if (offset === ATOM_LENGTH) {\n pre = clone;\n post = blankMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Invalid offset given to Atom#splitAtOffset: \"' + offset + '\"', false);\n }\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n return [pre, post];\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return ATOM_LENGTH;\n }\n }]);\n\n return Atom;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Atom, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Atom;\n});","define('mobiledoc-kit/models/card-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CardNode = (function () {\n function CardNode(editor, card, section, element, options) {\n _classCallCheck(this, CardNode);\n\n this.editor = editor;\n this.card = card;\n this.section = section;\n this.element = element;\n this.options = options;\n\n this.mode = null;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(CardNode, [{\n key: 'render',\n value: function render(mode) {\n if (this.mode === mode) {\n return;\n }\n\n this.teardown();\n\n this.mode = mode;\n\n var method = mode === 'display' ? 'render' : 'edit';\n method = this.card[method];\n\n (0, _mobiledocKitUtilsAssert['default'])('Card is missing \"' + method + '\" (tried to render mode: \"' + mode + '\")', !!method);\n var rendered = method({\n env: this.env,\n options: this.options,\n payload: this.section.payload\n });\n\n this._validateAndAppendRenderResult(rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: 'didRender',\n value: function didRender() {\n if (this._didRenderCallback) {\n this._didRenderCallback();\n }\n }\n }, {\n key: 'display',\n value: function display() {\n this.render('display');\n }\n }, {\n key: 'edit',\n value: function edit() {\n this.render('edit');\n }\n }, {\n key: 'remove',\n value: function remove() {\n var _this = this;\n\n this.editor.run(function (postEditor) {\n return postEditor.removeSection(_this.section);\n });\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.card.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + name + '\" must render dom (render value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n this._rendered = rendered;\n this.didRender();\n }\n }, {\n key: 'env',\n get: function get() {\n var _this2 = this;\n\n return {\n name: this.card.name,\n isInEditor: true,\n onTeardown: function onTeardown(callback) {\n return _this2._teardownCallback = callback;\n },\n didRender: function didRender(callback) {\n return _this2._didRenderCallback = callback;\n },\n edit: function edit() {\n return _this2.edit();\n },\n save: function save(payload) {\n var transition = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\n _this2.section.payload = payload;\n\n _this2.editor._postDidChange();\n if (transition) {\n _this2.display();\n }\n },\n cancel: function cancel() {\n return _this2.display();\n },\n remove: function remove() {\n return _this2.remove();\n },\n postModel: this.section\n };\n }\n }]);\n\n return CardNode;\n })();\n\n exports['default'] = CardNode;\n});","define('mobiledoc-kit/models/card', ['exports', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/copy'], function (exports, _mobiledocKitModels_section, _mobiledocKitModelsTypes, _mobiledocKitUtilsCopy) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var CARD_MODES = {\n DISPLAY: 'display',\n EDIT: 'edit'\n };\n\n exports.CARD_MODES = CARD_MODES;\n var CARD_LENGTH = 1;\n\n var DEFAULT_INITIAL_MODE = CARD_MODES.DISPLAY;\n\n var Card = (function (_Section) {\n _inherits(Card, _Section);\n\n function Card(name, payload) {\n _classCallCheck(this, Card);\n\n _get(Object.getPrototypeOf(Card.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.CARD_TYPE);\n this.name = name;\n this.payload = payload;\n this.setInitialMode(DEFAULT_INITIAL_MODE);\n this.isCardSection = true;\n }\n\n _createClass(Card, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var payload = (0, _mobiledocKitUtilsCopy.shallowCopyObject)(this.payload);\n var card = this.builder.createCardSection(this.name, payload);\n // If this card is currently rendered, clone the mode it is\n // currently in as the default mode of the new card.\n var mode = this._initialMode;\n if (this.renderNode && this.renderNode.cardNode) {\n mode = this.renderNode.cardNode.mode;\n }\n card.setInitialMode(mode);\n return card;\n }\n\n /**\n * set the mode that this will be rendered into initially\n * @private\n */\n }, {\n key: 'setInitialMode',\n value: function setInitialMode(initialMode) {\n // TODO validate initialMode\n this._initialMode = initialMode;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return CARD_LENGTH;\n }\n }]);\n\n return Card;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Card;\n});","define('mobiledoc-kit/models/image', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Image = (function (_Section) {\n _inherits(Image, _Section);\n\n function Image() {\n _classCallCheck(this, Image);\n\n _get(Object.getPrototypeOf(Image.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE);\n this.src = null;\n }\n\n _createClass(Image, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return 1;\n }\n }]);\n\n return Image;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Image;\n});","define('mobiledoc-kit/models/lifecycle-callbacks', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LifecycleCallbacks = (function () {\n function LifecycleCallbacks() {\n var _this = this;\n\n var queueNames = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, LifecycleCallbacks);\n\n this.callbackQueues = {};\n this.removalQueues = {};\n\n queueNames.forEach(function (name) {\n _this.callbackQueues[name] = [];\n _this.removalQueues[name] = [];\n });\n }\n\n _createClass(LifecycleCallbacks, [{\n key: 'runCallbacks',\n value: function runCallbacks(queueName) {\n var args = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var queue = this._getQueue(queueName);\n queue.forEach(function (cb) {\n return cb.apply(undefined, _toConsumableArray(args));\n });\n\n var toRemove = this.removalQueues[queueName];\n toRemove.forEach(function (cb) {\n var index = queue.indexOf(cb);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n });\n\n this.removalQueues[queueName] = [];\n }\n }, {\n key: 'addCallback',\n value: function addCallback(queueName, callback) {\n this._getQueue(queueName).push(callback);\n }\n }, {\n key: '_scheduleCallbackForRemoval',\n value: function _scheduleCallbackForRemoval(queueName, callback) {\n this.removalQueues[queueName].push(callback);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce(queueName, callback) {\n var queue = this._getQueue(queueName);\n if (queue.indexOf(callback) === -1) {\n queue.push(callback);\n this._scheduleCallbackForRemoval(queueName, callback);\n }\n }\n }, {\n key: '_getQueue',\n value: function _getQueue(queueName) {\n var queue = this.callbackQueues[queueName];\n (0, _mobiledocKitUtilsAssert['default'])('No queue found for \"' + queueName + '\"', !!queue);\n return queue;\n }\n }]);\n\n return LifecycleCallbacks;\n })();\n\n exports['default'] = LifecycleCallbacks;\n});","define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_ITEM_TAGNAMES = ['li'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_ITEM_TAGNAMES = VALID_LIST_ITEM_TAGNAMES;\n\n var ListItem = (function (_Markerable) {\n _inherits(ListItem, _Markerable);\n\n function ListItem(tagName) {\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, ListItem);\n\n _get(Object.getPrototypeOf(ListItem.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, tagName, markers);\n this.isListItem = true;\n this.isNested = true;\n }\n\n _createClass(ListItem, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_ITEM_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n // FIXME need to check if we are going to split into two list items\n // or a list item and a new markup section:\n var isLastItem = !this.next;\n var createNewSection = !marker && offset === 0 && isLastItem;\n\n var beforeSection = this.builder.createListItem();\n var afterSection = createNewSection ? this.builder.createMarkupSection() : this.builder.createListItem();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }, {\n key: 'post',\n get: function get() {\n return this.section.post;\n }\n }]);\n\n return ListItem;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = ListItem;\n});","define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitModels_attributable, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_SECTION_TAGNAMES = ['ul', 'ol'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_SECTION_TAGNAMES = VALID_LIST_SECTION_TAGNAMES;\n var DEFAULT_TAG_NAME = VALID_LIST_SECTION_TAGNAMES[0];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n\n var ListSection = (function (_Section) {\n _inherits(ListSection, _Section);\n\n function ListSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n\n var _this = this;\n\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n _classCallCheck(this, ListSection);\n\n _get(Object.getPrototypeOf(ListSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_SECTION_TYPE);\n this.tagName = tagName;\n this.isListSection = true;\n this.isLeafSection = false;\n\n (0, _mobiledocKitModels_attributable.attributable)(this);\n (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var k = _ref2[0];\n var v = _ref2[1];\n return _this.setAttribute(k, v);\n });\n\n this.items = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(i) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem);\n i.section = i.parent = _this;\n },\n freeItem: function freeItem(i) {\n return i.section = i.parent = null;\n }\n });\n this.sections = this.items;\n\n items.forEach(function (i) {\n return _this.items.append(i);\n });\n }\n\n _createClass(ListSection, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.items.head.headPosition();\n }\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.items.tail.tailPosition();\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newSection = this.builder.createListSection(this.tagName);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.items, function (i) {\n return newSection.items.append(i.clone());\n });\n return newSection;\n }\n\n /**\n * Mutates this list\n * @param {ListSection|Markerable}\n * @return null\n */\n }, {\n key: 'join',\n value: function join(other) {\n var _this2 = this;\n\n if (other.isListSection) {\n other.items.forEach(function (i) {\n return _this2.join(i);\n });\n } else if (other.isMarkerable) {\n var item = this.builder.createListItem();\n item.join(other);\n this.items.append(item);\n }\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.items.isEmpty;\n }\n }]);\n\n return ListSection;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = ListSection;\n});","define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // Unicode uses a pair of \"surrogate\" characters\" (a high- and low-surrogate)\n // to encode characters outside the basic multilingual plane (like emoji and\n // some languages).\n // These values are the unicode code points for the start and end of the\n // high- and low-surrogate characters.\n // See \"high surrogate\" and \"low surrogate\" on\n // https://en.wikipedia.org/wiki/Unicode_block\n var HIGH_SURROGATE_RANGE = [0xD800, 0xDBFF];\n exports.HIGH_SURROGATE_RANGE = HIGH_SURROGATE_RANGE;\n var LOW_SURROGATE_RANGE = [0xDC00, 0xDFFF];\n\n exports.LOW_SURROGATE_RANGE = LOW_SURROGATE_RANGE;\n var Marker = (function (_LinkedItem) {\n _inherits(Marker, _LinkedItem);\n\n function Marker() {\n var _this = this;\n\n var value = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, Marker);\n\n _get(Object.getPrototypeOf(Marker.prototype), 'constructor', this).call(this);\n this.value = value;\n (0, _mobiledocKitUtilsAssert['default'])('Marker must have value', value !== undefined && value !== null);\n this.markups = [];\n this.type = _mobiledocKitModelsTypes.MARKER_TYPE;\n this.isMarker = true;\n this.isAtom = false;\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Marker, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createMarker(this.value, clonedMarkups);\n }\n }, {\n key: 'charAt',\n value: function charAt(offset) {\n return this.value.slice(offset, offset + 1);\n }\n\n /**\n * A marker's text is equal to its value.\n * Compare with an Atom which distinguishes between text and value\n */\n }, {\n key: 'deleteValueAtOffset',\n\n // delete the character at this offset,\n // update the value with the new value\n value: function deleteValueAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot delete value at offset outside bounds', offset >= 0 && offset <= this.length);\n\n var width = 1;\n var code = this.value.charCodeAt(offset);\n if (code >= HIGH_SURROGATE_RANGE[0] && code <= HIGH_SURROGATE_RANGE[1]) {\n width = 2;\n } else if (code >= LOW_SURROGATE_RANGE[0] && code <= LOW_SURROGATE_RANGE[1]) {\n width = 2;\n offset = offset - 1;\n }\n\n var left = this.value.slice(0, offset);\n var right = this.value.slice(offset + width);\n\n this.value = left + right;\n\n return width;\n }\n }, {\n key: 'canJoin',\n value: function canJoin(other) {\n return other && other.isMarker && (0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(this.markups, other.markups);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(offset) {\n return this.value.slice(0, offset);\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? this.length : arguments[1];\n\n var markers = [this.builder.createMarker(this.value.substring(0, offset)), this.builder.createMarker(this.value.substring(offset, endOffset)), this.builder.createMarker(this.value.substring(endOffset))];\n\n this.markups.forEach(function (mu) {\n return markers.forEach(function (m) {\n return m.addMarkup(mu);\n });\n });\n return markers;\n }\n\n /**\n * @return {Array} 2 markers either or both of which could be blank\n */\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n var value = this.value;\n var builder = this.builder;\n\n var pre = builder.createMarker(value.substring(0, offset));\n var post = builder.createMarker(value.substring(offset));\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n\n return [pre, post];\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.isBlank;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.length === 0;\n }\n }, {\n key: 'text',\n get: function get() {\n return this.value;\n }\n }, {\n key: 'length',\n get: function get() {\n return this.value.length;\n }\n }]);\n\n return Marker;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Marker, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Marker;\n});","define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModels_attributable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsObjectUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // valid values of `tagName` for a MarkupSection\n var VALID_MARKUP_SECTION_TAGNAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_SECTION_TAGNAMES = VALID_MARKUP_SECTION_TAGNAMES;\n // valid element names for a MarkupSection. A MarkupSection with a tagName\n // not in this will be rendered as a div with a className matching the\n // tagName\n var MARKUP_SECTION_ELEMENT_NAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n exports.MARKUP_SECTION_ELEMENT_NAMES = MARKUP_SECTION_ELEMENT_NAMES;\n var DEFAULT_TAG_NAME = VALID_MARKUP_SECTION_TAGNAMES[8];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n var MarkupSection = (function (_Markerable) {\n _inherits(MarkupSection, _Markerable);\n\n function MarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n\n var _this = this;\n\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n _classCallCheck(this, MarkupSection);\n\n _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers);\n\n (0, _mobiledocKitModels_attributable.attributable)(this);\n (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var k = _ref2[0];\n var v = _ref2[1];\n return _this.setAttribute(k, v);\n });\n\n this.isMarkupSection = true;\n }\n\n _createClass(MarkupSection, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_MARKUP_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var beforeSection = this.builder.createMarkupSection(this.tagName, [], false, this.attributes);\n var afterSection = this.builder.createMarkupSection();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }]);\n\n return MarkupSection;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = MarkupSection;\n});","define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var VALID_MARKUP_TAGNAMES = ['a', 'b', 'code', 'em', 'i', 's', // strikethrough\n 'strong', 'sub', // subscript\n 'sup', // superscript\n 'u'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_TAGNAMES = VALID_MARKUP_TAGNAMES;\n var VALID_ATTRIBUTES = ['href', 'rel'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n /**\n * A Markup is similar with an inline HTML tag that might be added to\n * text to modify its meaning and/or display. Examples of types of markup\n * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links).\n * @property {String} tagName\n */\n\n var Markup = (function () {\n /*\n * @param {Object} attributes key-values\n */\n\n function Markup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, Markup);\n\n this.tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must use attributes object param (not array) for Markup', !Array.isArray(attributes));\n\n this.attributes = (0, _mobiledocKitUtilsArrayUtils.filterObject)(attributes, VALID_ATTRIBUTES);\n this.type = _mobiledocKitModelsTypes.MARKUP_TYPE;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1);\n }\n\n /**\n * Whether text in the forward direction of the cursor (i.e. to the right in ltr text)\n * should be considered to have this markup applied to it.\n * @private\n */\n\n _createClass(Markup, [{\n key: 'isForwardInclusive',\n value: function isForwardInclusive() {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(\"a\") ? false : true;\n }\n }, {\n key: 'isBackwardInclusive',\n value: function isBackwardInclusive() {\n return false;\n }\n }, {\n key: 'hasTag',\n value: function hasTag(tagName) {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n }\n\n /**\n * Returns the attribute value\n * @param {String} name, e.g. \"href\"\n */\n }, {\n key: 'getAttribute',\n value: function getAttribute(name) {\n return this.attributes[name];\n }\n }], [{\n key: 'isValidElement',\n value: function isValidElement(element) {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n return VALID_MARKUP_TAGNAMES.indexOf(tagName) !== -1;\n }\n }]);\n\n return Markup;\n })();\n\n exports['default'] = Markup;\n});","define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/models/atom', 'mobiledoc-kit/models/post', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/image', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsAtom, _mobiledocKitModelsPost, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsImage, _mobiledocKitModelsMarker, _mobiledocKitModelsMarkup, _mobiledocKitModelsCard, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function cacheKey(tagName, attributes) {\n return (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName) + '-' + (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(attributes).join('-');\n }\n\n function addMarkupToCache(cache, markup) {\n cache[cacheKey(markup.tagName, markup.attributes)] = markup;\n }\n\n function findMarkupInCache(cache, tagName, attributes) {\n var key = cacheKey(tagName, attributes);\n return cache[key];\n }\n\n /**\n * The PostNodeBuilder is used to create new {@link Post} primitives, such\n * as a MarkupSection, a CardSection, a Markup, etc. Every instance of an\n * {@link Editor} has its own builder instance. The builder can be used\n * inside an {@link Editor#run} callback to programmatically create new\n * Post primitives to insert into the document.\n * A PostNodeBuilder should be read from the Editor, *not* instantiated on its own.\n */\n\n var PostNodeBuilder = (function () {\n /**\n * @private\n */\n\n function PostNodeBuilder() {\n _classCallCheck(this, PostNodeBuilder);\n\n this.markupCache = {};\n }\n\n /**\n * @return {Post} A new, blank post\n */\n\n _createClass(PostNodeBuilder, [{\n key: 'createPost',\n value: function createPost() {\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var post = new _mobiledocKitModelsPost['default']();\n post.builder = this;\n\n sections.forEach(function (s) {\n return post.sections.append(s);\n });\n\n return post;\n }\n }, {\n key: 'createMarkerableSection',\n value: function createMarkerableSection(type, tagName) {\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.createListItem(markers);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.createMarkupSection(tagName, markers);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markerable section of type ' + type, false);\n }\n }\n\n /**\n * @param {tagName} [tagName='P']\n * @param {Marker[]} [markers=[]]\n * @return {MarkupSection}\n */\n }, {\n key: 'createMarkupSection',\n value: function createMarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0];\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n var attributes = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers, attributes);\n if (isGenerated) {\n section.isGenerated = true;\n }\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListSection',\n value: function createListSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0];\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsListSection['default'](tagName, items, attributes);\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListItem',\n value: function createListItem() {\n var markers = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('li');\n var item = new _mobiledocKitModelsListItem['default'](tagName, markers);\n item.builder = this;\n return item;\n }\n }, {\n key: 'createImageSection',\n value: function createImageSection(url) {\n var section = new _mobiledocKitModelsImage['default']();\n if (url) {\n section.src = url;\n }\n return section;\n }\n\n /**\n * @param {String} name\n * @param {Object} [payload={}]\n * @return {CardSection}\n */\n }, {\n key: 'createCardSection',\n value: function createCardSection(name) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var card = new _mobiledocKitModelsCard['default'](name, payload);\n card.builder = this;\n return card;\n }\n\n /**\n * @param {String} value\n * @param {Markup[]} [markups=[]]\n * @return {Marker}\n */\n }, {\n key: 'createMarker',\n value: function createMarker(value) {\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var marker = new _mobiledocKitModelsMarker['default'](value, markups);\n marker.builder = this;\n return marker;\n }\n\n /**\n * @param {String} name\n * @param {String} [value='']\n * @param {Object} [payload={}]\n * @param {Markup[]} [markups=[]]\n * @return {Atom}\n */\n }, {\n key: 'createAtom',\n value: function createAtom(name) {\n var value = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var payload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n var atom = new _mobiledocKitModelsAtom['default'](name, value, payload, markups);\n atom.builder = this;\n return atom;\n }\n\n /**\n * @param {String} tagName\n * @param {Object} attributes Key-value pairs of attributes for the markup\n * @return {Markup}\n */\n }, {\n key: 'createMarkup',\n value: function createMarkup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n var markup = findMarkupInCache(this.markupCache, tagName, attributes);\n if (!markup) {\n markup = new _mobiledocKitModelsMarkup['default'](tagName, attributes);\n markup.builder = this;\n addMarkupToCache(this.markupCache, markup);\n }\n\n return markup;\n }\n }]);\n\n return PostNodeBuilder;\n })();\n\n exports['default'] = PostNodeBuilder;\n});","define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * The Post is an in-memory representation of an editor's document.\n * An editor always has a single post. The post is organized into a list of\n * sections. Each section may be markerable (contains \"markers\", aka editable\n * text) or non-markerable (e.g., a card).\n * When persisting a post, it must first be serialized (loss-lessly) into\n * mobiledoc using {@link Editor#serialize}.\n */\n\n var Post = (function () {\n /**\n * @private\n */\n\n function Post() {\n var _this = this;\n\n _classCallCheck(this, Post);\n\n this.type = _mobiledocKitModelsTypes.POST_TYPE;\n this.sections = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(s) {\n return s.post = s.parent = _this;\n },\n freeItem: function freeItem(s) {\n return s.post = s.parent = null;\n }\n });\n }\n\n /**\n * @return {Position} The position at the start of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n\n _createClass(Post, [{\n key: 'headPosition',\n value: function headPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.head.headPosition();\n }\n }\n\n /**\n * @return {Position} The position at the end of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.tail.tailPosition();\n }\n }\n\n /**\n * @return {Range} A range encompassing the entire post\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'markersContainedByRange',\n\n /**\n * @param {Range} range\n * @return {Array} markers that are completely contained by the range\n */\n value: function markersContainedByRange(range) {\n var markers = [];\n\n this.walkMarkerableSections(range, function (section) {\n section._markersInRange(range.trimTo(section), function (m, _ref) {\n var isContained = _ref.isContained;\n if (isContained) {\n markers.push(m);\n }\n });\n });\n\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n\n if (range.isCollapsed) {\n var pos = range.head;\n if (pos.isMarkerable) {\n var back = pos.markerIn(-1);\n var forward = pos.markerIn(1);\n\n if (back && forward && back === forward) {\n back.markups.forEach(function (m) {\n return markups.add(m);\n });\n } else {\n (back && back.markups || []).forEach(function (m) {\n if (m.isForwardInclusive()) {\n markups.add(m);\n }\n });\n (forward && forward.markups || []).forEach(function (m) {\n if (m.isBackwardInclusive()) {\n markups.add(m);\n }\n });\n }\n }\n } else {\n this.walkMarkerableSections(range, function (section) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markupsInRange(range.trimTo(section)), function (m) {\n return markups.add(m);\n });\n });\n }\n\n return markups.toArray();\n }\n }, {\n key: 'walkAllLeafSections',\n value: function walkAllLeafSections(callback) {\n var range = this.headPosition().toRange(this.tailPosition());\n return this.walkLeafSections(range, callback);\n }\n }, {\n key: 'walkLeafSections',\n value: function walkLeafSections(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n var index = 0;\n var nextSection = undefined,\n shouldStop = undefined;\n var currentSection = head.section;\n\n while (currentSection) {\n nextSection = this._nextLeafSection(currentSection);\n shouldStop = currentSection === tail.section;\n\n callback(currentSection, index);\n index++;\n\n if (shouldStop) {\n break;\n } else {\n currentSection = nextSection;\n }\n }\n }\n }, {\n key: 'walkMarkerableSections',\n value: function walkMarkerableSections(range, callback) {\n this.walkLeafSections(range, function (section) {\n if (section.isMarkerable) {\n callback(section);\n }\n });\n }\n\n // return the next section that has markers after this one,\n // possibly skipping non-markerable sections\n }, {\n key: '_nextLeafSection',\n value: function _nextLeafSection(section) {\n if (!section) {\n return null;\n }\n\n var next = section.next;\n if (next) {\n if (next.isLeafSection) {\n return next;\n } else if (next.items) {\n return next.items.head;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false);\n }\n } else if (section.isNested) {\n // if there is no section after this, but this section is a child\n // (e.g. a ListItem inside a ListSection), check for a markerable\n // section after its parent\n return this._nextLeafSection(section.parent);\n }\n }\n\n /**\n * @param {Range} range\n * @return {Post} A new post, constrained to {range}\n */\n }, {\n key: 'trimTo',\n value: function trimTo(range) {\n var post = this.builder.createPost();\n var builder = this.builder;\n\n var sectionParent = post,\n listParent = null;\n this.walkLeafSections(range, function (section) {\n var newSection = undefined;\n if (section.isMarkerable) {\n if (section.isListItem) {\n if (listParent) {\n sectionParent = null;\n } else {\n listParent = builder.createListSection(section.parent.tagName);\n post.sections.append(listParent);\n sectionParent = null;\n }\n newSection = builder.createListItem();\n listParent.items.append(newSection);\n } else {\n listParent = null;\n sectionParent = post;\n newSection = builder.createMarkupSection(section.tagName);\n }\n\n var currentRange = range.trimTo(section);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markersFor(currentRange.headSectionOffset, currentRange.tailSectionOffset), function (m) {\n return newSection.markers.append(m);\n });\n } else {\n newSection = section.clone();\n sectionParent = post;\n }\n if (sectionParent) {\n sectionParent.sections.append(newSection);\n }\n });\n return post;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.sections.isEmpty;\n }\n\n /**\n * If the post has no sections, or only has one, blank section, then it does\n * not have content and this method returns false. Otherwise it is true.\n * @return {Boolean}\n * @public\n */\n }, {\n key: 'hasContent',\n get: function get() {\n if (this.sections.length > 1 || this.sections.length === 1 && !this.sections.head.isBlank) {\n return true;\n } else {\n return false;\n }\n }\n }]);\n\n return Post;\n })();\n\n exports['default'] = Post;\n});","define('mobiledoc-kit/models/render-node', ['exports', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var RenderNode = (function (_LinkedItem) {\n _inherits(RenderNode, _LinkedItem);\n\n function RenderNode(postNode, renderTree) {\n _classCallCheck(this, RenderNode);\n\n _get(Object.getPrototypeOf(RenderNode.prototype), 'constructor', this).call(this);\n this.parent = null;\n this.isDirty = true;\n this.isRemoved = false;\n this.postNode = postNode;\n this._childNodes = null;\n this._element = null;\n this._cursorElement = null; // blank render nodes need a cursor element\n this.renderTree = renderTree;\n\n // RenderNodes for Markers keep track of their markupElement\n this.markupElement = null;\n\n // RenderNodes for Atoms use these properties\n this.headTextNode = null;\n this.tailTextNode = null;\n this.atomNode = null;\n\n // RenderNodes for cards use this property\n this.cardNode = null;\n }\n\n _createClass(RenderNode, [{\n key: 'isAttached',\n value: function isAttached() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot check if a renderNode is attached without an element.', !!this.element);\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(this.renderTree.rootElement, this.element);\n }\n }, {\n key: 'scheduleForRemoval',\n value: function scheduleForRemoval() {\n this.isRemoved = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markDirty',\n value: function markDirty() {\n this.isDirty = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markClean',\n value: function markClean() {\n this.isDirty = false;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.element = null;\n this.parent = null;\n this.postNode = null;\n this.renderTree = null;\n }\n }, {\n key: 'reparsesMutationOfChildNode',\n value: function reparsesMutationOfChildNode(node) {\n if (this.postNode.isCardSection) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.cardNode.element, node);\n } else if (this.postNode.isAtom) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.atomNode.element, node);\n }\n return true;\n }\n }, {\n key: 'childNodes',\n get: function get() {\n var _this = this;\n\n if (!this._childNodes) {\n this._childNodes = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(item) {\n return item.parent = _this;\n },\n freeItem: function freeItem(item) {\n return item.destroy();\n }\n });\n }\n return this._childNodes;\n }\n }, {\n key: 'isRendered',\n get: function get() {\n return !!this.element;\n }\n }, {\n key: 'element',\n set: function set(element) {\n var currentElement = this._element;\n this._element = element;\n\n if (currentElement) {\n this.renderTree.removeElementRenderNode(currentElement);\n }\n\n if (element) {\n this.renderTree.setElementRenderNode(element, this);\n }\n },\n get: function get() {\n return this._element;\n }\n }, {\n key: 'cursorElement',\n set: function set(cursorElement) {\n this._cursorElement = cursorElement;\n },\n get: function get() {\n return this._cursorElement || this.element;\n }\n }]);\n\n return RenderNode;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = RenderNode;\n});","define('mobiledoc-kit/models/render-tree', ['exports', 'mobiledoc-kit/models/render-node', 'mobiledoc-kit/utils/element-map'], function (exports, _mobiledocKitModelsRenderNode, _mobiledocKitUtilsElementMap) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var RenderTree = (function () {\n function RenderTree(rootPostNode) {\n _classCallCheck(this, RenderTree);\n\n this._rootNode = this.buildRenderNode(rootPostNode);\n this._elements = new _mobiledocKitUtilsElementMap['default']();\n }\n\n /*\n * @return {RenderNode} The root render node in this tree\n */\n\n _createClass(RenderTree, [{\n key: 'getElementRenderNode',\n\n /*\n * @param {DOMNode} element\n * @return {RenderNode} The renderNode for this element, if any\n */\n value: function getElementRenderNode(element) {\n return this._elements.get(element);\n }\n }, {\n key: 'setElementRenderNode',\n value: function setElementRenderNode(element, renderNode) {\n this._elements.set(element, renderNode);\n }\n }, {\n key: 'removeElementRenderNode',\n value: function removeElementRenderNode(element) {\n this._elements.remove(element);\n }\n\n /**\n * @param {DOMNode} element\n * Walk up from the dom element until we find a renderNode element\n */\n }, {\n key: 'findRenderNodeFromElement',\n value: function findRenderNodeFromElement(element) {\n var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {\n return true;\n } : arguments[1];\n\n var renderNode = undefined;\n while (element) {\n renderNode = this.getElementRenderNode(element);\n if (renderNode && conditionFn(renderNode)) {\n return renderNode;\n }\n\n // continue loop\n element = element.parentNode;\n\n // stop if we are at the root element\n if (element === this.rootElement) {\n if (conditionFn(this.rootNode)) {\n return this.rootNode;\n } else {\n return;\n }\n }\n }\n }\n }, {\n key: 'buildRenderNode',\n value: function buildRenderNode(postNode) {\n var renderNode = new _mobiledocKitModelsRenderNode['default'](postNode, this);\n postNode.renderNode = renderNode;\n return renderNode;\n }\n }, {\n key: 'rootNode',\n get: function get() {\n return this._rootNode;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'isDirty',\n get: function get() {\n return this.rootNode && this.rootNode.isDirty;\n }\n\n /*\n * @return {DOMNode} The root DOM element in this tree\n */\n }, {\n key: 'rootElement',\n get: function get() {\n return this.rootNode.element;\n }\n }]);\n\n return RenderTree;\n })();\n\n exports['default'] = RenderTree;\n});","define('mobiledoc-kit/models/types', ['exports'], function (exports) {\n 'use strict';\n\n var MARKUP_SECTION_TYPE = 'markup-section';\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var LIST_SECTION_TYPE = 'list-section';\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var MARKUP_TYPE = 'markup';\n exports.MARKUP_TYPE = MARKUP_TYPE;\n var MARKER_TYPE = 'marker';\n exports.MARKER_TYPE = MARKER_TYPE;\n var POST_TYPE = 'post';\n exports.POST_TYPE = POST_TYPE;\n var LIST_ITEM_TYPE = 'list-item';\n exports.LIST_ITEM_TYPE = LIST_ITEM_TYPE;\n var CARD_TYPE = 'card-section';\n exports.CARD_TYPE = CARD_TYPE;\n var IMAGE_SECTION_TYPE = 'image-section';\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var ATOM_TYPE = 'atom';\n exports.ATOM_TYPE = ATOM_TYPE;\n});","define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/parsers/section', 'mobiledoc-kit/models/markup'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCharacters, _mobiledocKitParsersSection, _mobiledocKitModelsMarkup) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.transformHTMLText = transformHTMLText;\n exports.trimSectionText = trimSectionText;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var GOOGLE_DOCS_CONTAINER_ID_REGEX = /^docs\\-internal\\-guid/;\n\n var NO_BREAK_SPACE_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.NO_BREAK_SPACE, 'g');\n var TAB_CHARACTER_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.TAB_CHARACTER, 'g');\n\n function transformHTMLText(textContent) {\n var text = textContent;\n text = text.replace(NO_BREAK_SPACE_REGEX, ' ');\n text = text.replace(TAB_CHARACTER_REGEX, _mobiledocKitUtilsCharacters.TAB);\n return text;\n }\n\n function trimSectionText(section) {\n if (section.isMarkerable && section.markers.length) {\n var _section$markers = section.markers;\n var head = _section$markers.head;\n var tail = _section$markers.tail;\n\n head.value = head.value.replace(/^\\s+/, '');\n tail.value = tail.value.replace(/\\s+$/, '');\n }\n }\n\n function isGoogleDocsContainer(element) {\n return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id);\n }\n\n function detectRootElement(element) {\n var childNodes = element.childNodes || [];\n var googleDocsContainer = (0, _mobiledocKitUtilsArrayUtils.detect)(childNodes, isGoogleDocsContainer);\n\n if (googleDocsContainer) {\n return googleDocsContainer;\n } else {\n return element;\n }\n }\n\n var TAG_REMAPPING = {\n 'b': 'strong',\n 'i': 'em'\n };\n\n function remapTagName(tagName) {\n var normalized = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var remapped = TAG_REMAPPING[normalized];\n return remapped || normalized;\n }\n\n function trim(str) {\n return str.replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n\n function walkMarkerableNodes(parent, callback) {\n var currentNode = parent;\n\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(currentNode) || (0, _mobiledocKitUtilsDomUtils.isElementNode)(currentNode) && currentNode.classList.contains(_mobiledocKitRenderersEditorDom.ATOM_CLASS_NAME)) {\n callback(currentNode);\n } else {\n currentNode = currentNode.firstChild;\n while (currentNode) {\n walkMarkerableNodes(currentNode, callback);\n currentNode = currentNode.nextSibling;\n }\n }\n }\n\n /**\n * Parses DOM element -> Post\n * @private\n */\n\n var DOMParser = (function () {\n function DOMParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, DOMParser);\n\n this.builder = builder;\n this.sectionParser = new _mobiledocKitParsersSection['default'](this.builder, options);\n }\n\n _createClass(DOMParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n var post = this.builder.createPost();\n var rootElement = detectRootElement(element);\n\n this._eachChildNode(rootElement, function (child) {\n var sections = _this.parseSections(child);\n _this.appendSections(post, sections);\n });\n\n // trim leading/trailing whitespace of markerable sections to avoid\n // unnessary whitespace from indented HTML input\n (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n return trimSectionText(section);\n });\n\n return post;\n }\n }, {\n key: 'appendSections',\n value: function appendSections(post, sections) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(sections, function (section) {\n return _this2.appendSection(post, section);\n });\n }\n }, {\n key: 'appendSection',\n value: function appendSection(post, section) {\n if (section.isBlank || section.isMarkerable && trim(section.text) === \"\" && !(0, _mobiledocKitUtilsArrayUtils.any)(section.markers, function (marker) {\n return marker.isAtom;\n })) {\n return;\n }\n\n var lastSection = post.sections.tail;\n if (lastSection && lastSection._inferredTagName && section._inferredTagName && lastSection.tagName === section.tagName) {\n lastSection.join(section);\n } else {\n post.sections.append(section);\n }\n }\n }, {\n key: '_eachChildNode',\n value: function _eachChildNode(element, callback) {\n var nodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n return callback(node);\n });\n }\n }, {\n key: 'parseSections',\n value: function parseSections(element) {\n return this.sectionParser.parse(element);\n }\n\n // walk up from the textNode until the rootNode, converting each\n // parentNode into a markup\n }, {\n key: 'collectMarkups',\n value: function collectMarkups(textNode, rootNode) {\n var markups = [];\n var currentNode = textNode.parentNode;\n while (currentNode && currentNode !== rootNode) {\n var markup = this.markupFromNode(currentNode);\n if (markup) {\n markups.push(markup);\n }\n\n currentNode = currentNode.parentNode;\n }\n return markups;\n }\n\n // Turn an element node into a markup\n }, {\n key: 'markupFromNode',\n value: function markupFromNode(node) {\n if (_mobiledocKitModelsMarkup['default'].isValidElement(node)) {\n var tagName = remapTagName(node.tagName);\n var attributes = (0, _mobiledocKitUtilsDomUtils.getAttributes)(node);\n return this.builder.createMarkup(tagName, attributes);\n }\n }\n\n // FIXME should move to the section parser?\n // FIXME the `collectMarkups` logic could simplify the section parser?\n }, {\n key: 'reparseSection',\n value: function reparseSection(section, renderTree) {\n switch (section.type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n return this.reparseListSection(section, renderTree);\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.reparseListItem(section, renderTree);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.reparseMarkupSection(section, renderTree);\n default:\n return; // can only parse the above types\n }\n }\n }, {\n key: 'reparseMarkupSection',\n value: function reparseMarkupSection(section, renderTree) {\n return this._reparseSectionContainingMarkers(section, renderTree);\n }\n }, {\n key: 'reparseListItem',\n value: function reparseListItem(listItem, renderTree) {\n return this._reparseSectionContainingMarkers(listItem, renderTree);\n }\n }, {\n key: 'reparseListSection',\n value: function reparseListSection(listSection, renderTree) {\n var _this3 = this;\n\n listSection.items.forEach(function (li) {\n return _this3.reparseListItem(li, renderTree);\n });\n }\n }, {\n key: '_reparseSectionContainingMarkers',\n value: function _reparseSectionContainingMarkers(section, renderTree) {\n var _this4 = this;\n\n var element = section.renderNode.element;\n var seenRenderNodes = [];\n var previousMarker = undefined;\n\n walkMarkerableNodes(element, function (node) {\n var marker = undefined;\n var renderNode = renderTree.getElementRenderNode(node);\n if (renderNode) {\n if (renderNode.postNode.isMarker) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n if (text.length) {\n marker = renderNode.postNode;\n marker.value = text;\n marker.markups = markups;\n } else {\n renderNode.scheduleForRemoval();\n }\n } else if (renderNode.postNode.isAtom) {\n var _renderNode = renderNode;\n var headTextNode = _renderNode.headTextNode;\n var tailTextNode = _renderNode.tailTextNode;\n\n if (headTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = headTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n headTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n if (previousMarker && previousMarker.isMarker) {\n previousMarker.value += value;\n if (previousMarker.renderNode) {\n previousMarker.renderNode.markDirty();\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newPreviousMarker = _this4.builder.createMarker(value, newMarkups);\n section.markers.insertBefore(newPreviousMarker, postNode);\n\n var newPreviousRenderNode = renderTree.buildRenderNode(newPreviousMarker);\n newPreviousRenderNode.markDirty();\n section.renderNode.markDirty();\n\n seenRenderNodes.push(newPreviousRenderNode);\n section.renderNode.childNodes.insertBefore(newPreviousRenderNode, renderNode);\n }\n }\n if (tailTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = tailTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n tailTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n\n if (renderNode.postNode.next && renderNode.postNode.next.isMarker) {\n var nextMarker = renderNode.postNode.next;\n\n if (nextMarker.renderNode) {\n var nextValue = nextMarker.renderNode.element.textContent;\n nextMarker.renderNode.element.textContent = value + nextValue;\n } else {\n var nextValue = value + nextMarker.value;\n nextMarker.value = nextValue;\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newMarker = _this4.builder.createMarker(value, newMarkups);\n\n section.markers.insertAfter(newMarker, postNode);\n\n var newRenderNode = renderTree.buildRenderNode(newMarker);\n seenRenderNodes.push(newRenderNode);\n\n newRenderNode.markDirty();\n section.renderNode.markDirty();\n\n section.renderNode.childNodes.insertAfter(newRenderNode, renderNode);\n }\n }\n if (renderNode) {\n marker = renderNode.postNode;\n }\n }\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n marker = _this4.builder.createMarker(text, markups);\n\n renderNode = renderTree.buildRenderNode(marker);\n renderNode.element = node;\n renderNode.markClean();\n section.renderNode.markDirty();\n\n var previousRenderNode = previousMarker && previousMarker.renderNode;\n section.markers.insertAfter(marker, previousMarker);\n section.renderNode.childNodes.insertAfter(renderNode, previousRenderNode);\n }\n\n if (renderNode) {\n seenRenderNodes.push(renderNode);\n }\n previousMarker = marker;\n });\n\n var renderNode = section.renderNode.childNodes.head;\n while (renderNode) {\n if (seenRenderNodes.indexOf(renderNode) === -1) {\n renderNode.scheduleForRemoval();\n }\n renderNode = renderNode.next;\n }\n }\n }]);\n\n return DOMParser;\n })();\n\n exports['default'] = DOMParser;\n});","define('mobiledoc-kit/parsers/html', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/parsers/dom'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitParsersDom) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var HTMLParser = (function () {\n function HTMLParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, HTMLParser);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass builder to HTMLParser', builder);\n this.builder = builder;\n this.options = options;\n }\n\n /**\n * @param {String} html to parse\n * @return {Post} A post abstract\n */\n\n _createClass(HTMLParser, [{\n key: 'parse',\n value: function parse(html) {\n var dom = (0, _mobiledocKitUtilsDomUtils.parseHTML)(html);\n var parser = new _mobiledocKitParsersDom['default'](this.builder, this.options);\n return parser.parse(dom);\n }\n }]);\n\n return HTMLParser;\n })();\n\n exports['default'] = HTMLParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sectionData = _ref.sections;\n\n try {\n var markerTypes = sectionData[0];\n var sections = sectionData[1];\n\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this2 = this;\n\n sections.forEach(function (section) {\n return _this2.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ' + type, false);\n }\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref3, post) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref4, post) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var src = _ref42[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 3);\n\n var tagName = _ref62[1];\n var items = _ref62[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this3 = this;\n\n items.forEach(function (i) {\n return _this3.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this4 = this;\n\n markers.forEach(function (m) {\n return _this4.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref7, parent) {\n var _this5 = this;\n\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var markerTypeIndexes = _ref72[0];\n var closeCount = _ref72[1];\n var value = _ref72[2];\n\n markerTypeIndexes.forEach(function (index) {\n _this5.markups.push(_this5.markerTypes[index]);\n });\n var marker = this.builder.createMarker(value, this.markups.slice());\n parent.markers.append(marker);\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE:\n {\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n var atomName = _getAtomTypeFromIndex2[0];\n var atomValue = _getAtomTypeFromIndex2[1];\n var atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n }\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 4);\n\n var tagName = _ref72[1];\n var markers = _ref72[2];\n var attributesArray = _ref72[3];\n\n var section = this.builder.createMarkupSection(tagName);\n post.sections.append(section);\n if (attributesArray) {\n (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref8) {\n var _ref82 = _slicedToArray(_ref8, 2);\n\n var key = _ref82[0];\n var value = _ref82[1];\n\n section.setAttribute(key, value);\n });\n }\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref9, post) {\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var tagName = _ref92[1];\n var items = _ref92[2];\n var attributesArray = _ref92[3];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n if (attributesArray) {\n (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref10) {\n var _ref102 = _slicedToArray(_ref10, 2);\n\n var key = _ref102[0];\n var value = _ref102[1];\n\n section.setAttribute(key, value);\n });\n }\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref11, parent) {\n var _this7 = this;\n\n var _ref112 = _slicedToArray(_ref11, 4);\n\n var type = _ref112[0];\n var markerTypeIndexes = _ref112[1];\n var closeCount = _ref112[2];\n var value = _ref112[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_ATOM_MARKER_TYPE:\n {\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n var atomName = _getAtomTypeFromIndex2[0];\n var atomValue = _getAtomTypeFromIndex2[1];\n var atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n }\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc03, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE:\n {\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n var atomName = _getAtomTypeFromIndex2[0];\n var atomValue = _getAtomTypeFromIndex2[1];\n var atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n }\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/parsers/mobiledoc/0-3-2', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitParsersMobiledoc032, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n function parseVersion(mobiledoc) {\n return mobiledoc.version;\n }\n\n exports['default'] = {\n parse: function parse(builder, mobiledoc) {\n var version = parseVersion(mobiledoc);\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc02['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc032['default'](builder).parse(mobiledoc);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false);\n }\n }\n };\n});","define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkup, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitParsersDom, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SKIPPABLE_ELEMENT_TAG_NAMES = ['style', 'head', 'title', 'meta'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n var NEWLINES = /\\n/g;\n function sanitize(text) {\n return text.replace(NEWLINES, ' ');\n }\n\n /**\n * parses an element into a section, ignoring any non-markup\n * elements contained within\n * @private\n */\n\n var SectionParser = (function () {\n function SectionParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, SectionParser);\n\n this.builder = builder;\n this.plugins = options.plugins || [];\n }\n\n _createClass(SectionParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n if (this._isSkippable(element)) {\n return [];\n }\n this.sections = [];\n this.state = {};\n\n this._updateStateFromElement(element);\n\n var finished = false;\n\n // top-level text nodes will be run through parseNode later so avoid running\n // the node through parserPlugins twice\n if (!(0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n finished = this.runPlugins(element);\n }\n\n if (!finished) {\n var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n _this.parseNode(el);\n });\n }\n\n this._closeCurrentSection();\n\n return this.sections;\n }\n }, {\n key: 'runPlugins',\n value: function runPlugins(node) {\n var _this2 = this;\n\n var isNodeFinished = false;\n var env = {\n addSection: function addSection(section) {\n // avoid creating empty paragraphs due to wrapper elements around\n // parser-plugin-handled elements\n if (_this2.state.section.isMarkerable && !_this2.state.text && !_this2.state.section.text) {\n _this2.state.section = null;\n } else {\n _this2._closeCurrentSection();\n }\n _this2.sections.push(section);\n },\n addMarkerable: function addMarkerable(marker) {\n var state = _this2.state;\n var section = state.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable);\n if (state.text) {\n _this2._createMarker();\n }\n section.markers.append(marker);\n },\n nodeFinished: function nodeFinished() {\n isNodeFinished = true;\n }\n };\n for (var i = 0; i < this.plugins.length; i++) {\n var plugin = this.plugins[i];\n plugin(node, this.builder, env);\n if (isNodeFinished) {\n return true;\n }\n }\n return false;\n }\n\n /* eslint-disable complexity */\n }, {\n key: 'parseNode',\n value: function parseNode(node) {\n var _this3 = this;\n\n if (!this.state.section) {\n this._updateStateFromElement(node);\n }\n\n var nodeFinished = this.runPlugins(node);\n if (nodeFinished) {\n return;\n }\n\n // handle closing the current section and starting a new one if we hit a\n // new-section-creating element.\n if (this.state.section && !(0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.tagName) {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.tagName);\n var isListSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName);\n var isListItem = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName);\n var isMarkupSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName);\n var isNestedListSection = isListSection && this.state.section.isListItem;\n var lastSection = this.sections[this.sections.length - 1];\n\n // we can hit a list item after parsing a nested list, when that happens\n // and the lists are of different types we need to make sure we switch\n // the list type back\n if (isListItem && lastSection && lastSection.isListSection) {\n var parentElement = node.parentElement;\n var parentElementTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(parentElement.tagName);\n if (parentElementTagName !== lastSection.tagName) {\n this._closeCurrentSection();\n this._updateStateFromElement(parentElement);\n }\n }\n\n // if we've broken out of a list due to nested section-level elements we\n // can hit the next list item without having a list section in the current\n // state. In this instance we find the parent list node and use it to\n // re-initialize the state with a new list section\n if (isListItem && !(this.state.section.isListItem || this.state.section.isListSection) && !lastSection.isListSection) {\n this._closeCurrentSection();\n this._updateStateFromElement(node.parentElement);\n }\n\n // if we have consecutive list sections of different types (ul, ol) then\n // ensure we close the current section and start a new one\n var isNewListSection = lastSection && lastSection.isListSection && this.state.section.isListItem && isListSection && tagName !== lastSection.tagName;\n\n if (isNewListSection || isListSection && !isNestedListSection || isMarkupSection || isListItem) {\n // don't break out of the list for list items that contain a single

    .\n // deals with typical case of

  • Text

  • Text

  • \n if (this.state.section.isListItem && tagName === 'p' && !node.nextSibling && (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.parentElement.tagName))) {\n this.parseElementNode(node);\n return;\n }\n\n // avoid creating empty paragraphs due to wrapper elements around\n // section-creating elements\n if (this.state.section.isMarkerable && !this.state.text && this.state.section.markers.length === 0) {\n this.state.section = null;\n } else {\n this._closeCurrentSection();\n }\n\n this._updateStateFromElement(node);\n }\n\n if (this.state.section.isListSection) {\n // ensure the list section is closed and added to the sections list.\n // _closeCurrentSection handles pushing list items onto the list section\n this._closeCurrentSection();\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(node.childNodes, function (node) {\n _this3.parseNode(node);\n });\n return;\n }\n }\n\n switch (node.nodeType) {\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT:\n this.parseTextNode(node);\n break;\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT:\n this.parseElementNode(node);\n break;\n }\n }\n }, {\n key: 'parseElementNode',\n value: function parseElementNode(element) {\n var _state$markups,\n _this4 = this;\n\n var state = this.state;\n\n var markups = this._markupsFromElement(element);\n if (markups.length && state.text.length && state.section.isMarkerable) {\n this._createMarker();\n }\n (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups));\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.childNodes, function (node) {\n _this4.parseNode(node);\n });\n\n if (markups.length && state.text.length && state.section.isMarkerable) {\n // create the marker started for this node\n this._createMarker();\n }\n\n // pop the current markups from the stack\n state.markups.splice(-markups.length, markups.length);\n }\n }, {\n key: 'parseTextNode',\n value: function parseTextNode(textNode) {\n var state = this.state;\n\n state.text += sanitize(textNode.textContent);\n }\n }, {\n key: '_updateStateFromElement',\n value: function _updateStateFromElement(element) {\n var state = this.state;\n\n state.section = this._createSectionFromElement(element);\n state.markups = this._markupsFromElement(element);\n state.text = '';\n }\n }, {\n key: '_closeCurrentSection',\n value: function _closeCurrentSection() {\n var sections = this.sections;\n var state = this.state;\n\n var lastSection = sections[sections.length - 1];\n\n if (!state.section) {\n return;\n }\n\n // close a trailing text node if it exists\n if (state.text.length && state.section.isMarkerable) {\n this._createMarker();\n }\n\n // push listItems onto the listSection or add a new section\n if (state.section.isListItem && lastSection && lastSection.isListSection) {\n (0, _mobiledocKitParsersDom.trimSectionText)(state.section);\n lastSection.items.append(state.section);\n } else {\n // avoid creating empty markup sections, especially useful for indented source\n if (state.section.isMarkerable && !state.section.text.trim() && !(0, _mobiledocKitUtilsArrayUtils.any)(state.section.markers, function (marker) {\n return marker.isAtom;\n })) {\n state.section = null;\n state.text = '';\n return;\n }\n\n // remove empty list sections before creating a new section\n if (lastSection && lastSection.isListSection && lastSection.items.length === 0) {\n sections.pop();\n }\n\n sections.push(state.section);\n }\n\n state.section = null;\n state.text = '';\n }\n }, {\n key: '_markupsFromElement',\n value: function _markupsFromElement(element) {\n var builder = this.builder;\n\n var markups = [];\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n return markups;\n }\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n if (this._isValidMarkupForElement(tagName, element)) {\n markups.push(builder.createMarkup(tagName, (0, _mobiledocKitUtilsDomUtils.getAttributes)(element)));\n }\n\n this._markupsFromElementStyle(element).forEach(function (markup) {\n return markups.push(markup);\n });\n\n return markups;\n }\n }, {\n key: '_isValidMarkupForElement',\n value: function _isValidMarkupForElement(tagName, element) {\n if (_mobiledocKitModelsMarkup.VALID_MARKUP_TAGNAMES.indexOf(tagName) === -1) {\n return false;\n } else if (tagName === 'b') {\n // google docs add a that should not\n // create a \"b\" markup\n return element.style.fontWeight !== 'normal';\n }\n return true;\n }\n }, {\n key: '_markupsFromElementStyle',\n value: function _markupsFromElementStyle(element) {\n var builder = this.builder;\n\n var markups = [];\n var _element$style = element.style;\n var fontStyle = _element$style.fontStyle;\n var fontWeight = _element$style.fontWeight;\n\n if (fontStyle === 'italic') {\n markups.push(builder.createMarkup('em'));\n }\n if (fontWeight === 'bold' || fontWeight === '700') {\n markups.push(builder.createMarkup('strong'));\n }\n return markups;\n }\n }, {\n key: '_createMarker',\n value: function _createMarker() {\n var state = this.state;\n\n var text = (0, _mobiledocKitParsersDom.transformHTMLText)(state.text);\n var marker = this.builder.createMarker(text, state.markups);\n state.section.markers.append(marker);\n state.text = '';\n }\n }, {\n key: '_getSectionDetails',\n value: function _getSectionDetails(element) {\n var sectionType = undefined,\n tagName = undefined,\n inferredTagName = false;\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n inferredTagName = true;\n } else {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_ITEM_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n } else {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n inferredTagName = true;\n }\n }\n\n return { sectionType: sectionType, tagName: tagName, inferredTagName: inferredTagName };\n }\n }, {\n key: '_createSectionFromElement',\n value: function _createSectionFromElement(element) {\n var builder = this.builder;\n\n var section = undefined;\n\n var _getSectionDetails2 = this._getSectionDetails(element);\n\n var tagName = _getSectionDetails2.tagName;\n var sectionType = _getSectionDetails2.sectionType;\n var inferredTagName = _getSectionDetails2.inferredTagName;\n\n switch (sectionType) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n section = builder.createListSection(tagName);\n break;\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n section = builder.createListItem();\n break;\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = builder.createMarkupSection(tagName);\n section._inferredTagName = inferredTagName;\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot parse section from element', false);\n }\n\n return section;\n }\n }, {\n key: '_isSkippable',\n value: function _isSkippable(element) {\n return (0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) || element.nodeType === _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT && (0, _mobiledocKitUtilsArrayUtils.contains)(SKIPPABLE_ELEMENT_TAG_NAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName));\n }\n }]);\n\n return SectionParser;\n })();\n\n exports['default'] = SectionParser;\n});","define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup-section'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkupSection) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var UL_LI_REGEX = /^\\* (.*)$/;\n var OL_LI_REGEX = /^\\d\\.? (.*)$/;\n var CR = '\\r';\n var LF = '\\n';\n var CR_REGEX = new RegExp(CR, 'g');\n var CR_LF_REGEX = new RegExp(CR + LF, 'g');\n\n var SECTION_BREAK = LF;\n\n exports.SECTION_BREAK = SECTION_BREAK;\n function normalizeLineEndings(text) {\n return text.replace(CR_LF_REGEX, LF).replace(CR_REGEX, LF);\n }\n\n var TextParser = (function () {\n function TextParser(builder, options) {\n _classCallCheck(this, TextParser);\n\n this.builder = builder;\n this.options = options;\n\n this.post = this.builder.createPost();\n this.prevSection = null;\n }\n\n /**\n * @param {String} text to parse\n * @return {Post} a post abstract\n */\n\n _createClass(TextParser, [{\n key: 'parse',\n value: function parse(text) {\n var _this = this;\n\n text = normalizeLineEndings(text);\n text.split(SECTION_BREAK).forEach(function (text) {\n var section = _this._parseSection(text);\n _this._appendSection(section);\n });\n\n return this.post;\n }\n }, {\n key: '_parseSection',\n value: function _parseSection(text) {\n var tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME,\n type = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n section = undefined;\n\n if (UL_LI_REGEX.test(text)) {\n tagName = 'ul';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(UL_LI_REGEX)[1];\n } else if (OL_LI_REGEX.test(text)) {\n tagName = 'ol';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(OL_LI_REGEX)[1];\n }\n\n var markers = [this.builder.createMarker(text)];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n {\n var item = this.builder.createListItem(markers);\n var list = this.builder.createListSection(tagName, [item]);\n section = list;\n break;\n }\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = this.builder.createMarkupSection(tagName, markers);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown type encountered ' + type, false);\n }\n\n return section;\n }\n }, {\n key: '_appendSection',\n value: function _appendSection(section) {\n var _this2 = this;\n\n var isSameListSection = section.isListSection && this.prevSection && this.prevSection.isListSection && this.prevSection.tagName === section.tagName;\n\n if (isSameListSection) {\n section.items.forEach(function (item) {\n _this2.prevSection.items.append(item.clone());\n });\n } else {\n this.post.sections.insertAfter(section, this.prevSection);\n this.prevSection = section;\n }\n }\n }]);\n\n return TextParser;\n })();\n\n exports['default'] = TextParser;\n});","define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/card-node', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/atom-node', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitModelsCardNode, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsAtomNode, _mobiledocKitModelsTypes, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitModelsMarkupSection, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCharacters) {\n 'use strict';\n\n var _destroyHooks;\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CARD_ELEMENT_CLASS_NAME = '__mobiledoc-card';\n exports.CARD_ELEMENT_CLASS_NAME = CARD_ELEMENT_CLASS_NAME;\n var NO_BREAK_SPACE = ' ';\n exports.NO_BREAK_SPACE = NO_BREAK_SPACE;\n var TAB_CHARACTER = ' ';\n exports.TAB_CHARACTER = TAB_CHARACTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n var ZWNJ = '‌';\n exports.ZWNJ = ZWNJ;\n var ATOM_CLASS_NAME = '-mobiledoc-kit__atom';\n exports.ATOM_CLASS_NAME = ATOM_CLASS_NAME;\n var EDITOR_HAS_NO_CONTENT_CLASS_NAME = '__has-no-content';\n exports.EDITOR_HAS_NO_CONTENT_CLASS_NAME = EDITOR_HAS_NO_CONTENT_CLASS_NAME;\n var EDITOR_ELEMENT_CLASS_NAME = '__mobiledoc-editor';\n\n exports.EDITOR_ELEMENT_CLASS_NAME = EDITOR_ELEMENT_CLASS_NAME;\n function createElementFromMarkup(doc, markup) {\n var element = doc.createElement(markup.tagName);\n Object.keys(markup.attributes).forEach(function (k) {\n element.setAttribute(k, markup.attributes[k]);\n });\n return element;\n }\n\n var TWO_SPACES = '' + SPACE + SPACE;\n var SPACE_AND_NO_BREAK = '' + SPACE + NO_BREAK_SPACE;\n var SPACES_REGEX = new RegExp(TWO_SPACES, 'g');\n var TAB_REGEX = new RegExp(_mobiledocKitUtilsCharacters.TAB, 'g');\n var endsWithSpace = function endsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.endsWith)(text, SPACE);\n };\n var startsWithSpace = function startsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.startsWith)(text, SPACE);\n };\n\n // FIXME: This can be done more efficiently with a single pass\n // building a correct string based on the original.\n function renderHTMLText(marker) {\n var text = marker.value;\n text = text.replace(SPACES_REGEX, SPACE_AND_NO_BREAK).replace(TAB_REGEX, TAB_CHARACTER);\n\n // If the first marker has a leading space or the last marker has a\n // trailing space, the browser will collapse the space when we position\n // the cursor.\n // See https://github.com/bustle/mobiledoc-kit/issues/68\n // and https://github.com/bustle/mobiledoc-kit/issues/75\n if (marker.isMarker && endsWithSpace(text) && !marker.next) {\n text = text.substr(0, text.length - 1) + NO_BREAK_SPACE;\n }\n if (marker.isMarker && startsWithSpace(text) && (!marker.prev || marker.prev.isMarker && endsWithSpace(marker.prev.value))) {\n text = NO_BREAK_SPACE + text.substr(1);\n }\n return text;\n }\n\n // ascends from element upward, returning the last parent node that is not\n // parentElement\n function penultimateParentOf(element, parentElement) {\n while (parentElement && element.parentNode !== parentElement && element.parentNode !== document.body // ensure the while loop stops\n ) {\n element = element.parentNode;\n }\n return element;\n }\n\n function setSectionAttributesOnElement(section, element) {\n section.eachAttribute(function (key, value) {\n element.setAttribute(key, value);\n });\n }\n\n function renderMarkupSection(section) {\n var element = undefined;\n if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) {\n element = document.createElement(section.tagName);\n } else {\n element = document.createElement('div');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName);\n }\n\n setSectionAttributesOnElement(section, element);\n\n return element;\n }\n\n function renderListSection(section) {\n var element = document.createElement(section.tagName);\n\n setSectionAttributesOnElement(section, element);\n\n return element;\n }\n\n function renderListItem() {\n return document.createElement('li');\n }\n\n function renderCursorPlaceholder() {\n return document.createElement('br');\n }\n\n function renderInlineCursorPlaceholder() {\n return document.createTextNode(ZWNJ);\n }\n\n function renderCard() {\n var wrapper = document.createElement('div');\n var cardElement = document.createElement('div');\n cardElement.contentEditable = false;\n (0, _mobiledocKitUtilsDomUtils.addClassName)(cardElement, CARD_ELEMENT_CLASS_NAME);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n wrapper.appendChild(cardElement);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n return { wrapper: wrapper, cardElement: cardElement };\n }\n\n /**\n * Wrap the element in all of the opened markups\n * @return {DOMElement} the wrapped element\n * @private\n */\n function wrapElement(element, openedMarkups) {\n var wrappedElement = element;\n\n for (var i = openedMarkups.length - 1; i >= 0; i--) {\n var markup = openedMarkups[i];\n var openedElement = createElementFromMarkup(document, markup);\n openedElement.appendChild(wrappedElement);\n wrappedElement = openedElement;\n }\n\n return wrappedElement;\n }\n\n // Attach the element to its parent element at the correct position based on the\n // previousRenderNode\n function attachElementToParent(element, parentElement) {\n var previousRenderNode = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n if (previousRenderNode) {\n var previousSibling = previousRenderNode.element;\n var previousSiblingPenultimate = penultimateParentOf(previousSibling, parentElement);\n parentElement.insertBefore(element, previousSiblingPenultimate.nextSibling);\n } else {\n parentElement.insertBefore(element, parentElement.firstChild);\n }\n }\n\n function renderAtom(atom, element, previousRenderNode) {\n var atomElement = document.createElement('span');\n atomElement.contentEditable = false;\n\n var wrapper = document.createElement('span');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(wrapper, ATOM_CLASS_NAME);\n var headTextNode = renderInlineCursorPlaceholder();\n var tailTextNode = renderInlineCursorPlaceholder();\n\n wrapper.appendChild(headTextNode);\n wrapper.appendChild(atomElement);\n wrapper.appendChild(tailTextNode);\n\n var wrappedElement = wrapElement(wrapper, atom.openedMarkups);\n attachElementToParent(wrappedElement, element, previousRenderNode);\n\n return {\n markupElement: wrappedElement,\n wrapper: wrapper,\n atomElement: atomElement,\n headTextNode: headTextNode,\n tailTextNode: tailTextNode\n };\n }\n\n function getNextMarkerElement(renderNode) {\n var element = renderNode.element.parentNode;\n var marker = renderNode.postNode;\n var closedCount = marker.closedMarkups.length;\n\n while (closedCount--) {\n element = element.parentNode;\n }\n return element;\n }\n\n /**\n * Render the marker\n * @param {Marker} marker the marker to render\n * @param {DOMNode} element the element to attach the rendered marker to\n * @param {RenderNode} [previousRenderNode] The render node before this one, which\n * affects the determination of where to insert this rendered marker.\n * @return {Object} With properties `element` and `markupElement`.\n * The element (textNode) that has the text for\n * this marker, and the outermost rendered element. If the marker has no\n * markups, element and markupElement will be the same textNode\n * @private\n */\n function renderMarker(marker, parentElement, previousRenderNode) {\n var text = renderHTMLText(marker);\n\n var element = document.createTextNode(text);\n var markupElement = wrapElement(element, marker.openedMarkups);\n attachElementToParent(markupElement, parentElement, previousRenderNode);\n\n return { element: element, markupElement: markupElement };\n }\n\n // Attach the render node's element to the DOM,\n // replacing the originalElement if it exists\n function attachRenderNodeElementToDOM(renderNode) {\n var originalElement = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n var element = renderNode.element;\n var hasRendered = !!originalElement;\n\n if (hasRendered) {\n var parentElement = renderNode.parent.element;\n parentElement.replaceChild(element, originalElement);\n } else {\n var parentElement = undefined,\n nextSiblingElement = undefined;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n parentElement = previousElement.parentNode;\n nextSiblingElement = previousElement.nextSibling;\n } else {\n parentElement = renderNode.parent.element;\n nextSiblingElement = parentElement.firstChild;\n }\n parentElement.insertBefore(element, nextSiblingElement);\n }\n }\n\n function removeRenderNodeSectionFromParent(renderNode, section) {\n var parent = renderNode.parent.postNode;\n parent.sections.remove(section);\n }\n\n function removeRenderNodeElementFromParent(renderNode) {\n if (renderNode.element && renderNode.element.parentNode) {\n renderNode.element.parentNode.removeChild(renderNode.element);\n }\n }\n\n function validateCards() {\n var cards = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(cards, function (card) {\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define type \"dom\", has: \"' + card.type + '\"', card.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define `render` method', !!card.render);\n });\n return cards;\n }\n\n function validateAtoms() {\n var atoms = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(atoms, function (atom) {\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define type \"dom\", has: \"' + atom.type + '\"', atom.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define `render` method', !!atom.render);\n });\n return atoms;\n }\n\n var Visitor = (function () {\n function Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Visitor);\n\n this.editor = editor;\n this.cards = validateCards(cards);\n this.atoms = validateAtoms(atoms);\n this.unknownCardHandler = unknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler;\n this.options = options;\n }\n\n _createClass(Visitor, [{\n key: '_findCard',\n value: function _findCard(cardName) {\n var card = (0, _mobiledocKitUtilsArrayUtils.detect)(this.cards, function (card) {\n return card.name === cardName;\n });\n return card || this._createUnknownCard(cardName);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(cardName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown card \"' + cardName + '\" found, but no unknownCardHandler is defined', !!this.unknownCardHandler);\n\n return {\n name: cardName,\n type: 'dom',\n render: this.unknownCardHandler,\n edit: this.unknownCardHandler\n };\n }\n }, {\n key: '_findAtom',\n value: function _findAtom(atomName) {\n var atom = (0, _mobiledocKitUtilsArrayUtils.detect)(this.atoms, function (atom) {\n return atom.name === atomName;\n });\n return atom || this._createUnknownAtom(atomName);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(atomName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown atom \"' + atomName + '\" found, but no unknownAtomHandler is defined', !!this.unknownAtomHandler);\n\n return {\n name: atomName,\n type: 'dom',\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(renderNode, post, visit) {\n if (!renderNode.element) {\n renderNode.element = document.createElement('div');\n }\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_ELEMENT_CLASS_NAME);\n if (post.hasContent) {\n (0, _mobiledocKitUtilsDomUtils.removeClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n } else {\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n }\n visit(renderNode, post.sections);\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n // Always rerender the section -- its tag name or attributes may have changed.\n // TODO make this smarter, only rerendering and replacing the element when necessary\n renderNode.element = renderMarkupSection(section);\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n if (section.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, section.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n renderNode.element = renderListSection(section);\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var visitAll = true;\n visit(renderNode, section.items, visitAll);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(renderNode, item, visit) {\n // FIXME do we need to do anything special for rerenders?\n renderNode.element = renderListItem();\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, null);\n\n if (item.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, item.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKER_TYPE,\n value: function value(renderNode, marker) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var _renderMarker = renderMarker(marker, parentElement, renderNode.prev);\n\n var element = _renderMarker.element;\n var markupElement = _renderMarker.markupElement;\n\n renderNode.element = element;\n renderNode.markupElement = markupElement;\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(renderNode, section) {\n if (renderNode.element) {\n if (renderNode.element.src !== section.src) {\n renderNode.element.src = section.src;\n }\n } else {\n var element = document.createElement('img');\n element.src = section.src;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n var nextElement = previousElement.nextSibling;\n if (nextElement) {\n nextElement.parentNode.insertBefore(element, nextElement);\n }\n }\n if (!element.parentNode) {\n renderNode.parent.element.appendChild(element);\n }\n renderNode.element = element;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(renderNode, section) {\n var originalElement = renderNode.element;\n var editor = this.editor;\n var options = this.options;\n\n var card = this._findCard(section.name);\n\n var _renderCard = renderCard();\n\n var wrapper = _renderCard.wrapper;\n var cardElement = _renderCard.cardElement;\n\n renderNode.element = wrapper;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var cardNode = new _mobiledocKitModelsCardNode['default'](editor, card, section, cardElement, options);\n renderNode.cardNode = cardNode;\n\n var initialMode = section._initialMode;\n cardNode[initialMode]();\n }\n }, {\n key: _mobiledocKitModelsTypes.ATOM_TYPE,\n value: function value(renderNode, atomModel) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var editor = this.editor;\n var options = this.options;\n\n var _renderAtom = renderAtom(atomModel, parentElement, renderNode.prev);\n\n var wrapper = _renderAtom.wrapper;\n var markupElement = _renderAtom.markupElement;\n var atomElement = _renderAtom.atomElement;\n var headTextNode = _renderAtom.headTextNode;\n var tailTextNode = _renderAtom.tailTextNode;\n\n var atom = this._findAtom(atomModel.name);\n\n var atomNode = renderNode.atomNode;\n if (!atomNode) {\n // create new AtomNode\n atomNode = new _mobiledocKitModelsAtomNode['default'](editor, atom, atomModel, atomElement, options);\n } else {\n // retarget atomNode to new atom element\n atomNode.element = atomElement;\n }\n\n atomNode.render();\n\n renderNode.atomNode = atomNode;\n renderNode.element = wrapper;\n renderNode.headTextNode = headTextNode;\n renderNode.tailTextNode = tailTextNode;\n renderNode.markupElement = markupElement;\n }\n }]);\n\n return Visitor;\n })();\n\n var destroyHooks = (_destroyHooks = {}, _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.POST_TYPE, function () /*renderNode, post*/{\n (0, _mobiledocKitUtilsAssert['default'])('post destruction is not supported by the renderer', false);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (renderNode, li) {\n removeRenderNodeSectionFromParent(renderNode, li);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKER_TYPE, function (renderNode, marker) {\n // FIXME before we render marker, should delete previous renderNode's element\n // and up until the next marker element\n\n // If an atom throws during render we may end up later destroying a renderNode\n // that has not rendered yet, so exit early here if so.\n if (!renderNode.isRendered) {\n return;\n }\n var markupElement = renderNode.markupElement;\n\n if (marker.section) {\n marker.section.markers.remove(marker);\n }\n\n if (markupElement.parentNode) {\n // if no parentNode, the browser already removed this element\n markupElement.parentNode.removeChild(markupElement);\n }\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.CARD_TYPE, function (renderNode, section) {\n if (renderNode.cardNode) {\n renderNode.cardNode.teardown();\n }\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.ATOM_TYPE, function (renderNode, atom) {\n if (renderNode.atomNode) {\n renderNode.atomNode.teardown();\n }\n\n // an atom is a kind of marker so just call its destroy hook vs copying here\n destroyHooks[_mobiledocKitModelsTypes.MARKER_TYPE](renderNode, atom);\n }), _destroyHooks);\n\n // removes children from parentNode (a RenderNode) that are scheduled for removal\n function removeDestroyedChildren(parentNode) {\n var forceRemoval = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n var child = parentNode.childNodes.head;\n var nextChild = undefined,\n method = undefined;\n while (child) {\n nextChild = child.next;\n if (child.isRemoved || forceRemoval) {\n removeDestroyedChildren(child, true);\n method = child.postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('editor-dom cannot destroy \"' + method + '\"', !!destroyHooks[method]);\n destroyHooks[method](child, child.postNode);\n parentNode.childNodes.remove(child);\n }\n child = nextChild;\n }\n }\n\n // Find an existing render node for the given postNode, or\n // create one, insert it into the tree, and return it\n function lookupNode(renderTree, parentNode, postNode, previousNode) {\n if (postNode.renderNode) {\n return postNode.renderNode;\n } else {\n var renderNode = renderTree.buildRenderNode(postNode);\n parentNode.childNodes.insertAfter(renderNode, previousNode);\n return renderNode;\n }\n }\n\n var Renderer = (function () {\n function Renderer(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Renderer);\n\n this.editor = editor;\n this.visitor = new Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options);\n this.nodes = [];\n this.hasRendered = false;\n }\n\n _createClass(Renderer, [{\n key: 'destroy',\n value: function destroy() {\n if (!this.hasRendered) {\n return;\n }\n var renderNode = this.renderTree.rootNode;\n var force = true;\n removeDestroyedChildren(renderNode, force);\n }\n }, {\n key: 'visit',\n value: function visit(renderTree, parentNode, postNodes) {\n var _this = this;\n\n var visitAll = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];\n\n var previousNode = undefined;\n postNodes.forEach(function (postNode) {\n var node = lookupNode(renderTree, parentNode, postNode, previousNode);\n if (node.isDirty || visitAll) {\n _this.nodes.push(node);\n }\n previousNode = node;\n });\n }\n }, {\n key: 'render',\n value: function render(renderTree) {\n var _this2 = this;\n\n this.hasRendered = true;\n this.renderTree = renderTree;\n var renderNode = renderTree.rootNode;\n var method = undefined,\n postNode = undefined;\n\n while (renderNode) {\n removeDestroyedChildren(renderNode);\n postNode = renderNode.postNode;\n\n method = postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]);\n this.visitor[method](renderNode, postNode, function () {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return _this2.visit.apply(_this2, [renderTree].concat(args));\n });\n renderNode.markClean();\n renderNode = this.nodes.shift();\n }\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-kit/renderers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.2.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, name, payload]);\n },\n openPost: function openPost() {\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n sections: [this.markerTypes, this.sections]\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.1';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.2';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName, attributes) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]);\n },\n openListSection: function openListSection(tagName, attributes) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n exports['default'] = {\n render: function render(post, version) {\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc02['default'].render(post);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc03['default'].render(post);\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc031['default'].render(post);\n case undefined:\n case null:\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc032['default'].render(post);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false);\n }\n }\n };\n});","define(\"mobiledoc-kit/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function detect(enumerable, callback) {\n if (enumerable.detect) {\n return enumerable.detect(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return enumerable[i];\n }\n }\n }\n }\n\n function any(enumerable, callback) {\n if (enumerable.any) {\n return enumerable.any(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return true;\n }\n }\n\n return false;\n }\n\n function every(enumerable, callback) {\n if (enumerable.every) {\n return enumerable.every(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (!callback(enumerable[i])) {\n return false;\n }\n }\n return true;\n }\n\n function toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n }\n\n /**\n * Useful for array-like things that aren't\n * actually arrays, like NodeList\n * @private\n */\n function forEach(enumerable, callback) {\n if (enumerable.forEach) {\n enumerable.forEach(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n callback(enumerable[i], i);\n }\n }\n }\n\n function filter(enumerable, conditionFn) {\n var filtered = [];\n forEach(enumerable, function (i) {\n if (conditionFn(i)) {\n filtered.push(i);\n }\n });\n return filtered;\n }\n\n /**\n * @return {Integer} the number of items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItemLength(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return offset;\n }\n\n /**\n * @return {Array} the items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItems(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return listA.slice(0, offset);\n }\n\n // return new array without falsy items like ruby's `compact`\n function compact(enumerable) {\n return filter(enumerable, function (i) {\n return !!i;\n });\n }\n\n function reduce(enumerable, callback, initialValue) {\n var previousValue = initialValue;\n forEach(enumerable, function (val, index) {\n previousValue = callback(previousValue, val, index);\n });\n return previousValue;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n function kvArrayToObject(array) {\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n\n // check shallow equality of two non-nested arrays\n function isArrayEqual(arr1, arr2) {\n var l1 = arr1.length,\n l2 = arr2.length;\n if (l1 !== l2) {\n return false;\n }\n\n for (var i = 0; i < l1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n return true;\n }\n\n // return an object with only the valid keys\n function filterObject(object) {\n var validKeys = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var result = {};\n forEach(filter(Object.keys(object), function (key) {\n return validKeys.indexOf(key) !== -1;\n }), function (key) {\n return result[key] = object[key];\n });\n return result;\n }\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function values(object) {\n return Object.keys(object).map(function (key) {\n return object[key];\n });\n }\n\n exports.detect = detect;\n exports.forEach = forEach;\n exports.any = any;\n exports.every = every;\n exports.filter = filter;\n exports.commonItemLength = commonItemLength;\n exports.commonItems = commonItems;\n exports.compact = compact;\n exports.reduce = reduce;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n exports.kvArrayToObject = kvArrayToObject;\n exports.isArrayEqual = isArrayEqual;\n exports.toArray = toArray;\n exports.filterObject = filterObject;\n exports.contains = contains;\n exports.values = values;\n});","define('mobiledoc-kit/utils/assert', ['exports', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n exports['default'] = function (message, conditional) {\n if (!conditional) {\n throw new _mobiledocKitUtilsMobiledocError['default'](message);\n }\n };\n});","define('mobiledoc-kit/utils/browser', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n isMac: function isMac() {\n return typeof window !== 'undefined' && window.navigator && /Mac/.test(window.navigator.platform);\n },\n isWin: function isWin() {\n return typeof window !== 'undefined' && window.navigator && /Win/.test(window.navigator.platform);\n }\n };\n});","define('mobiledoc-kit/utils/characters', ['exports'], function (exports) {\n 'use strict';\n\n var TAB = '\\t';\n exports.TAB = TAB;\n var ENTER = '\\n';\n exports.ENTER = ENTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n});","define('mobiledoc-kit/utils/compiler', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports.visit = visit;\n exports.compile = compile;\n exports.visitArray = visitArray;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function visit(visitor, node, opcodes) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit unknown type ' + method, !!visitor[method]);\n visitor[method](node, opcodes);\n }\n\n function compile(compiler, opcodes) {\n for (var i = 0, l = opcodes.length; i < l; i++) {\n var _opcodes$i = _toArray(opcodes[i]);\n\n var method = _opcodes$i[0];\n\n var params = _opcodes$i.slice(1);\n\n var _length = params.length;\n if (_length === 0) {\n compiler[method].call(compiler);\n } else if (_length === 1) {\n compiler[method].call(compiler, params[0]);\n } else if (_length === 2) {\n compiler[method].call(compiler, params[0], params[1]);\n } else {\n compiler[method].apply(compiler, params);\n }\n }\n }\n\n function visitArray(visitor, nodes, opcodes) {\n if (!nodes || nodes.length === 0) {\n return;\n }\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n visit(visitor, node, opcodes);\n });\n }\n});","define(\"mobiledoc-kit/utils/copy\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function shallowCopyObject(object) {\n var copy = {};\n Object.keys(object).forEach(function (key) {\n copy[key] = object[key];\n });\n return copy;\n }\n\n exports.shallowCopyObject = shallowCopyObject;\n});","define('mobiledoc-kit/utils/cursor', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/key'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKey) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n\n var Cursor = (function () {\n function Cursor(editor) {\n _classCallCheck(this, Cursor);\n\n this.editor = editor;\n this.renderTree = editor._renderTree;\n this.post = editor.post;\n }\n\n _createClass(Cursor, [{\n key: 'clearSelection',\n value: function clearSelection() {\n (0, _mobiledocKitUtilsSelectionUtils.clearSelection)();\n }\n\n /**\n * @return {Boolean} true when there is either a collapsed cursor in the\n * editor's element or a selection that is contained in the editor's element\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.editor.hasRendered && (this._hasCollapsedSelection() || this._hasSelection());\n }\n }, {\n key: 'hasSelection',\n value: function hasSelection() {\n return this.editor.hasRendered && this._hasSelection();\n }\n\n /**\n * @return {Boolean} Can the cursor be on this element?\n */\n }, {\n key: 'isAddressable',\n value: function isAddressable(element) {\n var renderTree = this.renderTree;\n\n var renderNode = renderTree.findRenderNodeFromElement(element);\n if (renderNode && renderNode.postNode.isCardSection) {\n var renderedElement = renderNode.element;\n\n // card sections have addressable text nodes containing ‌\n // as their first and last child\n if (element !== renderedElement && element !== renderedElement.firstChild && element !== renderedElement.lastChild) {\n return false;\n }\n }\n\n return !!renderNode;\n }\n\n /*\n * @return {Range} Cursor#Range object\n */\n }, {\n key: '_findNodeForPosition',\n value: function _findNodeForPosition(position) {\n var section = position.section;\n\n var node = undefined,\n offset = undefined;\n if (section.isCardSection) {\n offset = 0;\n if (position.offset === 0) {\n node = section.renderNode.element.firstChild;\n } else {\n node = section.renderNode.element.lastChild;\n }\n } else if (section.isBlank) {\n node = section.renderNode.cursorElement;\n offset = 0;\n } else {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n if (marker.isAtom) {\n if (offsetInMarker > 0) {\n // FIXME -- if there is a next marker, focus on it?\n offset = 0;\n node = marker.renderNode.tailTextNode;\n } else {\n offset = 0;\n node = marker.renderNode.headTextNode;\n }\n } else {\n node = marker.renderNode.element;\n offset = offsetInMarker;\n }\n }\n\n return { node: node, offset: offset };\n }\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n if (range.isBlank) {\n this.clearSelection();\n return;\n }\n\n var head = range.head;\n var tail = range.tail;\n var direction = range.direction;\n\n var _findNodeForPosition2 = this._findNodeForPosition(head);\n\n var headNode = _findNodeForPosition2.node;\n var headOffset = _findNodeForPosition2.offset;\n\n var _findNodeForPosition3 = this._findNodeForPosition(tail);\n\n var tailNode = _findNodeForPosition3.node;\n var tailOffset = _findNodeForPosition3.offset;\n\n this._moveToNode(headNode, headOffset, tailNode, tailOffset, direction);\n\n // Firefox sometimes doesn't keep focus in the editor after adding a card\n this.editor._ensureFocus();\n }\n }, {\n key: 'selectedText',\n value: function selectedText() {\n // FIXME remove this\n return this.selection.toString();\n }\n\n /**\n * @param {textNode} node\n * @param {integer} offset\n * @param {textNode} endNode\n * @param {integer} endOffset\n * @param {integer} direction forward or backward, default forward\n * @private\n */\n }, {\n key: '_moveToNode',\n value: function _moveToNode(node, offset, endNode, endOffset) {\n var direction = arguments.length <= 4 || arguments[4] === undefined ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : arguments[4];\n\n this.clearSelection();\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n var _ref = [endNode, endOffset, node, offset];\n node = _ref[0];\n offset = _ref[1];\n endNode = _ref[2];\n endOffset = _ref[3];\n }\n\n var range = document.createRange();\n range.setStart(node, offset);\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD && !!this.selection.extend) {\n this.selection.addRange(range);\n this.selection.extend(endNode, endOffset);\n } else {\n range.setEnd(endNode, endOffset);\n this.selection.addRange(range);\n }\n }\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var element = this.editor.element;\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange || _selectionRange.collapsed) {\n return false;\n }\n\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode) && (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.focusNode);\n }\n }, {\n key: '_hasCollapsedSelection',\n value: function _hasCollapsedSelection() {\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange) {\n return false;\n }\n\n var element = this.editor.element;\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode);\n }\n }, {\n key: 'offsets',\n get: function get() {\n if (!this.hasCursor()) {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n\n var selection = this.selection;\n var renderTree = this.renderTree;\n\n var parentNode = this.editor.element;\n selection = (0, _mobiledocKitUtilsSelectionUtils.constrainSelectionTo)(selection, parentNode);\n\n var _comparePosition = (0, _mobiledocKitUtilsSelectionUtils.comparePosition)(selection);\n\n var headNode = _comparePosition.headNode;\n var headOffset = _comparePosition.headOffset;\n var tailNode = _comparePosition.tailNode;\n var tailOffset = _comparePosition.tailOffset;\n var direction = _comparePosition.direction;\n\n var headPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, headNode, headOffset);\n var tailPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, tailNode, tailOffset);\n\n return new _mobiledocKitUtilsCursorRange['default'](headPosition, tailPosition, direction);\n }\n }, {\n key: 'selection',\n get: function get() {\n return window.getSelection();\n }\n }, {\n key: '_selectionRange',\n get: function get() {\n var selection = this.selection;\n\n if (selection.rangeCount === 0) {\n return null;\n }\n return selection.getRangeAt(0);\n }\n }]);\n\n return Cursor;\n })();\n\n exports['default'] = Cursor;\n});","define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitModelsMarker, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsKey, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n // generated via http://xregexp.com/ to cover chars that \\w misses\n // (new XRegExp('\\\\p{Alphabetic}|[0-9]|_|:')).toString()\n var WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]|[0-9]|_|:/;\n\n function findParentSectionFromNode(renderTree, node) {\n var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) {\n return renderNode.postNode.isSection;\n });\n\n return renderNode && renderNode.postNode;\n }\n\n function findOffsetInMarkerable(markerable, node, offset) {\n var offsetInSection = 0;\n var marker = markerable.markers.head;\n while (marker) {\n var markerNode = marker.renderNode.element;\n if (markerNode === node) {\n return offsetInSection + offset;\n } else if (marker.isAtom) {\n if (marker.renderNode.headTextNode === node) {\n return offsetInSection;\n } else if (marker.renderNode.tailTextNode === node) {\n return offsetInSection + 1;\n }\n }\n\n offsetInSection += marker.length;\n marker = marker.next;\n }\n\n return offsetInSection;\n }\n\n function findOffsetInSection(section, node, offset) {\n if (section.isMarkerable) {\n return findOffsetInMarkerable(section, node, offset);\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('findOffsetInSection must be called with markerable or card section', section.isCardSection);\n\n var wrapperNode = section.renderNode.element;\n var endTextNode = wrapperNode.lastChild;\n if (node === endTextNode) {\n return 1;\n }\n return 0;\n }\n }\n\n var Position = undefined,\n BlankPosition = undefined;\n\n Position = (function () {\n /**\n * A position is a logical location (zero-width, or \"collapsed\") in a post,\n * typically between two characters in a section.\n * Two positions (a head and a tail) make up a {@link Range}.\n * @constructor\n */\n\n function Position(section) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var isBlank = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n _classCallCheck(this, Position);\n\n if (!isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Position must have a section that is addressable by the cursor', section && section.isLeafSection);\n (0, _mobiledocKitUtilsAssert['default'])('Position must have numeric offset', typeof offset === 'number');\n }\n\n this.section = section;\n this.offset = offset;\n this.isBlank = isBlank;\n }\n\n /**\n * @param {integer} x x-position in current viewport\n * @param {integer} y y-position in current viewport\n * @param {Editor} editor\n * @return {Position|null}\n */\n\n _createClass(Position, [{\n key: 'toRange',\n\n /**\n * Returns a range from this position to the given tail. If no explicit\n * tail is given this returns a collapsed range focused on this position.\n * @param {Position} [tail=this] The ending position\n * @return {Range}\n * @public\n */\n value: function toRange() {\n var tail = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0];\n var direction = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n return new _mobiledocKitUtilsCursorRange['default'](this, tail, direction);\n }\n }, {\n key: 'markerIn',\n\n /**\n * Returns the marker in `direction` from this position.\n * If the position is in the middle of a marker, the direction is irrelevant.\n * Otherwise, if the position is at a boundary between two markers, returns the\n * marker to the left if `direction` === BACKWARD and the marker to the right\n * if `direction` === FORWARD (assuming left-to-right text direction).\n * @param {Direction}\n * @return {Marker|undefined}\n */\n value: function markerIn(direction) {\n if (!this.isMarkerable) {\n return;\n }\n\n var marker = this.marker;\n var offsetInMarker = this.offsetInMarker;\n\n if (!marker) {\n return;\n }\n\n if (offsetInMarker > 0 && offsetInMarker < marker.length) {\n return marker;\n } else if (offsetInMarker === 0) {\n return direction === BACKWARD ? marker : marker.prev;\n } else if (offsetInMarker === marker.length) {\n return direction === FORWARD ? marker.next : marker;\n }\n }\n }, {\n key: 'isEqual',\n value: function isEqual(position) {\n return this.section === position.section && this.offset === position.offset;\n }\n\n /**\n * @return {Boolean} If this position is at the head of the post\n */\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return this.move(BACKWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the tail of the post\n */\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return this.move(FORWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the head of its section\n */\n }, {\n key: 'isHead',\n value: function isHead() {\n return this.isEqual(this.section.headPosition());\n }\n\n /**\n * @return {Boolean} If this position is at the tail of its section\n */\n }, {\n key: 'isTail',\n value: function isTail() {\n return this.isEqual(this.section.tailPosition());\n }\n\n /**\n * Move the position 1 unit in `direction`.\n *\n * @param {Number} units to move. > 0 moves right, < 0 moves left\n * @return {Position} Return a new position one unit in the given\n * direction. If the position is moving left and at the beginning of the post,\n * the same position will be returned. Same if the position is moving right and\n * at the end of the post.\n */\n }, {\n key: 'move',\n value: function move(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Position#move', typeof units === 'number');\n\n if (units < 0) {\n return this.moveLeft().move(++units);\n } else if (units > 0) {\n return this.moveRight().move(--units);\n } else {\n return this;\n }\n }\n\n /**\n * @param {Number} direction (FORWARD or BACKWARD)\n * @return {Position} The result of moving 1 \"word\" unit in `direction`\n */\n }, {\n key: 'moveWord',\n value: function moveWord(direction) {\n var isPostBoundary = direction === BACKWARD ? this.isHeadOfPost() : this.isTailOfPost();\n if (isPostBoundary) {\n return this;\n }\n\n if (!this.isMarkerable) {\n return this.move(direction);\n }\n\n var pos = this;\n\n // Helper fn to check if the pos is at the `dir` boundary of its section\n var isBoundary = function isBoundary(pos, dir) {\n return dir === BACKWARD ? pos.isHead() : pos.isTail();\n };\n // Get the char at this position (looking forward/right)\n var getChar = function getChar(pos) {\n var marker = pos.marker;\n var offsetInMarker = pos.offsetInMarker;\n\n return marker.charAt(offsetInMarker);\n };\n // Get the char in `dir` at this position\n var peekChar = function peekChar(pos, dir) {\n return dir === BACKWARD ? getChar(pos.move(BACKWARD)) : getChar(pos);\n };\n // Whether there is an atom in `dir` from this position\n var isAtom = function isAtom(pos, dir) {\n // Special case when position is at end, the marker associated with it is\n // the marker to its left. Normally `pos#marker` is the marker to the right of the pos's offset.\n if (dir === BACKWARD && pos.isTail() && pos.marker.isAtom) {\n return true;\n }\n return dir === BACKWARD ? pos.move(BACKWARD).marker.isAtom : pos.marker.isAtom;\n };\n\n if (isBoundary(pos, direction)) {\n // extend movement into prev/next section\n return pos.move(direction).moveWord(direction);\n }\n\n var seekWord = function seekWord(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && !WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first word char\n while (seekWord(pos)) {\n pos = pos.move(direction);\n }\n\n if (isAtom(pos, direction)) {\n return pos.move(direction);\n }\n\n var seekBoundary = function seekBoundary(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first boundary position\n while (seekBoundary(pos)) {\n pos = pos.move(direction);\n }\n\n return pos;\n }\n\n /**\n * The position to the left of this position.\n * If this position is the post's headPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveLeft',\n value: function moveLeft() {\n if (this.isHead()) {\n var prev = this.section.previousLeafSection();\n return prev ? prev.tailPosition() : this;\n } else {\n var offset = this.offset - 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset);\n if (code >= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[1]) {\n offset = offset - 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n\n /**\n * The position to the right of this position.\n * If this position is the post's tailPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveRight',\n value: function moveRight() {\n if (this.isTail()) {\n var next = this.section.nextLeafSection();\n return next ? next.headPosition() : this;\n } else {\n var offset = this.offset + 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset - 1);\n if (code >= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[1]) {\n offset = offset + 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n var _this = this;\n\n var post = this.section.post;\n var leafSectionIndex = undefined;\n post.walkAllLeafSections(function (section, index) {\n if (section === _this.section) {\n leafSectionIndex = index;\n }\n });\n return leafSectionIndex;\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return this.section && this.section.isMarkerable;\n }\n\n /**\n * Returns the marker at this position, in the backward direction\n * (i.e., the marker to the left of the cursor if the cursor is on a marker boundary and text is left-to-right)\n * @return {Marker|undefined}\n */\n }, {\n key: 'marker',\n get: function get() {\n return this.isMarkerable && this.markerPosition.marker;\n }\n }, {\n key: 'offsetInMarker',\n get: function get() {\n return this.markerPosition.offset;\n }\n }, {\n key: 'markerPosition',\n\n /**\n * @private\n */\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get markerPosition without a section', !!this.section);\n (0, _mobiledocKitUtilsAssert['default'])('cannot get markerPosition of a non-markerable', !!this.section.isMarkerable);\n return this.section.markerPositionAtOffset(this.offset);\n }\n }], [{\n key: 'atPoint',\n value: function atPoint(x, y, editor) {\n var _renderTree = editor._renderTree;\n var rootElement = editor.element;\n\n var elementFromPoint = document.elementFromPoint(x, y);\n if (!(0, _mobiledocKitUtilsDomUtils.containsNode)(rootElement, elementFromPoint)) {\n return;\n }\n\n var _findOffsetInNode = (0, _mobiledocKitUtilsSelectionUtils.findOffsetInNode)(elementFromPoint, { left: x, top: y });\n\n var node = _findOffsetInNode.node;\n var offset = _findOffsetInNode.offset;\n\n return Position.fromNode(_renderTree, node, offset);\n }\n }, {\n key: 'blankPosition',\n value: function blankPosition() {\n return new BlankPosition();\n }\n }, {\n key: 'fromNode',\n value: function fromNode(renderTree, node, offset) {\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n return Position.fromTextNode(renderTree, node, offset);\n } else {\n return Position.fromElementNode(renderTree, node, offset);\n }\n }\n }, {\n key: 'fromTextNode',\n value: function fromTextNode(renderTree, textNode, offsetInNode) {\n var renderNode = renderTree.getElementRenderNode(textNode);\n var section = undefined,\n offsetInSection = undefined;\n\n if (renderNode) {\n var marker = renderNode.postNode;\n section = marker.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for mapped text node \"' + textNode.textContent + '\"', !!section);\n offsetInSection = section.offsetOfMarker(marker, offsetInNode);\n } else {\n // all text nodes should be rendered by markers except:\n // * text nodes inside cards\n // * text nodes created by the browser during text input\n // both of these should have rendered parent sections, though\n section = findParentSectionFromNode(renderTree, textNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for un-mapped text node \"' + textNode.textContent + '\"', !!section);\n\n offsetInSection = findOffsetInSection(section, textNode, offsetInNode);\n }\n\n return new Position(section, offsetInSection);\n }\n }, {\n key: 'fromElementNode',\n value: function fromElementNode(renderTree, elementNode, offset) {\n var position = undefined;\n\n // The browser may change the reported selection to equal the editor's root\n // element if the user clicks an element that is immediately removed,\n // which can happen when clicking to remove a card.\n if (elementNode === renderTree.rootElement) {\n var post = renderTree.rootNode.postNode;\n position = offset === 0 ? post.headPosition() : post.tailPosition();\n } else {\n var section = findParentSectionFromNode(renderTree, elementNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section from element node', !!section);\n\n if (section.isCardSection) {\n // Selections in cards are usually made on a text node\n // containing a ‌ on one side or the other of the card but\n // some scenarios (Firefox) will result in selecting the\n // card's wrapper div. If the offset is 2 we've selected\n // the final zwnj and should consider the cursor at the\n // end of the card (offset 1). Otherwise, the cursor is at\n // the start of the card\n position = offset < 2 ? section.headPosition() : section.tailPosition();\n } else {\n\n // In Firefox it is possible for the cursor to be on an atom's wrapper\n // element. (In Chrome/Safari, the browser corrects this to be on\n // one of the text nodes surrounding the wrapper).\n // This code corrects for when the browser reports the cursor position\n // to be on the wrapper element itself\n var renderNode = renderTree.getElementRenderNode(elementNode);\n var postNode = renderNode && renderNode.postNode;\n if (postNode && postNode.isAtom) {\n var sectionOffset = section.offsetOfMarker(postNode);\n if (offset > 1) {\n // we are on the tail side of the atom\n sectionOffset += postNode.length;\n }\n position = new Position(section, sectionOffset);\n } else if (offset >= elementNode.childNodes.length) {\n\n // This is to deal with how Firefox handles triple-click selections.\n // See https://stackoverflow.com/a/21234837/1269194 for an\n // explanation.\n position = section.tailPosition();\n } else {\n // The offset is 0 if the cursor is on a non-atom-wrapper element node\n // (e.g., a
    tag in a blank markup section)\n position = section.headPosition();\n }\n }\n }\n\n return position;\n }\n }]);\n\n return Position;\n })();\n\n BlankPosition = (function (_Position) {\n _inherits(BlankPosition, _Position);\n\n function BlankPosition() {\n _classCallCheck(this, BlankPosition);\n\n _get(Object.getPrototypeOf(BlankPosition.prototype), 'constructor', this).call(this, null, 0, true);\n }\n\n _createClass(BlankPosition, [{\n key: 'isEqual',\n value: function isEqual(other) {\n return other && other.isBlank;\n }\n }, {\n key: 'toRange',\n value: function toRange() {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return false;\n }\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return false;\n }\n }, {\n key: 'isHead',\n value: function isHead() {\n return false;\n }\n }, {\n key: 'isTail',\n value: function isTail() {\n return false;\n }\n }, {\n key: 'move',\n value: function move() {\n return this;\n }\n }, {\n key: 'moveWord',\n value: function moveWord() {\n return this;\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('must implement get leafSectionIndex', false);\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return false;\n }\n }, {\n key: 'marker',\n get: function get() {\n return false;\n }\n }, {\n key: 'markerPosition',\n get: function get() {\n return {};\n }\n }]);\n\n return BlankPosition;\n })(Position);\n\n exports['default'] = Position;\n});","define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsKey, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * A logical range of a {@link Post}.\n * Usually an instance of Range will be read from the {@link Editor#range} property,\n * but it may be useful to instantiate a range directly when programmatically modifying a Post.\n */\n\n var Range = (function () {\n /**\n * @param {Position} head\n * @param {Position} [tail=head]\n * @param {Direction} [direction=null]\n * @return {Range}\n * @private\n */\n\n function Range(head) {\n var tail = arguments.length <= 1 || arguments[1] === undefined ? head : arguments[1];\n var direction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n return (function () {\n _classCallCheck(this, Range);\n\n /** @property {Position} head */\n this.head = head;\n\n /** @property {Position} tail */\n this.tail = tail;\n\n /** @property {Direction} direction */\n this.direction = direction;\n }).apply(this, arguments);\n }\n\n /**\n * Shorthand to create a new range from a section(s) and offset(s).\n * When given only a head section and offset, creates a collapsed range.\n * @param {Section} headSection\n * @param {number} headOffset\n * @param {Section} [tailSection=headSection]\n * @param {number} [tailOffset=headOffset]\n * @param {Direction} [direction=null]\n * @return {Range}\n */\n\n _createClass(Range, [{\n key: 'trimTo',\n\n /**\n * @param {Markerable} section\n * @return {Range} A range that is constrained to only the part that\n * includes the section.\n * FIXME -- if the section isn't the head or tail, it's assumed to be\n * wholly contained. It's possible to call `trimTo` with a selection that is\n * outside of the range, though, which would invalidate that assumption.\n * There's no efficient way to determine if a section is within a range, yet.\n * @private\n */\n value: function trimTo(section) {\n var length = section.length;\n\n var headOffset = section === this.head.section ? Math.min(this.head.offset, length) : 0;\n var tailOffset = section === this.tail.section ? Math.min(this.tail.offset, length) : length;\n\n return Range.create(section, headOffset, section, tailOffset);\n }\n\n /**\n * Expands the range 1 unit in the given direction\n * If the range is expandable in the given direction, always returns a\n * non-collapsed range.\n * @param {Number} units If units is > 0, the range is extended to the right,\n * otherwise range is extended to the left.\n * @return {Range}\n * @public\n */\n }, {\n key: 'extend',\n value: function extend(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Range#extend', typeof units === 'number');\n\n if (units === 0) {\n return this;\n }\n\n var head = this.head;\n var tail = this.tail;\n var currentDirection = this.direction;\n\n switch (currentDirection) {\n case _mobiledocKitUtilsKey.DIRECTION.FORWARD:\n return new Range(head, tail.move(units), currentDirection);\n case _mobiledocKitUtilsKey.DIRECTION.BACKWARD:\n return new Range(head.move(units), tail, currentDirection);\n default:\n {\n var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n return new Range(head, tail, newDirection).extend(units);\n }\n }\n }\n\n /**\n * Moves this range 1 unit in the given direction.\n * If the range is collapsed, returns a collapsed range shifted by 1 unit,\n * otherwise collapses this range to the position at the `direction` end of the range.\n * Always returns a collapsed range.\n * @param {Direction} direction\n * @return {Range}\n * @public\n */\n }, {\n key: 'move',\n value: function move(direction) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass DIRECTION.FORWARD (' + _mobiledocKitUtilsKey.DIRECTION.FORWARD + ') or DIRECTION.BACKWARD (' + _mobiledocKitUtilsKey.DIRECTION.BACKWARD + ') to Range#move', direction === _mobiledocKitUtilsKey.DIRECTION.FORWARD || direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD);\n\n var focusedPosition = this.focusedPosition;\n var isCollapsed = this.isCollapsed;\n\n if (isCollapsed) {\n return new Range(focusedPosition.move(direction));\n } else {\n return this._collapse(direction);\n }\n }\n\n /**\n * expand a range to all markers matching a given check\n *\n * @param {Function} detectMarker\n * @return {Range} The expanded range\n *\n * @public\n */\n }, {\n key: 'expandByMarker',\n value: function expandByMarker(detectMarker) {\n var head = this.head;\n var tail = this.tail;\n var direction = this.direction;\n var headSection = head.section;\n\n if (headSection !== tail.section) {\n throw new Error('#expandByMarker does not work across sections. Perhaps you should confirm the range is collapsed');\n }\n\n var firstNotMatchingDetect = function firstNotMatchingDetect(i) {\n return !detectMarker(i);\n };\n\n var headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true);\n if (!headMarker && detectMarker(headSection.markers.head)) {\n headMarker = headSection.markers.head;\n } else {\n headMarker = headMarker.next || head.marker;\n }\n var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker));\n\n var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker);\n if (!tailMarker && detectMarker(headSection.markers.tail)) {\n tailMarker = headSection.markers.tail;\n } else {\n tailMarker = tailMarker.prev || tail.marker;\n }\n var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length);\n\n return headPosition.toRange(tailPosition, direction);\n }\n }, {\n key: '_collapse',\n value: function _collapse(direction) {\n return new Range(direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail);\n }\n }, {\n key: 'isEqual',\n value: function isEqual(other) {\n return other && this.head.isEqual(other.head) && this.tail.isEqual(other.tail);\n }\n }, {\n key: 'focusedPosition',\n get: function get() {\n return this.direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.head.isBlank && this.tail.isBlank;\n }\n\n // \"legacy\" APIs\n }, {\n key: 'headSection',\n get: function get() {\n return this.head.section;\n }\n }, {\n key: 'tailSection',\n get: function get() {\n return this.tail.section;\n }\n }, {\n key: 'headSectionOffset',\n get: function get() {\n return this.head.offset;\n }\n }, {\n key: 'tailSectionOffset',\n get: function get() {\n return this.tail.offset;\n }\n }, {\n key: 'isCollapsed',\n get: function get() {\n return this.head.isEqual(this.tail);\n }\n }, {\n key: 'headMarker',\n get: function get() {\n return this.head.marker;\n }\n }, {\n key: 'tailMarker',\n get: function get() {\n return this.tail.marker;\n }\n }, {\n key: 'headMarkerOffset',\n get: function get() {\n return this.head.offsetInMarker;\n }\n }, {\n key: 'tailMarkerOffset',\n get: function get() {\n return this.tail.offsetInMarker;\n }\n }], [{\n key: 'create',\n value: function create(headSection, headOffset) {\n var tailSection = arguments.length <= 2 || arguments[2] === undefined ? headSection : arguments[2];\n var tailOffset = arguments.length <= 3 || arguments[3] === undefined ? headOffset : arguments[3];\n var direction = arguments.length <= 4 || arguments[4] === undefined ? null : arguments[4];\n return (function () {\n return new Range(new _mobiledocKitUtilsCursorPosition['default'](headSection, headOffset), new _mobiledocKitUtilsCursorPosition['default'](tailSection, tailOffset), direction);\n })();\n }\n }, {\n key: 'blankRange',\n value: function blankRange() {\n return new Range(_mobiledocKitUtilsCursorPosition['default'].blankPosition(), _mobiledocKitUtilsCursorPosition['default'].blankPosition());\n }\n }]);\n\n return Range;\n })();\n\n exports['default'] = Range;\n});","define(\"mobiledoc-kit/utils/deprecate\", [\"exports\"], function (exports) {\n /**\n * Usage:\n * Without a conditional, always prints deprecate message:\n * `deprecate('This is deprecated')`\n *\n * Conditional deprecation, works similarly to `assert`, prints deprecation if\n * conditional is false:\n * `deprecate('Deprecated only if foo !== bar', foo === bar)`\n */\n \"use strict\";\n\n exports[\"default\"] = deprecate;\n\n function deprecate(message) {\n var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (!conditional) {\n // eslint-disable-next-line no-console\n console.log(\"[mobiledoc-kit] [DEPRECATED]: \" + message);\n }\n }\n});","define('mobiledoc-kit/utils/dom-utils', ['exports', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n COMMENT: 8\n };\n\n exports.NODE_TYPES = NODE_TYPES;\n function isTextNode(node) {\n return node.nodeType === NODE_TYPES.TEXT;\n }\n\n function isCommentNode(node) {\n return node.nodeType === NODE_TYPES.COMMENT;\n }\n\n function isElementNode(node) {\n return node.nodeType === NODE_TYPES.ELEMENT;\n }\n\n // perform a pre-order tree traversal of the dom, calling `callbackFn(node)`\n // for every node for which `conditionFn(node)` is true\n function walkDOM(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n var conditionFn = arguments.length <= 2 || arguments[2] === undefined ? function () {\n return true;\n } : arguments[2];\n\n var currentNode = topNode;\n\n if (conditionFn(currentNode)) {\n callbackFn(currentNode);\n }\n\n currentNode = currentNode.firstChild;\n\n while (currentNode) {\n walkDOM(currentNode, callbackFn, conditionFn);\n currentNode = currentNode.nextSibling;\n }\n }\n\n function walkTextNodes(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n\n var conditionFn = function conditionFn(node) {\n return isTextNode(node);\n };\n walkDOM(topNode, callbackFn, conditionFn);\n }\n\n function clearChildNodes(element) {\n while (element.childNodes.length) {\n element.removeChild(element.childNodes[0]);\n }\n }\n\n /**\n * @return {Boolean} true when the child node is contained or the same as\n * (e.g., inclusive containment) the parent node\n * see https://github.com/webmodules/node-contains/blob/master/index.js\n * Mimics the behavior of `Node.contains`, which is broken in IE 10\n * @private\n */\n function containsNode(parentNode, childNode) {\n if (parentNode === childNode) {\n return true;\n }\n var position = parentNode.compareDocumentPosition(childNode);\n return !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY);\n }\n\n /**\n * converts the element's NamedNodeMap of attrs into\n * an object with key-value pairs\n * @param {DOMNode} element\n * @return {Object} key-value pairs\n * @private\n */\n function getAttributes(element) {\n var result = {};\n if (element.hasAttributes()) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.attributes, function (_ref) {\n var name = _ref.name;\n var value = _ref.value;\n\n result[name] = value;\n });\n }\n return result;\n }\n\n function addClassName(element, className) {\n element.classList.add(className);\n }\n\n function removeClassName(element, className) {\n element.classList.remove(className);\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n\n function parseHTML(html) {\n var div = document.createElement('div');\n div.innerHTML = html;\n return div;\n }\n\n function serializeHTML(node) {\n var div = document.createElement('div');\n div.appendChild(node);\n return div.innerHTML;\n }\n\n exports.containsNode = containsNode;\n exports.clearChildNodes = clearChildNodes;\n exports.getAttributes = getAttributes;\n exports.walkDOM = walkDOM;\n exports.walkTextNodes = walkTextNodes;\n exports.addClassName = addClassName;\n exports.removeClassName = removeClassName;\n exports.normalizeTagName = normalizeTagName;\n exports.isTextNode = isTextNode;\n exports.isCommentNode = isCommentNode;\n exports.isElementNode = isElementNode;\n exports.parseHTML = parseHTML;\n exports.serializeHTML = serializeHTML;\n});","define('mobiledoc-kit/utils/element-map', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // start at one to make the falsy semantics easier\n var uuidGenerator = 1;\n\n var ElementMap = (function () {\n function ElementMap() {\n _classCallCheck(this, ElementMap);\n\n this._map = {};\n }\n\n _createClass(ElementMap, [{\n key: 'set',\n value: function set(key, value) {\n var uuid = key._uuid;\n if (!uuid) {\n key._uuid = uuid = '' + uuidGenerator++;\n }\n this._map[uuid] = value;\n }\n }, {\n key: 'get',\n value: function get(key) {\n if (key._uuid) {\n return this._map[key._uuid];\n }\n return null;\n }\n }, {\n key: 'remove',\n value: function remove(key) {\n (0, _mobiledocKitUtilsAssert['default'])('tried to fetch a value for an element not seen before', !!key._uuid);\n delete this._map[key._uuid];\n }\n }]);\n\n return ElementMap;\n })();\n\n exports['default'] = ElementMap;\n});","define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function getEventTargetMatchingTag(tagName, target, container) {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n // Traverses up DOM from an event target to find the node matching specifed tag\n while (target && target !== container) {\n if ((0, _mobiledocKitUtilsDomUtils.normalizeTagName)(target.tagName) === tagName) {\n return target;\n }\n target = target.parentNode;\n }\n }\n\n function getElementRelativeOffset(element) {\n var offset = { left: 0, top: -window.pageYOffset };\n var offsetParent = element.offsetParent;\n var offsetParentPosition = window.getComputedStyle(offsetParent).position;\n var offsetParentRect;\n\n if (offsetParentPosition === 'relative') {\n offsetParentRect = offsetParent.getBoundingClientRect();\n offset.left = offsetParentRect.left;\n offset.top = offsetParentRect.top;\n }\n return offset;\n }\n\n function getElementComputedStyleNumericProp(element, prop) {\n return parseFloat(window.getComputedStyle(element)[prop]);\n }\n\n function positionElementToRect(element, rect, topOffset, leftOffset) {\n var relativeOffset = getElementRelativeOffset(element);\n var style = element.style;\n var round = Math.round;\n var left, top;\n\n topOffset = topOffset || 0;\n leftOffset = leftOffset || 0;\n left = round(rect.left - relativeOffset.left - leftOffset);\n top = round(rect.top - relativeOffset.top - topOffset);\n style.left = left + 'px';\n style.top = top + 'px';\n return { left: left, top: top };\n }\n\n function positionElementHorizontallyCenteredToRect(element, rect, topOffset) {\n var horizontalCenter = element.offsetWidth / 2 - rect.width / 2;\n return positionElementToRect(element, rect, topOffset, horizontalCenter);\n }\n\n function positionElementCenteredBelow(element, belowElement) {\n var elementMargin = getElementComputedStyleNumericProp(element, 'marginTop');\n return positionElementHorizontallyCenteredToRect(element, belowElement.getBoundingClientRect(), -element.offsetHeight - elementMargin);\n }\n\n function setData(element, name, value) {\n if (element.dataset) {\n element.dataset[name] = value;\n } else {\n var dataName = (0, _mobiledocKitUtilsStringUtils.dasherize)(name);\n return element.setAttribute(dataName, value);\n }\n }\n\n function whenElementIsNotInDOM(element, callback) {\n var isCanceled = false;\n var observerFn = function observerFn() {\n if (isCanceled) {\n return;\n }\n if (!element.parentNode) {\n callback();\n } else {\n window.requestAnimationFrame(observerFn);\n }\n };\n observerFn();\n return { cancel: function cancel() {\n return isCanceled = true;\n } };\n }\n\n exports.setData = setData;\n exports.getEventTargetMatchingTag = getEventTargetMatchingTag;\n exports.getElementRelativeOffset = getElementRelativeOffset;\n exports.getElementComputedStyleNumericProp = getElementComputedStyleNumericProp;\n exports.positionElementToRect = positionElementToRect;\n exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect;\n exports.positionElementCenteredBelow = positionElementCenteredBelow;\n exports.whenElementIsNotInDOM = whenElementIsNotInDOM;\n});","define('mobiledoc-kit/utils/environment', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n hasDOM: function hasDOM() {\n return typeof document !== 'undefined';\n }\n };\n});","define(\"mobiledoc-kit/utils/fixed-queue\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var FixedQueue = (function () {\n function FixedQueue() {\n var length = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\n _classCallCheck(this, FixedQueue);\n\n this._maxLength = length;\n this._items = [];\n }\n\n _createClass(FixedQueue, [{\n key: \"pop\",\n value: function pop() {\n return this._items.pop();\n }\n }, {\n key: \"push\",\n value: function push(item) {\n this._items.push(item);\n if (this.length > this._maxLength) {\n this._items.shift();\n }\n }\n }, {\n key: \"clear\",\n value: function clear() {\n this._items = [];\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this._items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this._items.length;\n }\n }]);\n\n return FixedQueue;\n })();\n\n exports[\"default\"] = FixedQueue;\n});","define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/keys', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKeys, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.modifierMask = modifierMask;\n exports.specialCharacterToCode = specialCharacterToCode;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * @typedef Direction\n * @enum {number}\n * @property {number} FORWARD\n * @property {number} BACKWARD\n */\n var DIRECTION = {\n FORWARD: 1,\n BACKWARD: -1\n };\n exports.DIRECTION = DIRECTION;\n var MODIFIERS = {\n META: 1, // also called \"command\" on OS X\n CTRL: 2,\n SHIFT: 4,\n ALT: 8 // also called \"option\" on OS X\n };\n\n exports.MODIFIERS = MODIFIERS;\n\n function modifierMask(event) {\n var metaKey = event.metaKey;\n var shiftKey = event.shiftKey;\n var ctrlKey = event.ctrlKey;\n var altKey = event.altKey;\n\n var modVal = function modVal(val, modifier) {\n return val && modifier || 0;\n };\n return modVal(metaKey, MODIFIERS.META) + modVal(shiftKey, MODIFIERS.SHIFT) + modVal(ctrlKey, MODIFIERS.CTRL) + modVal(altKey, MODIFIERS.ALT);\n }\n\n var SPECIAL_KEYS = {\n BACKSPACE: _mobiledocKitUtilsKeycodes['default'].BACKSPACE,\n TAB: _mobiledocKitUtilsKeycodes['default'].TAB,\n ENTER: _mobiledocKitUtilsKeycodes['default'].ENTER,\n ESC: _mobiledocKitUtilsKeycodes['default'].ESC,\n SPACE: _mobiledocKitUtilsKeycodes['default'].SPACE,\n PAGEUP: _mobiledocKitUtilsKeycodes['default'].PAGEUP,\n PAGEDOWN: _mobiledocKitUtilsKeycodes['default'].PAGEDOWN,\n END: _mobiledocKitUtilsKeycodes['default'].END,\n HOME: _mobiledocKitUtilsKeycodes['default'].HOME,\n LEFT: _mobiledocKitUtilsKeycodes['default'].LEFT,\n UP: _mobiledocKitUtilsKeycodes['default'].UP,\n RIGHT: _mobiledocKitUtilsKeycodes['default'].RIGHT,\n DOWN: _mobiledocKitUtilsKeycodes['default'].DOWN,\n INS: _mobiledocKitUtilsKeycodes['default'].INS,\n DEL: _mobiledocKitUtilsKeycodes['default'].DELETE\n };\n\n function specialCharacterToCode(specialCharacter) {\n return SPECIAL_KEYS[specialCharacter];\n }\n\n // heuristic for determining if `event` is a key event\n function isKeyEvent(event) {\n return (/^key/.test(event.type)\n );\n }\n\n /**\n * An abstraction around a KeyEvent\n * that key listeners in the editor can use\n * to determine what sort of key was pressed\n */\n var Key = (function () {\n function Key(event) {\n _classCallCheck(this, Key);\n\n this.key = event.key;\n this.keyCode = event.keyCode;\n this.charCode = event.charCode;\n this.event = event;\n this.modifierMask = modifierMask(event);\n }\n\n _createClass(Key, [{\n key: 'toString',\n value: function toString() {\n if (this.isTab()) {\n return _mobiledocKitUtilsCharacters.TAB;\n }\n return String.fromCharCode(this.charCode);\n }\n\n // See https://caniuse.com/#feat=keyboardevent-key for browser support.\n }, {\n key: 'isKeySupported',\n value: function isKeySupported() {\n return this.key;\n }\n }, {\n key: 'isKey',\n value: function isKey(identifier) {\n if (this.isKeySupported()) {\n (0, _mobiledocKitUtilsAssert['default'])('Must define Keys.' + identifier + '.', _mobiledocKitUtilsKeys['default'][identifier]);\n return this.key === _mobiledocKitUtilsKeys['default'][identifier];\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Must define Keycodes.' + identifier + '.', _mobiledocKitUtilsKeycodes['default'][identifier]);\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'][identifier];\n }\n }\n }, {\n key: 'isEscape',\n value: function isEscape() {\n return this.isKey('ESC');\n }\n }, {\n key: 'isDelete',\n value: function isDelete() {\n return this.isKey('BACKSPACE') || this.isForwardDelete();\n }\n }, {\n key: 'isForwardDelete',\n value: function isForwardDelete() {\n return this.isKey('DELETE');\n }\n }, {\n key: 'isArrow',\n value: function isArrow() {\n return this.isHorizontalArrow() || this.isVerticalArrow();\n }\n }, {\n key: 'isHorizontalArrow',\n value: function isHorizontalArrow() {\n return this.isLeftArrow() || this.isRightArrow();\n }\n }, {\n key: 'isHorizontalArrowWithoutModifiersOtherThanShift',\n value: function isHorizontalArrowWithoutModifiersOtherThanShift() {\n return this.isHorizontalArrow() && !(this.ctrlKey || this.metaKey || this.altKey);\n }\n }, {\n key: 'isVerticalArrow',\n value: function isVerticalArrow() {\n return this.isKey('UP') || this.isKey('DOWN');\n }\n }, {\n key: 'isLeftArrow',\n value: function isLeftArrow() {\n return this.isKey('LEFT');\n }\n }, {\n key: 'isRightArrow',\n value: function isRightArrow() {\n return this.isKey('RIGHT');\n }\n }, {\n key: 'isHome',\n value: function isHome() {\n return this.isKey('HOME');\n }\n }, {\n key: 'isEnd',\n value: function isEnd() {\n return this.isKey('END');\n }\n }, {\n key: 'isPageUp',\n value: function isPageUp() {\n return this.isKey('PAGEUP');\n }\n }, {\n key: 'isPageDown',\n value: function isPageDown() {\n return this.isKey('PAGEDOWN');\n }\n }, {\n key: 'isInsert',\n value: function isInsert() {\n return this.isKey('INS');\n }\n }, {\n key: 'isClear',\n value: function isClear() {\n return this.isKey('CLEAR');\n }\n }, {\n key: 'isPause',\n value: function isPause() {\n return this.isKey('PAUSE');\n }\n }, {\n key: 'isSpace',\n value: function isSpace() {\n return this.isKey('SPACE');\n }\n\n // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but\n // it will also fire a keydown event for the tab+modifier (ctrl). This causes\n // Mobiledoc to erroneously insert a tab character before FF switches to the\n // new browser tab. Chrome doesn't fire this event so the issue doesn't\n // arise there. Fix this by returning false when the TAB key event includes a\n // modifier.\n // See: https://github.com/bustle/mobiledoc-kit/issues/565\n }, {\n key: 'isTab',\n value: function isTab() {\n return !this.hasAnyModifier() && this.isKey('TAB');\n }\n }, {\n key: 'isEnter',\n value: function isEnter() {\n return this.isKey('ENTER');\n }\n\n /*\n * If the key is the actual shift key. This is false when the shift key\n * is held down and the source `event` is not the shift key.\n * @see {isShift}\n * @return {bool}\n */\n }, {\n key: 'isShiftKey',\n value: function isShiftKey() {\n return this.isKey('SHIFT');\n }\n\n /*\n * If the key is the actual alt key (aka \"option\" on mac). This is false when the alt key\n * is held down and the source `event` is not the alt key.\n * @return {bool}\n */\n }, {\n key: 'isAltKey',\n value: function isAltKey() {\n return this.isKey('ALT');\n }\n\n /*\n * If the key is the actual ctrl key. This is false when the ctrl key\n * is held down and the source `event` is not the ctrl key.\n * @return {bool}\n */\n }, {\n key: 'isCtrlKey',\n value: function isCtrlKey() {\n return this.isKey('CTRL');\n }\n }, {\n key: 'isIME',\n value: function isIME() {\n // FIXME the IME action seems to get lost when we issue an\n // `editor.deleteSelection` before it (in Chrome)\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].IME;\n }\n }, {\n key: 'isShift',\n\n /**\n * If the shift key is depressed.\n * For example, while holding down meta+shift, pressing the \"v\"\n * key would result in an event whose `Key` had `isShift()` with a truthy value,\n * because the shift key is down when pressing the \"v\".\n * @see {isShiftKey} which checks if the key is actually the shift key itself.\n * @return {bool}\n */\n value: function isShift() {\n return this.shiftKey;\n }\n }, {\n key: 'hasModifier',\n value: function hasModifier(modifier) {\n return modifier & this.modifierMask;\n }\n }, {\n key: 'hasAnyModifier',\n value: function hasAnyModifier() {\n return !!this.modifierMask;\n }\n }, {\n key: 'isPrintableKey',\n value: function isPrintableKey() {\n return !(this.isArrow() || this.isHome() || this.isEnd() || this.isPageUp() || this.isPageDown() || this.isInsert() || this.isClear() || this.isPause() || this.isEscape());\n }\n }, {\n key: 'isNumberKey',\n value: function isNumberKey() {\n if (this.isKeySupported()) {\n return this.key >= '0' && this.key <= '9';\n } else {\n var code = this.keyCode;\n return code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9; // numpad keys\n }\n }\n }, {\n key: 'isLetterKey',\n value: function isLetterKey() {\n if (this.isKeySupported()) {\n var key = this.key;\n return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z';\n } else {\n var code = this.keyCode;\n return code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z;\n }\n }\n }, {\n key: 'isPunctuation',\n value: function isPunctuation() {\n if (this.isKeySupported()) {\n var key = this.key;\n return key >= ';' && key <= '`' || key >= '[' && key <= '\"';\n } else {\n var code = this.keyCode;\n return code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['\"'];\n }\n }\n\n /**\n * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position\n * and http://stackoverflow.com/a/12467610/137784\n */\n }, {\n key: 'isPrintable',\n value: function isPrintable() {\n if (this.ctrlKey || this.metaKey) {\n return false;\n }\n\n // Firefox calls keypress events for some keys that should not be printable\n if (!this.isPrintableKey()) {\n return false;\n }\n\n return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME();\n }\n }, {\n key: 'direction',\n get: function get() {\n switch (true) {\n case this.isDelete():\n return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n case this.isHorizontalArrow():\n return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n }\n }\n }, {\n key: 'ctrlKey',\n get: function get() {\n return MODIFIERS.CTRL & this.modifierMask;\n }\n }, {\n key: 'metaKey',\n get: function get() {\n return MODIFIERS.META & this.modifierMask;\n }\n }, {\n key: 'shiftKey',\n get: function get() {\n return MODIFIERS.SHIFT & this.modifierMask;\n }\n }, {\n key: 'altKey',\n get: function get() {\n return MODIFIERS.ALT & this.modifierMask;\n }\n }], [{\n key: 'fromEvent',\n value: function fromEvent(event) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass a Key event to Key.fromEvent', event && isKeyEvent(event));\n return new Key(event);\n }\n }]);\n\n return Key;\n })();\n\n exports['default'] = Key;\n});","define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n BACKSPACE: 8,\n SPACE: 32,\n ENTER: 13,\n SHIFT: 16,\n ESC: 27,\n DELETE: 46,\n '0': 48,\n '9': 57,\n A: 65,\n Z: 90,\n a: 97,\n z: 122,\n 'NUMPAD_0': 186,\n 'NUMPAD_9': 111,\n ';': 186,\n '.': 190,\n '`': 192,\n '[': 219,\n '\"': 222,\n\n // Input Method Editor uses multiple keystrokes to display characters.\n // Example on mac: press option-i then i. This fires 2 key events in Chrome\n // with keyCode 229 and displays ˆ and then î.\n // See http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html#fixed-virtual-key-codes\n IME: 229,\n\n TAB: 9,\n CLEAR: 12,\n PAUSE: 19,\n PAGEUP: 33,\n PAGEDOWN: 34,\n END: 35,\n HOME: 36,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n INS: 45,\n META: 91,\n ALT: 18,\n CTRL: 17\n };\n});","define('mobiledoc-kit/utils/keys', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n BACKSPACE: 'Backspace',\n SPACE: ' ',\n ENTER: 'Enter',\n SHIFT: 'Shift',\n ESC: 'Escape',\n DELETE: 'Delete',\n INS: 'Insert',\n HOME: 'Home',\n END: 'End',\n PAGEUP: 'PageUp',\n PAGEDOWN: 'PageDown',\n CLEAR: 'Clear',\n PAUSE: 'Pause',\n TAB: 'Tab',\n ALT: 'Alt',\n CTRL: 'Control',\n\n LEFT: 'ArrowLeft',\n RIGHT: 'ArrowRight',\n UP: 'ArrowUp',\n DOWN: 'ArrowDown'\n };\n});","define(\"mobiledoc-kit/utils/linked-item\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var LinkedItem = function LinkedItem() {\n _classCallCheck(this, LinkedItem);\n\n this.next = null;\n this.prev = null;\n };\n\n exports[\"default\"] = LinkedItem;\n});","define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var PARENT_PROP = '__parent';\n\n var LinkedList = (function () {\n function LinkedList(options) {\n _classCallCheck(this, LinkedList);\n\n this.head = null;\n this.tail = null;\n this.length = 0;\n\n if (options) {\n var adoptItem = options.adoptItem;\n var freeItem = options.freeItem;\n\n this._adoptItem = adoptItem;\n this._freeItem = freeItem;\n }\n }\n\n _createClass(LinkedList, [{\n key: 'adoptItem',\n value: function adoptItem(item) {\n item[PARENT_PROP] = this;\n this.length++;\n if (this._adoptItem) {\n this._adoptItem(item);\n }\n }\n }, {\n key: 'freeItem',\n value: function freeItem(item) {\n item[PARENT_PROP] = null;\n this.length--;\n if (this._freeItem) {\n this._freeItem(item);\n }\n }\n }, {\n key: 'prepend',\n value: function prepend(item) {\n this.insertBefore(item, this.head);\n }\n }, {\n key: 'append',\n value: function append(item) {\n this.insertBefore(item, null);\n }\n }, {\n key: 'insertAfter',\n value: function insertAfter(item, prevItem) {\n var nextItem = prevItem ? prevItem.next : this.head;\n this.insertBefore(item, nextItem);\n }\n }, {\n key: '_ensureItemIsNotAlreadyInList',\n value: function _ensureItemIsNotAlreadyInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item.next && !item.prev && this.head !== item);\n }\n }, {\n key: 'insertBefore',\n value: function insertBefore(item, nextItem) {\n this._ensureItemIsNotInList(item);\n this.adoptItem(item);\n\n var insertPos = undefined;\n if (nextItem && nextItem.prev) {\n insertPos = 'middle';\n } else if (nextItem) {\n insertPos = 'start';\n } else {\n insertPos = 'end';\n }\n\n switch (insertPos) {\n case 'start':\n if (this.head) {\n item.next = this.head;\n this.head.prev = item;\n }\n this.head = item;\n\n break;\n case 'middle':\n {\n var prevItem = nextItem.prev;\n item.next = nextItem;\n item.prev = prevItem;\n nextItem.prev = item;\n prevItem.next = item;\n\n break;\n }\n case 'end':\n {\n var tail = this.tail;\n item.prev = tail;\n\n if (tail) {\n tail.next = item;\n } else {\n this.head = item;\n }\n this.tail = item;\n\n break;\n }\n }\n }\n }, {\n key: 'remove',\n value: function remove(item) {\n if (!item[PARENT_PROP]) {\n return;\n }\n this._ensureItemIsInThisList(item);\n this.freeItem(item);\n\n var prev = item.prev;\n var next = item.next;\n\n item.prev = null;\n item.next = null;\n\n if (prev) {\n prev.next = next;\n } else {\n this.head = next;\n }\n\n if (next) {\n next.prev = prev;\n } else {\n this.tail = prev;\n }\n }\n }, {\n key: 'forEach',\n value: function forEach(callback) {\n var item = this.head;\n var index = 0;\n while (item) {\n callback(item, index++);\n item = item.next;\n }\n }\n }, {\n key: 'map',\n value: function map(callback) {\n var result = [];\n this.forEach(function (i) {\n return result.push(callback(i));\n });\n return result;\n }\n }, {\n key: 'walk',\n value: function walk(startItem, endItem, callback) {\n var item = startItem || this.head;\n while (item) {\n callback(item);\n if (item === endItem) {\n break;\n }\n item = item.next;\n }\n }\n }, {\n key: 'readRange',\n value: function readRange(startItem, endItem) {\n var items = [];\n this.walk(startItem, endItem, function (item) {\n items.push(item);\n });\n return items;\n }\n }, {\n key: 'toArray',\n value: function toArray() {\n return this.readRange();\n }\n }, {\n key: 'detect',\n value: function detect(callback) {\n var item = arguments.length <= 1 || arguments[1] === undefined ? this.head : arguments[1];\n var reverse = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n while (item) {\n if (callback(item)) {\n return item;\n }\n item = reverse ? item.prev : item.next;\n }\n }\n }, {\n key: 'any',\n value: function any(callback) {\n return !!this.detect(callback);\n }\n }, {\n key: 'every',\n value: function every(callback) {\n var item = this.head;\n while (item) {\n if (!callback(item)) {\n return false;\n }\n item = item.next;\n }\n return true;\n }\n }, {\n key: 'objectAt',\n value: function objectAt(targetIndex) {\n var index = -1;\n return this.detect(function () {\n index++;\n return targetIndex === index;\n });\n }\n }, {\n key: 'splice',\n value: function splice(targetItem, removalCount, newItems) {\n var _this = this;\n\n var item = targetItem;\n var nextItem = item.next;\n var count = 0;\n while (item && count < removalCount) {\n count++;\n nextItem = item.next;\n this.remove(item);\n item = nextItem;\n }\n newItems.forEach(function (newItem) {\n _this.insertBefore(newItem, nextItem);\n });\n }\n }, {\n key: 'removeBy',\n value: function removeBy(conditionFn) {\n var item = this.head;\n while (item) {\n var nextItem = item.next;\n\n if (conditionFn(item)) {\n this.remove(item);\n }\n\n item = nextItem;\n }\n }\n }, {\n key: '_ensureItemIsNotInList',\n value: function _ensureItemIsNotInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item[PARENT_PROP]);\n }\n }, {\n key: '_ensureItemIsInThisList',\n value: function _ensureItemIsInThisList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot remove item that is in another list', item[PARENT_PROP] === this);\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.length === 0;\n }\n }]);\n\n return LinkedList;\n })();\n\n exports['default'] = LinkedList;\n});","define(\"mobiledoc-kit/utils/log-manager\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Logger = (function () {\n function Logger(type, manager) {\n _classCallCheck(this, Logger);\n\n this.type = type;\n this.manager = manager;\n }\n\n _createClass(Logger, [{\n key: \"isEnabled\",\n value: function isEnabled() {\n return this.manager.isEnabled(this.type);\n }\n }, {\n key: \"log\",\n value: function log() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n args.unshift(\"[\" + this.type + \"]\");\n if (this.isEnabled()) {\n var _window$console;\n\n (_window$console = window.console).log.apply(_window$console, args);\n }\n }\n }]);\n\n return Logger;\n })();\n\n var LogManager = (function () {\n function LogManager() {\n _classCallCheck(this, LogManager);\n\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n\n _createClass(LogManager, [{\n key: \"for\",\n value: function _for(type) {\n return new Logger(type, this);\n }\n }, {\n key: \"enableAll\",\n value: function enableAll() {\n this.allEnabled = true;\n }\n }, {\n key: \"enableTypes\",\n value: function enableTypes(types) {\n this.enabledTypes = this.enabledTypes.concat(types);\n }\n }, {\n key: \"disable\",\n value: function disable() {\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n }, {\n key: \"isEnabled\",\n value: function isEnabled(type) {\n return this.allEnabled || this.enabledTypes.indexOf(type) !== -1;\n }\n }]);\n\n return LogManager;\n })();\n\n exports[\"default\"] = LogManager;\n});","define('mobiledoc-kit/utils/markuperable', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var Markerupable = (function () {\n function Markerupable() {\n _classCallCheck(this, Markerupable);\n }\n\n _createClass(Markerupable, [{\n key: 'clearMarkups',\n value: function clearMarkups() {\n this.markups = [];\n }\n }, {\n key: 'addMarkup',\n value: function addMarkup(markup) {\n this.markups.push(markup);\n }\n }, {\n key: 'addMarkupAtIndex',\n value: function addMarkupAtIndex(markup, index) {\n this.markups.splice(index, 0, markup);\n }\n }, {\n key: 'removeMarkup',\n value: function removeMarkup(markupOrMarkupCallback) {\n var _this = this;\n\n var callback = undefined;\n if (typeof markupOrMarkupCallback === 'function') {\n callback = markupOrMarkupCallback;\n } else {\n (function () {\n var markup = markupOrMarkupCallback;\n callback = function (_markup) {\n return _markup === markup;\n };\n })();\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.markups, callback), function (m) {\n return _this._removeMarkup(m);\n });\n }\n }, {\n key: '_removeMarkup',\n value: function _removeMarkup(markup) {\n var index = this.markups.indexOf(markup);\n if (index !== -1) {\n this.markups.splice(index, 1);\n }\n }\n }, {\n key: 'hasMarkup',\n value: function hasMarkup(tagNameOrMarkup) {\n return !!this.getMarkup(tagNameOrMarkup);\n }\n }, {\n key: 'getMarkup',\n value: function getMarkup(tagNameOrMarkup) {\n var _this2 = this;\n\n if (typeof tagNameOrMarkup === 'string') {\n var _ret2 = (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagNameOrMarkup);\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup.tagName === tagName;\n })\n };\n })();\n\n if (typeof _ret2 === 'object') return _ret2.v;\n } else {\n var _ret3 = (function () {\n var targetMarkup = tagNameOrMarkup;\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup === targetMarkup;\n })\n };\n })();\n\n if (typeof _ret3 === 'object') return _ret3.v;\n }\n }\n }, {\n key: 'openedMarkups',\n get: function get() {\n var count = 0;\n if (this.prev) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.prev.markups);\n }\n\n return this.markups.slice(count);\n }\n }, {\n key: 'closedMarkups',\n get: function get() {\n var count = 0;\n if (this.next) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.next.markups);\n }\n\n return this.markups.slice(count);\n }\n }]);\n\n return Markerupable;\n })();\n\n exports['default'] = Markerupable;\n});","define(\"mobiledoc-kit/utils/merge\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function mergeWithOptions(original, updates, options) {\n options = options || {};\n for (var prop in updates) {\n if (options.hasOwnProperty(prop)) {\n original[prop] = options[prop];\n } else if (updates.hasOwnProperty(prop)) {\n original[prop] = updates[prop];\n }\n }\n return original;\n }\n\n /**\n * Merges properties of one object into another\n * @private\n */\n function merge(original, updates) {\n return mergeWithOptions(original, updates);\n }\n\n exports.mergeWithOptions = mergeWithOptions;\n exports.merge = merge;\n});","define('mobiledoc-kit/utils/mixin', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = mixin;\n var CONSTRUCTOR_FN_NAME = 'constructor';\n\n function mixin(target, source) {\n target = target.prototype;\n // Fallback to just `source` to allow mixing in a plain object (pojo)\n source = source.prototype || source;\n\n Object.getOwnPropertyNames(source).forEach(function (name) {\n if (name !== CONSTRUCTOR_FN_NAME) {\n var descriptor = Object.getOwnPropertyDescriptor(source, name);\n\n Object.defineProperty(target, name, descriptor);\n }\n });\n }\n});","define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) {\n 'use strict';\n\n var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];\n\n function MobiledocError() {\n var tmp = Error.apply(this, arguments);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.\n for (var idx = 0; idx < errorProps.length; idx++) {\n this[errorProps[idx]] = tmp[errorProps[idx]];\n }\n }\n\n MobiledocError.prototype = Object.create(Error.prototype);\n\n exports['default'] = MobiledocError;\n});","define(\"mobiledoc-kit/utils/object-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.entries = entries;\n\n function entries(obj) {\n var ownProps = Object.keys(obj);\n var i = ownProps.length;\n var resArray = new Array(i);\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]];\n }\n\n return resArray;\n }\n});","define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) {\n /* global JSON */\n 'use strict';\n\n exports.getContentFromPasteEvent = getContentFromPasteEvent;\n exports.setClipboardData = setClipboardData;\n exports.parsePostFromPaste = parsePostFromPaste;\n exports.parsePostFromDrop = parsePostFromDrop;\n var MIME_TEXT_PLAIN = 'text/plain';\n exports.MIME_TEXT_PLAIN = MIME_TEXT_PLAIN;\n var MIME_TEXT_HTML = 'text/html';\n exports.MIME_TEXT_HTML = MIME_TEXT_HTML;\n var NONSTANDARD_IE_TEXT_TYPE = 'Text';\n\n exports.NONSTANDARD_IE_TEXT_TYPE = NONSTANDARD_IE_TEXT_TYPE;\n var MOBILEDOC_REGEX = new RegExp(/data\\-mobiledoc='(.*?)'>/);\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromHTML(html, builder, plugins) {\n var post = undefined;\n\n if (MOBILEDOC_REGEX.test(html)) {\n var mobiledocString = html.match(MOBILEDOC_REGEX)[1];\n var mobiledoc = JSON.parse(mobiledocString);\n post = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n } else {\n post = new _mobiledocKitParsersHtml['default'](builder, { plugins: plugins }).parse(html);\n }\n\n return post;\n }\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromText(text, builder, plugins) {\n var parser = new _mobiledocKitParsersText['default'](builder, { plugins: plugins });\n var post = parser.parse(text);\n return post;\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n\n function getContentFromPasteEvent(event, window) {\n var html = '',\n text = '';\n\n var clipboardData = event.clipboardData;\n\n if (clipboardData && clipboardData.getData) {\n html = clipboardData.getData(MIME_TEXT_HTML);\n text = clipboardData.getData(MIME_TEXT_PLAIN);\n } else if (window.clipboardData && window.clipboardData.getData) {\n // IE\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n html = window.clipboardData.getData(NONSTANDARD_IE_TEXT_TYPE);\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n function getContentFromDropEvent(event, logger) {\n var html = '',\n text = '';\n\n try {\n html = event.dataTransfer.getData(MIME_TEXT_HTML);\n text = event.dataTransfer.getData(MIME_TEXT_PLAIN);\n } catch (e) {\n // FIXME IE11 does not include any data in the 'text/html' or 'text/plain'\n // mimetypes. It throws an error 'Invalid argument' when attempting to read\n // these properties.\n if (logger) {\n logger.log('Error getting drop data: ', e);\n }\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @param {CopyEvent|CutEvent}\n * @param {Editor}\n * @param {Window}\n * @private\n */\n\n function setClipboardData(event, _ref, window) {\n var mobiledoc = _ref.mobiledoc;\n var html = _ref.html;\n var text = _ref.text;\n\n if (mobiledoc && html) {\n html = '
    ' + html + '
    ';\n }\n\n var clipboardData = event.clipboardData;\n var nonstandardClipboardData = window.clipboardData;\n\n if (clipboardData && clipboardData.setData) {\n clipboardData.setData(MIME_TEXT_HTML, html);\n clipboardData.setData(MIME_TEXT_PLAIN, text);\n } else if (nonstandardClipboardData && nonstandardClipboardData.setData) {\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n nonstandardClipboardData.setData(NONSTANDARD_IE_TEXT_TYPE, html);\n }\n }\n\n /**\n * @param {PasteEvent}\n * @param {{builder: Builder, _parserPlugins: Array}} options\n * @return {Post}\n * @private\n */\n\n function parsePostFromPaste(pasteEvent, _ref2) {\n var builder = _ref2.builder;\n var plugins = _ref2._parserPlugins;\n\n var _ref3 = arguments.length <= 2 || arguments[2] === undefined ? { targetFormat: 'html' } : arguments[2];\n\n var targetFormat = _ref3.targetFormat;\n\n var _getContentFromPasteEvent = getContentFromPasteEvent(pasteEvent, window);\n\n var html = _getContentFromPasteEvent.html;\n var text = _getContentFromPasteEvent.text;\n\n if (targetFormat === 'html' && html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n\n /**\n * @param {DropEvent}\n * @param {Editor} editor\n * @param {Object} [options={}] Can pass a logger\n * @return {Post}\n * @private\n */\n\n function parsePostFromDrop(dropEvent, editor) {\n var _ref4 = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var logger = _ref4.logger;\n var builder = editor.builder;\n var plugins = editor._parserPlugins;\n\n var _getContentFromDropEvent = getContentFromDropEvent(dropEvent, logger);\n\n var html = _getContentFromDropEvent.html;\n var text = _getContentFromDropEvent.text;\n\n if (html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n});","define(\"mobiledoc-kit/utils/placeholder-image-src\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var placeholderImageSrc = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAMFBMVEXp7vG6vsHm6+63u77Hy868wMPe4+bO09bh5unr8fTR1djAxMfM0NPX3N/c4eTBxcjXRf5TAAACh0lEQVR4nO3b6ZKqMBSFUSQMYZL3f9tbBq/NEEDiqUqOfusn1ZXKbjcQlGQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC6RkbsGHuabChEtHmiGYfS3EQYM+Sxw/gMQvmcNnYaj6oTDHi73WPn2eqnj9B8zo3TJXcq5uNjXmVff86VwSR3JtryMa1BYqi7S1hJDCVpSigyLcGhJJEwzlCSNtPKrbVhVwsdCfOhH7uuaG3ARV9DwsaOzxt3N1yPqCHhvXytTUz92VDpmE/LLhZwl++R6Sds6sUa/PL6K/2E2fIhw1xdRKefsFolrPc+xNx/N0k/4fpBsdhL2HfeiN+TsDCms8dDpeRyS3P3QDl6Iqaf8L0rTf+80m6Lmn7Ct+4Wxf+/2RY1/YRv3PHz/u+fsCmqgoTnq7Z+8SGviqoh4dnKu1ieqauiakh4/PQ0r6ivqDoSHj0B97eNRVG1JNxV+L4bnxdVecJtRTdFVZ7QU9F1UXUn9FZ0VVRlCav5ob2KLouqKmFjy676u2HsVnRRVFUJq3J+8KCi86IqSthMvyl209Hjijqm3RsqAZ5pNfa5PJ2KelJRjQmr1/r7cfy0ouoSNvOfvbvhvKLaEr4qOin9kTQnrN7LpDZhE/Zmhp6Eq4p+YcKgiipKGFhRRQkDK6ooYfgLbiSMioQkJGF8P5XwHv4O+7AaKiXzaeXh1kMl5AffTUxiKEm/krD94BR8Gdxl1fceSlR58ZhXKbEpyD2amNiBtmrJLTMHL1LF8/rpXkSZXEmz8K8uvAFFNm6Iq0aBLUFOmeCuJ6exrcCmoLpN7kYx891bSAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgh/wDdr8peyRHLogAAAAASUVORK5CYII=\";\n\n exports[\"default\"] = placeholderImageSrc;\n});","define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function clearSelection() {\n window.getSelection().removeAllRanges();\n }\n\n function textNodeRects(node) {\n var range = document.createRange();\n range.setEnd(node, node.nodeValue.length);\n range.setStart(node, 0);\n return range.getClientRects();\n }\n\n function findOffsetInTextNode(node, coords) {\n var len = node.nodeValue.length;\n var range = document.createRange();\n for (var i = 0; i < len; i++) {\n range.setEnd(node, i + 1);\n range.setStart(node, i);\n var rect = range.getBoundingClientRect();\n if (rect.top === rect.bottom) {\n continue;\n }\n if (rect.left <= coords.left && rect.right >= coords.left && rect.top <= coords.top && rect.bottom >= coords.top) {\n return { node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };\n }\n }\n return { node: node, offset: 0 };\n }\n\n /*\n * @param {Object} coords with `top` and `left`\n * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js\n * @return {Object} {node, offset}\n */\n /* eslint-disable complexity */\n function findOffsetInNode(_x, _x2) {\n var _again = true;\n\n _function: while (_again) {\n var node = _x,\n coords = _x2;\n _again = false;\n\n var closest = undefined,\n dyClosest = 1e8,\n coordsClosest = undefined,\n offset = 0;\n for (var child = node.firstChild; child; child = child.nextSibling) {\n var rects = undefined;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child)) {\n rects = child.getClientRects();\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(child)) {\n rects = textNodeRects(child);\n } else {\n continue;\n }\n\n for (var i = 0; i < rects.length; i++) {\n var rect = rects[i];\n if (rect.left <= coords.left && rect.right >= coords.left) {\n var dy = rect.top > coords.top ? rect.top - coords.top : rect.bottom < coords.top ? coords.top - rect.bottom : 0;\n if (dy < dyClosest) {\n closest = child;\n dyClosest = dy;\n coordsClosest = dy ? { left: coords.left, top: rect.top } : coords;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child) && !child.firstChild) {\n offset = i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);\n }\n continue;\n }\n }\n if (!closest && (coords.top >= rect.bottom || coords.top >= rect.top && coords.left >= rect.right)) {\n offset = i + 1;\n }\n }\n }\n if (!closest) {\n return { node: node, offset: offset };\n }\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(closest)) {\n return findOffsetInTextNode(closest, coordsClosest);\n }\n if (closest.firstChild) {\n _x = closest;\n _x2 = coordsClosest;\n _again = true;\n closest = dyClosest = coordsClosest = offset = child = rects = i = rect = dy = undefined;\n continue _function;\n }\n return { node: node, offset: offset };\n }\n }\n /* eslint-enable complexity */\n\n function constrainNodeTo(node, parentNode, existingOffset) {\n var compare = parentNode.compareDocumentPosition(node);\n if (compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n // the node is inside parentNode, do nothing\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_CONTAINS) {\n // the node contains parentNode. This shouldn't happen.\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_PRECEDING) {\n // node is before parentNode. return start of deepest first child\n var child = parentNode.firstChild;\n while (child.firstChild) {\n child = child.firstChild;\n }\n return { node: child, offset: 0 };\n } else if (compare & Node.DOCUMENT_POSITION_FOLLOWING) {\n // node is after parentNode. return end of deepest last child\n var child = parentNode.lastChild;\n while (child.lastChild) {\n child = child.lastChild;\n }\n\n var offset = (0, _mobiledocKitUtilsDomUtils.isTextNode)(child) ? child.textContent.length : 1;\n return { node: child, offset: offset };\n } else {\n return { node: node, offset: existingOffset };\n }\n }\n\n /*\n * Returns a new selection that is constrained within parentNode.\n * If the anchorNode or focusNode are outside the parentNode, they are replaced with the beginning\n * or end of the parentNode's children\n */\n function constrainSelectionTo(selection, parentNode) {\n var _constrainNodeTo = constrainNodeTo(selection.anchorNode, parentNode, selection.anchorOffset);\n\n var anchorNode = _constrainNodeTo.node;\n var anchorOffset = _constrainNodeTo.offset;\n\n var _constrainNodeTo2 = constrainNodeTo(selection.focusNode, parentNode, selection.focusOffset);\n\n var focusNode = _constrainNodeTo2.node;\n var focusOffset = _constrainNodeTo2.offset;\n\n return { anchorNode: anchorNode, anchorOffset: anchorOffset, focusNode: focusNode, focusOffset: focusOffset };\n }\n\n function comparePosition(_x3) {\n var _again2 = true;\n\n _function2: while (_again2) {\n var selection = _x3;\n _again2 = false;\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n var headNode = undefined,\n tailNode = undefined,\n headOffset = undefined,\n tailOffset = undefined,\n direction = undefined;\n\n var position = anchorNode.compareDocumentPosition(focusNode);\n\n // IE may select return focus and anchor nodes far up the DOM tree instead of\n // picking the deepest, most specific possible node. For example in\n //\n //
    abcdef
    \n //\n // with a cursor between c and d, IE might say the focusNode is
    with\n // an offset of 1. However the anchorNode for a selection might still be\n // 2 if there was a selection.\n //\n // This code walks down the DOM tree until a good comparison of position can be\n // made.\n //\n if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n if (focusOffset < focusNode.childNodes.length) {\n focusNode = focusNode.childNodes[focusOffset];\n focusOffset = 0;\n } else {\n // This situation happens on IE when triple-clicking to select.\n // Set the focus to the very last character inside the node.\n while (focusNode.lastChild) {\n focusNode = focusNode.lastChild;\n }\n focusOffset = focusNode.textContent.length;\n }\n\n _x3 = {\n focusNode: focusNode,\n focusOffset: focusOffset,\n anchorNode: anchorNode, anchorOffset: anchorOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = undefined;\n continue _function2;\n } else if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n var offset = anchorOffset - 1;\n if (offset < 0) {\n offset = 0;\n }\n _x3 = {\n anchorNode: anchorNode.childNodes[offset],\n anchorOffset: 0,\n focusNode: focusNode, focusOffset: focusOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = offset = undefined;\n continue _function2;\n\n // The meat of translating anchor and focus nodes to head and tail nodes\n } else if (position & Node.DOCUMENT_POSITION_FOLLOWING) {\n headNode = anchorNode;tailNode = focusNode;\n headOffset = anchorOffset;tailOffset = focusOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n headNode = focusNode;tailNode = anchorNode;\n headOffset = focusOffset;tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else {\n // same node\n headNode = tailNode = anchorNode;\n headOffset = anchorOffset;\n tailOffset = focusOffset;\n if (tailOffset < headOffset) {\n // Swap the offset order\n headOffset = focusOffset;\n tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else if (headOffset < tailOffset) {\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else {\n direction = null;\n }\n }\n\n return { headNode: headNode, headOffset: headOffset, tailNode: tailNode, tailOffset: tailOffset, direction: direction };\n }\n }\n\n exports.clearSelection = clearSelection;\n exports.comparePosition = comparePosition;\n exports.findOffsetInNode = findOffsetInNode;\n exports.constrainSelectionTo = constrainSelectionTo;\n});","define(\"mobiledoc-kit/utils/set\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Set = (function () {\n function Set() {\n var _this = this;\n\n var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, Set);\n\n this.items = [];\n items.forEach(function (i) {\n return _this.add(i);\n });\n }\n\n _createClass(Set, [{\n key: \"add\",\n value: function add(item) {\n if (!this.has(item)) {\n this.items.push(item);\n }\n }\n }, {\n key: \"has\",\n value: function has(item) {\n return this.items.indexOf(item) !== -1;\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this.items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this.items.length;\n }\n }]);\n\n return Set;\n })();\n\n exports[\"default\"] = Set;\n});","define('mobiledoc-kit/utils/string-utils', ['exports'], function (exports) {\n /*\n * @param {String} string\n * @return {String} a dasherized string. 'modelIndex' -> 'model-index', etc\n */\n 'use strict';\n\n exports.dasherize = dasherize;\n exports.capitalize = capitalize;\n exports.startsWith = startsWith;\n exports.endsWith = endsWith;\n\n function dasherize(string) {\n return string.replace(/[A-Z]/g, function (match, offset) {\n var lower = match.toLowerCase();\n\n return offset === 0 ? lower : '-' + lower;\n });\n }\n\n function capitalize(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n }\n\n function startsWith(string, character) {\n return string.charAt(0) === character;\n }\n\n function endsWith(string, endString) {\n var index = string.lastIndexOf(endString);\n return index !== -1 && index === string.length - endString.length;\n }\n});","define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports['default'] = toRange;\n\n function toRange(rangeLike) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass non-blank object to \"toRange\"', !!rangeLike);\n\n if (rangeLike instanceof _mobiledocKitUtilsCursorRange['default']) {\n return rangeLike;\n } else if (rangeLike instanceof _mobiledocKitUtilsCursorPosition['default']) {\n return rangeLike.toRange();\n }\n\n (0, _mobiledocKitUtilsAssert['default'])('Incorrect structure for rangeLike: ' + rangeLike, false);\n }\n});","define('mobiledoc-kit/version', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = '##VERSION##';\n});","define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var DELAY = 200;\n\n var Tooltip = (function (_View) {\n _inherits(Tooltip, _View);\n\n function Tooltip(options) {\n var _this = this;\n\n _classCallCheck(this, Tooltip);\n\n var rootElement = options.rootElement;\n\n var timeout = undefined;\n options.classNames = ['__mobiledoc-tooltip'];\n _get(Object.getPrototypeOf(Tooltip.prototype), 'constructor', this).call(this, options);\n\n this.addEventListener(rootElement, 'mouseover', function (e) {\n var target = (0, _mobiledocKitUtilsElementUtils.getEventTargetMatchingTag)(options.showForTag, e.target, rootElement);\n if (target && target.isContentEditable) {\n timeout = setTimeout(function () {\n _this.showLink(target.href, target);\n }, DELAY);\n }\n });\n\n this.addEventListener(rootElement, 'mouseout', function (e) {\n clearTimeout(timeout);\n if (_this.elementObserver) {\n _this.elementObserver.cancel();\n }\n var toElement = e.toElement || e.relatedTarget;\n if (toElement && toElement.className !== _this.element.className) {\n _this.hide();\n }\n });\n }\n\n _createClass(Tooltip, [{\n key: 'showMessage',\n value: function showMessage(message, element) {\n var tooltipElement = this.element;\n tooltipElement.innerHTML = message;\n this.show();\n (0, _mobiledocKitUtilsElementUtils.positionElementCenteredBelow)(tooltipElement, element);\n }\n }, {\n key: 'showLink',\n value: function showLink(link, element) {\n var _this2 = this;\n\n var message = '' + link + '';\n this.showMessage(message, element);\n this.elementObserver = (0, _mobiledocKitUtilsElementUtils.whenElementIsNotInDOM)(element, function () {\n return _this2.hide();\n });\n }\n }]);\n\n return Tooltip;\n })(_mobiledocKitViewsView['default']);\n\n exports['default'] = Tooltip;\n});","define('mobiledoc-kit/views/view', ['exports', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var View = (function () {\n function View() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, View);\n\n options.tagName = options.tagName || 'div';\n options.container = options.container || document.body;\n\n this.element = document.createElement(options.tagName);\n this.container = options.container;\n this.isShowing = false;\n\n var classNames = options.classNames || [];\n classNames.forEach(function (name) {\n return (0, _mobiledocKitUtilsDomUtils.addClassName)(_this.element, name);\n });\n this._eventListeners = [];\n }\n\n _createClass(View, [{\n key: 'addEventListener',\n value: function addEventListener(element, type, listener) {\n element.addEventListener(type, listener);\n this._eventListeners.push([element, type, listener]);\n }\n }, {\n key: 'removeAllEventListeners',\n value: function removeAllEventListeners() {\n this._eventListeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var element = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n element.removeEventListener(type, listener);\n });\n }\n }, {\n key: 'show',\n value: function show() {\n if (!this.isShowing) {\n this.container.appendChild(this.element);\n this.isShowing = true;\n return true;\n }\n }\n }, {\n key: 'hide',\n value: function hide() {\n if (this.isShowing) {\n this.container.removeChild(this.element);\n this.isShowing = false;\n return true;\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.removeAllEventListeners();\n this.hide();\n this.isDestroyed = true;\n }\n }]);\n\n return View;\n })();\n\n exports['default'] = View;\n});","define('mobiledoc-text-renderer/cards/image', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n name: 'image-card',\n type: 'text',\n render: function render() {}\n };\n});","define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n function registerGlobal(window) {\n window.MobiledocTextRenderer = _mobiledocTextRendererRendererFactory['default'];\n }\n\n exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default'];\n exports['default'] = _mobiledocTextRendererRendererFactory['default'];\n});","define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var cards = _ref.cards;\n var atoms = _ref.atoms;\n var cardOptions = _ref.cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n\n _classCallCheck(this, RendererFactory);\n\n cards = cards || [];\n validateCards(cards);\n atoms = atoms || [];\n validateAtoms(atoms);\n cardOptions = cardOptions || {};\n\n this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION:\n return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render();\n case undefined:\n case null:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var sections = _sectionData[1];\n\n this.root = [];\n this.sections = sections;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n\n // for the text renderer, a missing card is a no-op\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var type = _ref32[0];\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 3);\n\n var text = _m[2];\n\n str += text;\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {};\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION_0_3 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1 && version !== MOBILEDOC_VERSION_0_3_2) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n\n validateVersion(version);\n\n this.root = [];\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var index = _ref32[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this4 = this;\n\n var env = {\n name: atom.name,\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || '';\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var _this5 = this;\n\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 4);\n\n var type = _m[0];\n var value = _m[3];\n\n switch (type) {\n case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n str += value;\n break;\n case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n str += _this5._renderAtom(value);\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {\n // for the text renderer, a missing card is a no-op\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref5) {\n var value = _ref5.value;\n\n return value || '';\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-text-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'text';\n});","define(\"mobiledoc-text-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACp3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACl7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5WA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;","file":"mobiledoc-kit.js"} \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/cards/image.js b/website/commonjs/mobiledoc-kit/cards/image.js index 1b6dc41ab..1a249bca4 100644 --- a/website/commonjs/mobiledoc-kit/cards/image.js +++ b/website/commonjs/mobiledoc-kit/cards/image.js @@ -7,8 +7,6 @@ exports['default'] = { type: 'dom', render: function render(_ref) { - var env = _ref.env; - var options = _ref.options; var payload = _ref.payload; var img = document.createElement('img'); diff --git a/website/commonjs/mobiledoc-kit/editor/edit-state.js b/website/commonjs/mobiledoc-kit/editor/edit-state.js index 891e26350..503656208 100644 --- a/website/commonjs/mobiledoc-kit/editor/edit-state.js +++ b/website/commonjs/mobiledoc-kit/editor/edit-state.js @@ -24,7 +24,8 @@ var EditState = (function () { range: _utilsCursorRange['default'].blankRange(), activeMarkups: [], activeSections: [], - activeSectionTagNames: [] + activeSectionTagNames: [], + activeSectionAttributes: {} }; this.prevState = this.state = defaultState; @@ -65,7 +66,7 @@ var EditState = (function () { var state = this.state; var prevState = this.prevState; - return !(0, _utilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _utilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames); + return !(0, _utilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _utilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _utilsArrayUtils.isArrayEqual)((0, _utilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _utilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes)); } /** @@ -102,6 +103,7 @@ var EditState = (function () { state.activeSectionTagNames = state.activeSections.map(function (s) { return s.isNested ? s.parent.tagName : s.tagName; }); + state.activeSectionAttributes = this._readSectionAttributes(state.activeSections); return state; } }, { @@ -124,6 +126,22 @@ var EditState = (function () { return post.markupsInRange(range); } + }, { + key: '_readSectionAttributes', + value: function _readSectionAttributes(sections) { + return sections.reduce(function (sectionAttributes, s) { + var attributes = s.isNested ? s.parent.attributes : s.attributes; + Object.keys(attributes || {}).forEach(function (attrName) { + var camelizedAttrName = attrName.replace(/^data-md-/, ''); + var attrValue = attributes[attrName]; + sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || []; + if (!(0, _utilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) { + sectionAttributes[camelizedAttrName].push(attrValue); + } + }); + return sectionAttributes; + }, {}); + } }, { key: '_removeActiveMarkup', value: function _removeActiveMarkup(markup) { @@ -150,6 +168,15 @@ var EditState = (function () { return this.state.activeSections; } + /** + * @return {Object} + */ + }, { + key: 'activeSectionAttributes', + get: function get() { + return this.state.activeSectionAttributes; + } + /** * @return {Markup[]} */ diff --git a/website/commonjs/mobiledoc-kit/editor/editor.js b/website/commonjs/mobiledoc-kit/editor/editor.js index 2d6dc803c..6b987681e 100644 --- a/website/commonjs/mobiledoc-kit/editor/editor.js +++ b/website/commonjs/mobiledoc-kit/editor/editor.js @@ -83,6 +83,7 @@ var defaults = { placeholder: 'Write here...', spellcheck: true, autofocus: true, + showLinkTooltips: true, undoDepth: 5, undoBlockTimeout: 5000, // ms for an undo event cards: [], @@ -136,6 +137,8 @@ var CALLBACK_QUEUES = { * a custom toolbar. * * {@link Editor#onTextInput} -- Register callbacks when the user enters text * that matches a given string or regex. + * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before + * applying changes from {@link Editor#toggleMarkup} */ var Editor = (function () { @@ -156,6 +159,7 @@ var Editor = (function () { * @param {String} [options.placeholder] Default text to show before user starts typing. * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered. + * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links * @param {number} [options.undoDepth=5] How many undo levels will be available. * Set to 0 to disable undo/redo functionality. * @return {Editor} @@ -171,7 +175,7 @@ var Editor = (function () { (0, _utilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType); this._views = []; - this.isEditable = null; + this.isEditable = true; this._parserPlugins = options.parserPlugins || []; // FIXME: This should merge onto this.options @@ -200,6 +204,7 @@ var Editor = (function () { this._mutationHandler = new _editorMutationHandler['default'](this); this._editState = new _editorEditState['default'](this); this._callbacks = new _modelsLifecycleCallbacks['default']((0, _utilsArrayUtils.values)(CALLBACK_QUEUES)); + this._beforeHooks = { toggleMarkup: [] }; _textInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) { return _this.onTextInput(handler); @@ -306,12 +311,10 @@ var Editor = (function () { this.element = element; - if (this.isEditable === null) { - this.enableEditing(); + if (this.showLinkTooltips) { + this._addTooltip(); } - this._addTooltip(); - // A call to `run` will trigger the didUpdatePostCallbacks hooks with a // postEditor. this.run(function () {}); @@ -325,6 +328,12 @@ var Editor = (function () { this._mutationHandler.init(); this._eventManager.init(); + if (this.isEditable === false) { + this.disableEditing(); + } else { + this.enableEditing(); + } + if (this.autofocus) { this.selectRange(this.post.headPosition()); } @@ -652,15 +661,17 @@ var Editor = (function () { switch (format) { case 'html': - var result = undefined; - if (_utilsEnvironment['default'].hasDOM()) { - rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc); - result = '
    ' + (0, _utilsDomUtils.serializeHTML)(rendered.result) + '
    '; - } else { - // Fallback to text serialization - result = this.serializePost(post, 'text', options); + { + var result = undefined; + if (_utilsEnvironment['default'].hasDOM()) { + rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc); + result = '
    ' + (0, _utilsDomUtils.serializeHTML)(rendered.result) + '
    '; + } else { + // Fallback to text serialization + result = this.serializePost(post, 'text', options); + } + return result; } - return result; case 'text': rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc); return rendered.result; @@ -725,12 +736,9 @@ var Editor = (function () { }, { key: 'disableEditing', value: function disableEditing() { - if (this.isEditable === false) { - return; - } - this.isEditable = false; if (this.hasRendered) { + this._eventManager.stop(); this.element.setAttribute('contentEditable', false); this.setPlaceholder(''); this.selectRange(_utilsCursorRange['default'].blankRange()); @@ -748,7 +756,8 @@ var Editor = (function () { key: 'enableEditing', value: function enableEditing() { this.isEditable = true; - if (this.element) { + if (this.hasRendered) { + this._eventManager.start(); this.element.setAttribute('contentEditable', true); this.setPlaceholder(this.placeholder); } @@ -986,22 +995,55 @@ var Editor = (function () { }); } + /** + * @callback editorBeforeCallback + * @param { Object } details + * @param { Markup } details.markup + * @param { Range } details.range + * @param { boolean } details.willAdd Whether the markup will be applied + */ + + /** + * Register a callback that will be run before {@link Editor#toggleMarkup} is applied. + * If any callback returns literal `false`, the toggling of markup will be canceled. + * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and + * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks. + * @param {editorBeforeCallback} + */ + }, { + key: 'beforeToggleMarkup', + value: function beforeToggleMarkup(callback) { + this._beforeHooks.toggleMarkup.push(callback); + } + /** * Toggles the given markup at the editor's current {@link Range}. * If the range is collapsed this changes the editor's state so that the * next characters typed will be affected. If there is text selected * (aka a non-collapsed range), the selections' markup will be toggled. * If the editor is not focused and has no active range, nothing happens. + * Hooks added using #beforeToggleMarkup will be run before toggling, + * and if any of them returns literal false, toggling the markup will be canceled + * and no change will be applied. * @param {String} markup E.g. "b", "em", "a" + * @param {Object} [attributes={}] E.g. {href: "http://bustle.com"} * @public * @see PostEditor#toggleMarkup */ }, { key: 'toggleMarkup', value: function toggleMarkup(markup) { - markup = this.builder.createMarkup(markup); + var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + + markup = this.builder.createMarkup(markup, attributes); var range = this.range; + var willAdd = !this.detectMarkupInRange(range, markup.tagName); + var shouldCancel = this._runBeforeHooks('toggleMarkup', { markup: markup, range: range, willAdd: willAdd }); + if (shouldCancel) { + return; + } + if (range.isCollapsed) { this._editState.toggleMarkupState(markup); this._inputModeDidChange(); @@ -1074,6 +1116,41 @@ var Editor = (function () { }); } + /** + * Sets an attribute for the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @param {String} value The value of the attribute. + * @public + * @see PostEditor#setAttribute + */ + }, { + key: 'setAttribute', + value: function setAttribute(key, value) { + var _this7 = this; + + this.run(function (postEditor) { + return postEditor.setAttribute(key, value, _this7.range); + }); + } + + /** + * Removes an attribute from the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @public + * @see PostEditor#removeAttribute + */ + }, { + key: 'removeAttribute', + value: function removeAttribute(key) { + var _this8 = this; + + this.run(function (postEditor) { + return postEditor.removeAttribute(key, _this8.range); + }); + } + /** * Finds and runs the first matching key command for the event * @@ -1185,7 +1262,7 @@ var Editor = (function () { }, { key: 'insertCard', value: function insertCard(cardName) { - var _this7 = this; + var _this9 = this; var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; @@ -1204,7 +1281,7 @@ var Editor = (function () { var position = range.tail; card = postEditor.builder.createCardSection(cardName, cardPayload); if (inEditMode) { - _this7.editCard(card); + _this9.editCard(card); } if (!range.isCollapsed) { @@ -1219,7 +1296,7 @@ var Editor = (function () { if (section.isBlank) { postEditor.replaceSection(section, card); } else { - var collection = _this7.post.sections; + var collection = _this9.post.sections; postEditor.insertSectionBefore(collection, card, section.next); } @@ -1291,6 +1368,28 @@ var Editor = (function () { } (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments); } + + /** + * Runs each callback for the given hookName. + * Only the hookName 'toggleMarkup' is currently supported + * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled + * @private + */ + }, { + key: '_runBeforeHooks', + value: function _runBeforeHooks(hookName) { + var hooks = this._beforeHooks[hookName] || []; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < hooks.length; i++) { + if (hooks[i].apply(hooks, args) === false) { + return true; + } + } + } }, { key: 'builder', get: function get() { @@ -1345,6 +1444,11 @@ var Editor = (function () { return activeSections[activeSections.length - 1]; } + }, { + key: 'activeSectionAttributes', + get: function get() { + return this._editState.activeSectionAttributes; + } }, { key: 'activeMarkups', get: function get() { diff --git a/website/commonjs/mobiledoc-kit/editor/event-manager.js b/website/commonjs/mobiledoc-kit/editor/event-manager.js index 5a8c758ea..7d3fdda12 100644 --- a/website/commonjs/mobiledoc-kit/editor/event-manager.js +++ b/website/commonjs/mobiledoc-kit/editor/event-manager.js @@ -31,12 +31,11 @@ var EventManager = (function () { this._textInputHandler = new _editorTextInputHandler['default'](editor); this._listeners = []; this.modifierKeys = { - shift: false, - alt: false, - ctrl: false + shift: false }; this._selectionManager = new _editorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this)); + this.started = true; } _createClass(EventManager, [{ @@ -54,6 +53,16 @@ var EventManager = (function () { this._selectionManager.start(); } + }, { + key: 'start', + value: function start() { + this.started = true; + } + }, { + key: 'stop', + value: function stop() { + this.started = false; + } }, { key: 'registerInputHandler', value: function registerInputHandler(inputHandler) { @@ -114,7 +123,6 @@ var EventManager = (function () { var _ref42 = _slicedToArray(_ref4, 3); var context = _ref42[0]; - var type = _ref42[1]; var listener = _ref42[2]; listener.call(context, event); @@ -132,6 +140,11 @@ var EventManager = (function () { value: function _handleEvent(type, event) { var element = event.target; + if (!this.started) { + // abort handling this event + return true; + } + if (!this.isElementAddressable(element)) { // abort handling this event return true; @@ -214,29 +227,34 @@ var EventManager = (function () { switch (true) { // FIXME This should be restricted to only card/atom boundaries case key.isHorizontalArrowWithoutModifiersOtherThanShift(): - var newRange = undefined; - if (key.isShift()) { - newRange = range.extend(key.direction * 1); - } else { - newRange = range.move(key.direction); + { + var newRange = undefined; + if (key.isShift()) { + newRange = range.extend(key.direction * 1); + } else { + newRange = range.move(key.direction); + } + + editor.selectRange(newRange); + event.preventDefault(); + break; } - - editor.selectRange(newRange); - event.preventDefault(); - break; case key.isDelete(): - var direction = key.direction; - - var unit = 'char'; - if (this.modifierKeys.alt && _utilsBrowser['default'].isMac()) { - unit = 'word'; - } else if (this.modifierKeys.ctrl && _utilsBrowser['default'].isWin()) { - unit = 'word'; + { + var direction = key.direction; + + var unit = 'char'; + if (key.altKey && _utilsBrowser['default'].isMac()) { + unit = 'word'; + } else if (key.ctrlKey && !_utilsBrowser['default'].isMac()) { + unit = 'word'; + } + editor.performDelete({ direction: direction, unit: unit }); + event.preventDefault(); + break; } - editor.performDelete({ direction: direction, unit: unit }); - event.preventDefault(); - break; case key.isEnter(): + this._textInputHandler.handleNewLine(); editor.handleNewline(event); break; case key.isTab(): @@ -344,10 +362,6 @@ var EventManager = (function () { if (key.isShiftKey()) { this.modifierKeys.shift = isDown; - } else if (key.isAltKey()) { - this.modifierKeys.alt = isDown; - } else if (key.isCtrlKey()) { - this.modifierKeys.ctrl = isDown; } } }]); diff --git a/website/commonjs/mobiledoc-kit/editor/key-commands.js b/website/commonjs/mobiledoc-kit/editor/key-commands.js index 73ed53b89..409dad277 100644 --- a/website/commonjs/mobiledoc-kit/editor/key-commands.js +++ b/website/commonjs/mobiledoc-kit/editor/key-commands.js @@ -172,7 +172,7 @@ function modifierNamesToMask(modiferNames) { function characterToCode(character) { var upperCharacter = character.toUpperCase(); - var special = _utilsKey.SPECIAL_KEYS[upperCharacter]; + var special = (0, _utilsKey.specialCharacterToCode)(upperCharacter); if (special) { return special; } else { diff --git a/website/commonjs/mobiledoc-kit/editor/post.js b/website/commonjs/mobiledoc-kit/editor/post.js index 7146daf12..f7a81b257 100644 --- a/website/commonjs/mobiledoc-kit/editor/post.js +++ b/website/commonjs/mobiledoc-kit/editor/post.js @@ -940,8 +940,6 @@ var PostEditor = (function () { sectionTagName = (0, _utilsDomUtils.normalizeTagName)(sectionTagName); var post = this.editor.post; - var nextRange = range; - var everySectionHasTagName = true; post.walkMarkerableSections(range, function (section) { if (!_this13._isSameSectionType(section, sectionTagName)) { @@ -950,17 +948,91 @@ var PostEditor = (function () { }); var tagName = everySectionHasTagName ? 'p' : sectionTagName; - var firstChanged = undefined; + var sectionTransformations = []; post.walkMarkerableSections(range, function (section) { var changedSection = _this13.changeSectionTagName(section, tagName); - firstChanged = firstChanged || changedSection; + sectionTransformations.push({ + from: section, + to: changedSection + }); }); - if (firstChanged) { - nextRange = firstChanged.headPosition().toRange(); - } + var nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations); this.setRange(nextRange); } + }, { + key: '_determineNextRangeAfterToggleSection', + value: function _determineNextRangeAfterToggleSection(range, sectionTransformations) { + if (sectionTransformations.length) { + var changedHeadSection = (0, _utilsArrayUtils.detect)(sectionTransformations, function (_ref2) { + var from = _ref2.from; + + return from === range.headSection; + }).to; + var changedTailSection = (0, _utilsArrayUtils.detect)(sectionTransformations, function (_ref3) { + var from = _ref3.from; + + return from === range.tailSection; + }).to; + + if (changedHeadSection.isListSection || changedTailSection.isListSection) { + // We don't know to which ListItem's the original sections point at, so + // we don't have enough information to reconstruct the range when + // dealing with lists. + return sectionTransformations[0].to.headPosition().toRange(); + } else { + return _utilsCursorRange['default'].create(changedHeadSection, range.headSectionOffset, changedTailSection, range.tailSectionOffset, range.direction); + } + } else { + return range; + } + } + }, { + key: 'setAttribute', + value: function setAttribute(key, value) { + var range = arguments.length <= 2 || arguments[2] === undefined ? this._range : arguments[2]; + + this._mutateAttribute(key, range, function (section, attribute) { + if (section.getAttribute(attribute) !== value) { + section.setAttribute(attribute, value); + return true; + } + }); + } + }, { + key: 'removeAttribute', + value: function removeAttribute(key) { + var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1]; + + this._mutateAttribute(key, range, function (section, attribute) { + if (section.hasAttribute(attribute)) { + section.removeAttribute(attribute); + return true; + } + }); + } + }, { + key: '_mutateAttribute', + value: function _mutateAttribute(key, range, cb) { + var _this14 = this; + + range = (0, _utilsToRange['default'])(range); + var post = this.editor.post; + + var attribute = 'data-md-' + key; + + post.walkMarkerableSections(range, function (section) { + if (section.isListItem) { + section = section.parent; + } + + if (cb(section, attribute) === true) { + _this14._markDirty(section); + } + }); + + this.setRange(range); + } }, { key: '_isSameSectionType', value: function _isSameSectionType(section, sectionTagName) { @@ -1039,13 +1111,11 @@ var PostEditor = (function () { if (positionIsMiddle) { var item = position.section; - var _splitListItem3 = // jshint ignore:line - this._splitListItem(item, position); + var _splitListItem3 = this._splitListItem(item, position); - var _splitListItem32 = _slicedToArray(_splitListItem3, 2); + var _splitListItem32 = _slicedToArray(_splitListItem3, 1); var pre = _splitListItem32[0]; - var post = _splitListItem32[1]; position = pre.tailPosition(); } @@ -1084,10 +1154,10 @@ var PostEditor = (function () { }, { key: '_splitListAtItem', value: function _splitListAtItem(list, item) { - var _this14 = this; + var _this15 = this; var next = list; - var prev = this.builder.createListSection(next.tagName); + var prev = this.builder.createListSection(next.tagName, [], next.attributes); var mid = this.builder.createListSection(next.tagName); var addToPrev = true; @@ -1105,7 +1175,7 @@ var PostEditor = (function () { return; // break after iterating prev and mid parts of the list } listToAppend.join(i); - _this14.removeSection(i); + _this15.removeSection(i); }); var found = !addToPrev; (0, _utilsAssert['default'])('Cannot split list at item that is not present in the list', found); @@ -1119,7 +1189,7 @@ var PostEditor = (function () { [prev, next].forEach(function (_list) { var isAttached = !!_list.parent; if (_list.isBlank && isAttached) { - _this14.removeSection(_list); + _this15.removeSection(_list); } }); }); @@ -1137,12 +1207,10 @@ var PostEditor = (function () { var _splitListAtItem2 = this._splitListAtItem(listSection, section); - var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 3); + var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 2); - var prev = _splitListAtItem22[0]; var mid = _splitListAtItem22[1]; - var next = _splitListAtItem22[2]; - // jshint ignore:line + this.replaceSection(mid, markupSection); return markupSection; } @@ -1162,12 +1230,10 @@ var PostEditor = (function () { if (section.isListItem) { var _splitListAtItem3 = this._splitListAtItem(section.parent, section); - var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 3); + var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 2); - var prev = _splitListAtItem32[0]; var mid = _splitListAtItem32[1]; - var next = _splitListAtItem32[2]; - // jshint ignore:line + sectionToReplace = mid; } else { sectionToReplace = section; @@ -1273,33 +1339,33 @@ var PostEditor = (function () { }, { key: 'removeAllSections', value: function removeAllSections() { - var _this15 = this; + var _this16 = this; this.editor.post.sections.toArray().forEach(function (section) { - _this15.removeSection(section); + _this16.removeSection(section); }); } }, { key: 'migrateSectionsFromPost', value: function migrateSectionsFromPost(post) { - var _this16 = this; + var _this17 = this; post.sections.toArray().forEach(function (section) { post.sections.remove(section); - _this16.insertSectionBefore(_this16.editor.post.sections, section, null); + _this17.insertSectionBefore(_this17.editor.post.sections, section, null); }); } }, { key: '_scheduleListRemovalIfEmpty', value: function _scheduleListRemovalIfEmpty(listSection) { - var _this17 = this; + var _this18 = this; this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () { // if the list is attached and blank after we do other rendering stuff, // remove it var isAttached = !!listSection.parent; if (isAttached && listSection.isBlank) { - _this17.removeSection(listSection); + _this18.removeSection(listSection); } }); } diff --git a/website/commonjs/mobiledoc-kit/editor/post/post-inserter.js b/website/commonjs/mobiledoc-kit/editor/post/post-inserter.js index 598b79d96..705bcb299 100644 --- a/website/commonjs/mobiledoc-kit/editor/post/post-inserter.js +++ b/website/commonjs/mobiledoc-kit/editor/post/post-inserter.js @@ -156,12 +156,10 @@ var Visitor = (function () { } else { var _breakListAtCursor2 = this._breakListAtCursor(); - var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 3); + var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 2); - var pre = _breakListAtCursor22[0]; var blank = _breakListAtCursor22[1]; - var post = _breakListAtCursor22[2]; - // jshint ignore:line + this.cursorPosition = blank.tailPosition(); } } @@ -236,13 +234,11 @@ var Visitor = (function () { }, { key: '_breakMarkerableAtCursor', value: function _breakMarkerableAtCursor() { - var _postEditor$splitSection = // jshint ignore:line - this.postEditor.splitSection(this.cursorPosition); + var _postEditor$splitSection = this.postEditor.splitSection(this.cursorPosition); - var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 2); + var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 1); var pre = _postEditor$splitSection2[0]; - var post = _postEditor$splitSection2[1]; this.cursorPosition = pre.tailPosition(); } @@ -348,7 +344,9 @@ var Inserter = (function () { key: 'insert', value: function insert(cursorPosition, newPost) { var visitor = new Visitor(this, cursorPosition); - visitor.visit(newPost); + if (!newPost.isBlank) { + visitor.visit(newPost); + } return visitor.cursorPosition; } }]); diff --git a/website/commonjs/mobiledoc-kit/editor/text-input-handler.js b/website/commonjs/mobiledoc-kit/editor/text-input-handler.js index 233b0f9df..e0bbbe5da 100644 --- a/website/commonjs/mobiledoc-kit/editor/text-input-handler.js +++ b/website/commonjs/mobiledoc-kit/editor/text-input-handler.js @@ -12,6 +12,8 @@ var _utilsAssert = require('../utils/assert'); var _utilsDeprecate = require('../utils/deprecate'); +var _utilsCharacters = require('../utils/characters'); + var TextInputHandler = (function () { function TextInputHandler(editor) { _classCallCheck(this, TextInputHandler); @@ -54,13 +56,29 @@ var TextInputHandler = (function () { } } }, { + key: 'handleNewLine', + value: function handleNewLine() { + var editor = this.editor; + + var matchedHandler = this._findHandler(_utilsCharacters.ENTER); + if (matchedHandler) { + var _matchedHandler2 = _slicedToArray(matchedHandler, 2); + + var handler = _matchedHandler2[0]; + var matches = _matchedHandler2[1]; + + handler.run(editor, matches); + } + } + }, { key: '_findHandler', value: function _findHandler() { + var string = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0]; var _editor$range = this.editor.range; var head = _editor$range.head; var section = _editor$range.head.section; - var preText = section.textUntil(head); + var preText = section.textUntil(head) + string; for (var i = 0; i < this._handlers.length; i++) { var handler = this._handlers[i]; diff --git a/website/commonjs/mobiledoc-kit/editor/ui.js b/website/commonjs/mobiledoc-kit/editor/ui.js index 2ff363289..66ff69290 100644 --- a/website/commonjs/mobiledoc-kit/editor/ui.js +++ b/website/commonjs/mobiledoc-kit/editor/ui.js @@ -65,19 +65,14 @@ function toggleLink(editor) { var hasLink = editor.detectMarkupInRange(range, 'a'); if (hasLink) { - editor.run(function (postEditor) { - return postEditor.toggleMarkup('a'); - }); + editor.toggleMarkup('a'); } else { showPrompt('Enter a URL', defaultUrl, function (url) { if (!url) { return; } - editor.run(function (postEditor) { - var markup = postEditor.builder.createMarkup('a', { href: url }); - postEditor.toggleMarkup(markup); - }); + editor.toggleMarkup('a', { href: url }); }); } } \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/index.js b/website/commonjs/mobiledoc-kit/index.js index 3ce3f5bd0..a7179218a 100644 --- a/website/commonjs/mobiledoc-kit/index.js +++ b/website/commonjs/mobiledoc-kit/index.js @@ -18,6 +18,8 @@ var _utilsMobiledocError = require('./utils/mobiledoc-error'); var _version = require('./version'); +var _renderersMobiledoc = require('./renderers/mobiledoc'); + var Mobiledoc = { Editor: _editorEditor['default'], UI: UI, @@ -25,7 +27,8 @@ var Mobiledoc = { Range: _utilsCursorRange['default'], Position: _utilsCursorPosition['default'], Error: _utilsMobiledocError['default'], - VERSION: _version['default'] + VERSION: _version['default'], + MOBILEDOC_VERSION: _renderersMobiledoc.MOBILEDOC_VERSION }; function registerGlobal(global) { @@ -36,4 +39,5 @@ exports.Editor = _editorEditor['default']; exports.UI = UI; exports.Range = _utilsCursorRange['default']; exports.Position = _utilsCursorPosition['default']; +exports.MOBILEDOC_VERSION = _renderersMobiledoc.MOBILEDOC_VERSION; exports['default'] = Mobiledoc; \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/models/_attributable.js b/website/commonjs/mobiledoc-kit/models/_attributable.js new file mode 100644 index 000000000..990cb43a0 --- /dev/null +++ b/website/commonjs/mobiledoc-kit/models/_attributable.js @@ -0,0 +1,47 @@ +'use strict'; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + +exports.attributable = attributable; + +var _utilsObjectUtils = require('../utils/object-utils'); + +var _utilsArrayUtils = require('../utils/array-utils'); + +var VALID_ATTRIBUTES = ['data-md-text-align']; + +exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; +/* + * A "mixin" to add section attribute support + * to markup and list sections. + */ + +function attributable(ctx) { + ctx.attributes = {}; + + ctx.hasAttribute = function (key) { + return key in ctx.attributes; + }; + + ctx.setAttribute = function (key, value) { + if (!(0, _utilsArrayUtils.contains)(VALID_ATTRIBUTES, key)) { + throw new Error('Invalid attribute "' + key + '" was passed. Constrain attributes to the spec-compliant whitelist.'); + } + ctx.attributes[key] = value; + }; + ctx.removeAttribute = function (key) { + delete ctx.attributes[key]; + }; + ctx.getAttribute = function (key) { + return ctx.attributes[key]; + }; + ctx.eachAttribute = function (cb) { + (0, _utilsObjectUtils.entries)(ctx.attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return cb(k, v); + }); + }; +} \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/models/_section.js b/website/commonjs/mobiledoc-kit/models/_section.js index 8d4b5c6f4..db01431b1 100644 --- a/website/commonjs/mobiledoc-kit/models/_section.js +++ b/website/commonjs/mobiledoc-kit/models/_section.js @@ -120,7 +120,7 @@ var Section = (function (_LinkedItem) { value: function nextLeafSection() { var next = this.next; if (next) { - if (!!next.items) { + if (next.items) { return next.items.head; } else { return next; @@ -146,7 +146,7 @@ var Section = (function (_LinkedItem) { var prev = this.prev; if (prev) { - if (!!prev.items) { + if (prev.items) { return prev.items.tail; } else { return prev; diff --git a/website/commonjs/mobiledoc-kit/models/list-section.js b/website/commonjs/mobiledoc-kit/models/list-section.js index 0eedf687f..854dbf922 100644 --- a/website/commonjs/mobiledoc-kit/models/list-section.js +++ b/website/commonjs/mobiledoc-kit/models/list-section.js @@ -1,25 +1,31 @@ 'use strict'; +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); -var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; +var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var _utilsLinkedList = require('../utils/linked-list'); - -var _utilsArrayUtils = require('../utils/array-utils'); - var _types = require('./types'); var _section = require('./_section'); +var _attributable = require('./_attributable'); + +var _utilsLinkedList = require('../utils/linked-list'); + +var _utilsArrayUtils = require('../utils/array-utils'); + var _utilsDomUtils = require('../utils/dom-utils'); var _utilsAssert = require('../utils/assert'); +var _utilsObjectUtils = require('../utils/object-utils'); + var VALID_LIST_SECTION_TAGNAMES = ['ul', 'ol'].map(_utilsDomUtils.normalizeTagName); exports.VALID_LIST_SECTION_TAGNAMES = VALID_LIST_SECTION_TAGNAMES; @@ -31,10 +37,12 @@ var ListSection = (function (_Section) { _inherits(ListSection, _Section); function ListSection() { + var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; + var _this = this; - var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, ListSection); @@ -43,6 +51,15 @@ var ListSection = (function (_Section) { this.isListSection = true; this.isLeafSection = false; + (0, _attributable.attributable)(this); + (0, _utilsObjectUtils.entries)(attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return _this.setAttribute(k, v); + }); + this.items = new _utilsLinkedList['default']({ adoptItem: function adoptItem(i) { (0, _utilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem); diff --git a/website/commonjs/mobiledoc-kit/models/markup-section.js b/website/commonjs/mobiledoc-kit/models/markup-section.js index f5e883a8d..3bd80794b 100644 --- a/website/commonjs/mobiledoc-kit/models/markup-section.js +++ b/website/commonjs/mobiledoc-kit/models/markup-section.js @@ -1,8 +1,10 @@ 'use strict'; +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); -var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; +var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -10,11 +12,15 @@ function _inherits(subClass, superClass) { if (typeof superClass !== 'function' var _markerable = require('./_markerable'); +var _attributable = require('./_attributable'); + +var _types = require('./types'); + var _utilsDomUtils = require('../utils/dom-utils'); var _utilsArrayUtils = require('../utils/array-utils'); -var _types = require('./types'); +var _utilsObjectUtils = require('../utils/object-utils'); // valid values of `tagName` for a MarkupSection var VALID_MARKUP_SECTION_TAGNAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_utilsDomUtils.normalizeTagName); @@ -33,11 +39,25 @@ var MarkupSection = (function (_Markerable) { function MarkupSection() { var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; + + var _this = this; + var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, MarkupSection); _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _types.MARKUP_SECTION_TYPE, tagName, markers); + + (0, _attributable.attributable)(this); + (0, _utilsObjectUtils.entries)(attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return _this.setAttribute(k, v); + }); + this.isMarkupSection = true; } @@ -50,7 +70,7 @@ var MarkupSection = (function (_Markerable) { key: 'splitAtMarker', value: function splitAtMarker(marker) { var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; - var beforeSection = this.builder.createMarkupSection(this.tagName, []); + var beforeSection = this.builder.createMarkupSection(this.tagName, [], false, this.attributes); var afterSection = this.builder.createMarkupSection(); return this._redistributeMarkers(beforeSection, afterSection, marker, offset); diff --git a/website/commonjs/mobiledoc-kit/models/markup.js b/website/commonjs/mobiledoc-kit/models/markup.js index 75eeddc37..f1aefcc64 100644 --- a/website/commonjs/mobiledoc-kit/models/markup.js +++ b/website/commonjs/mobiledoc-kit/models/markup.js @@ -21,6 +21,12 @@ exports.VALID_MARKUP_TAGNAMES = VALID_MARKUP_TAGNAMES; var VALID_ATTRIBUTES = ['href', 'rel']; exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; +/** + * A Markup is similar with an inline HTML tag that might be added to + * text to modify its meaning and/or display. Examples of types of markup + * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links). + * @property {String} tagName + */ var Markup = (function () { /* @@ -42,6 +48,12 @@ var Markup = (function () { (0, _utilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1); } + /** + * Whether text in the forward direction of the cursor (i.e. to the right in ltr text) + * should be considered to have this markup applied to it. + * @private + */ + _createClass(Markup, [{ key: 'isForwardInclusive', value: function isForwardInclusive() { @@ -57,6 +69,11 @@ var Markup = (function () { value: function hasTag(tagName) { return this.tagName === (0, _utilsDomUtils.normalizeTagName)(tagName); } + + /** + * Returns the attribute value + * @param {String} name, e.g. "href" + */ }, { key: 'getAttribute', value: function getAttribute(name) { diff --git a/website/commonjs/mobiledoc-kit/models/post-node-builder.js b/website/commonjs/mobiledoc-kit/models/post-node-builder.js index d74939a0d..b400d61a4 100644 --- a/website/commonjs/mobiledoc-kit/models/post-node-builder.js +++ b/website/commonjs/mobiledoc-kit/models/post-node-builder.js @@ -107,9 +107,10 @@ var PostNodeBuilder = (function () { var tagName = arguments.length <= 0 || arguments[0] === undefined ? _modelsMarkupSection.DEFAULT_TAG_NAME : arguments[0]; var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; + var attributes = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; tagName = (0, _utilsDomUtils.normalizeTagName)(tagName); - var section = new _modelsMarkupSection['default'](tagName, markers); + var section = new _modelsMarkupSection['default'](tagName, markers, attributes); if (isGenerated) { section.isGenerated = true; } @@ -121,9 +122,10 @@ var PostNodeBuilder = (function () { value: function createListSection() { var tagName = arguments.length <= 0 || arguments[0] === undefined ? _modelsListSection.DEFAULT_TAG_NAME : arguments[0]; var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; tagName = (0, _utilsDomUtils.normalizeTagName)(tagName); - var section = new _modelsListSection['default'](tagName, items); + var section = new _modelsListSection['default'](tagName, items, attributes); section.builder = this; return section; } diff --git a/website/commonjs/mobiledoc-kit/models/post.js b/website/commonjs/mobiledoc-kit/models/post.js index 4f25054e3..f4bb301f1 100644 --- a/website/commonjs/mobiledoc-kit/models/post.js +++ b/website/commonjs/mobiledoc-kit/models/post.js @@ -199,7 +199,7 @@ var Post = (function () { if (next) { if (next.isLeafSection) { return next; - } else if (!!next.items) { + } else if (next.items) { return next.items.head; } else { (0, _utilsAssert['default'])('Cannot determine next section from non-leaf-section', false); @@ -249,6 +249,7 @@ var Post = (function () { }); } else { newSection = section.clone(); + sectionParent = post; } if (sectionParent) { sectionParent.sections.append(newSection); diff --git a/website/commonjs/mobiledoc-kit/parsers/dom.js b/website/commonjs/mobiledoc-kit/parsers/dom.js index c2b0d5e81..79cdd313e 100644 --- a/website/commonjs/mobiledoc-kit/parsers/dom.js +++ b/website/commonjs/mobiledoc-kit/parsers/dom.js @@ -3,6 +3,7 @@ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); exports.transformHTMLText = transformHTMLText; +exports.trimSectionText = trimSectionText; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -32,6 +33,17 @@ function transformHTMLText(textContent) { return text; } +function trimSectionText(section) { + if (section.isMarkerable && section.markers.length) { + var _section$markers = section.markers; + var head = _section$markers.head; + var tail = _section$markers.tail; + + head.value = head.value.replace(/^\s+/, ''); + tail.value = tail.value.replace(/\s+$/, ''); + } +} + function isGoogleDocsContainer(element) { return !(0, _utilsDomUtils.isTextNode)(element) && !(0, _utilsDomUtils.isCommentNode)(element) && (0, _utilsDomUtils.normalizeTagName)(element.tagName) === (0, _utilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id); } @@ -104,6 +116,12 @@ var DOMParser = (function () { _this.appendSections(post, sections); }); + // trim leading/trailing whitespace of markerable sections to avoid + // unnessary whitespace from indented HTML input + (0, _utilsArrayUtils.forEach)(post.sections, function (section) { + return trimSectionText(section); + }); + return post; } }, { @@ -118,7 +136,9 @@ var DOMParser = (function () { }, { key: 'appendSection', value: function appendSection(post, section) { - if (section.isBlank || section.isMarkerable && trim(section.text) === '') { + if (section.isBlank || section.isMarkerable && trim(section.text) === "" && !(0, _utilsArrayUtils.any)(section.markers, function (marker) { + return marker.isAtom; + })) { return; } diff --git a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-2.js b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-2.js index feb4e8880..43ba20fe5 100644 --- a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-2.js +++ b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-2.js @@ -31,7 +31,6 @@ var MobiledocParser = (function () { _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sectionData = _ref.sections; try { @@ -107,7 +106,6 @@ var MobiledocParser = (function () { value: function parseCardSection(_ref3, post) { var _ref32 = _slicedToArray(_ref3, 3); - var type = _ref32[0]; var name = _ref32[1]; var payload = _ref32[2]; @@ -119,7 +117,6 @@ var MobiledocParser = (function () { value: function parseImageSection(_ref4, post) { var _ref42 = _slicedToArray(_ref4, 2); - var type = _ref42[0]; var src = _ref42[1]; var section = this.builder.createImageSection(src); @@ -130,7 +127,6 @@ var MobiledocParser = (function () { value: function parseMarkupSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 3); - var type = _ref52[0]; var tagName = _ref52[1]; var markers = _ref52[2]; @@ -150,7 +146,6 @@ var MobiledocParser = (function () { value: function parseListSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 3); - var type = _ref62[0]; var tagName = _ref62[1]; var items = _ref62[2]; diff --git a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-1.js b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-1.js index 6b50c8825..47746a437 100644 --- a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-1.js +++ b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-1.js @@ -31,7 +31,6 @@ var MobiledocParser = (function () { _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sections = _ref.sections; var markerTypes = _ref.markups; var cardTypes = _ref.cards; @@ -162,7 +161,6 @@ var MobiledocParser = (function () { value: function parseCardSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 2); - var type = _ref52[0]; var cardIndex = _ref52[1]; var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); @@ -180,7 +178,6 @@ var MobiledocParser = (function () { value: function parseImageSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 2); - var type = _ref62[0]; var src = _ref62[1]; var section = this.builder.createImageSection(src); @@ -191,7 +188,6 @@ var MobiledocParser = (function () { value: function parseMarkupSection(_ref7, post) { var _ref72 = _slicedToArray(_ref7, 3); - var type = _ref72[0]; var tagName = _ref72[1]; var markers = _ref72[2]; @@ -211,7 +207,6 @@ var MobiledocParser = (function () { value: function parseListSection(_ref8, post) { var _ref82 = _slicedToArray(_ref8, 3); - var type = _ref82[0]; var tagName = _ref82[1]; var items = _ref82[2]; @@ -272,13 +267,17 @@ var MobiledocParser = (function () { case _renderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); case _renderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE: - var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value), - _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3), - atomName = _getAtomTypeFromIndex2[0], - atomValue = _getAtomTypeFromIndex2[1], - atomPayload = _getAtomTypeFromIndex2[2]; + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); - return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; + + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: (0, _utilsAssert['default'])('Unexpected marker type ' + type, false); } diff --git a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-2.js b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-2.js new file mode 100644 index 000000000..ee9521ecd --- /dev/null +++ b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3-2.js @@ -0,0 +1,314 @@ +'use strict'; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +var _renderersMobiledoc032 = require('../../renderers/mobiledoc/0-3-2'); + +var _utilsArrayUtils = require('../../utils/array-utils'); + +var _utilsAssert = require('../../utils/assert'); + +var _utilsObjectUtils = require('../../utils/object-utils'); + +/* + * Parses from mobiledoc -> post + */ + +var MobiledocParser = (function () { + function MobiledocParser(builder) { + _classCallCheck(this, MobiledocParser); + + this.builder = builder; + } + + /** + * @param {Mobiledoc} + * @return {Post} + */ + + _createClass(MobiledocParser, [{ + key: 'parse', + value: function parse(_ref) { + var sections = _ref.sections; + var markerTypes = _ref.markups; + var cardTypes = _ref.cards; + var atomTypes = _ref.atoms; + + try { + var post = this.builder.createPost(); + + this.markups = []; + this.markerTypes = this.parseMarkerTypes(markerTypes); + this.cardTypes = this.parseCardTypes(cardTypes); + this.atomTypes = this.parseAtomTypes(atomTypes); + this.parseSections(sections, post); + + return post; + } catch (e) { + (0, _utilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false); + } + } + }, { + key: 'parseMarkerTypes', + value: function parseMarkerTypes(markerTypes) { + var _this = this; + + return markerTypes.map(function (markerType) { + return _this.parseMarkerType(markerType); + }); + } + }, { + key: 'parseMarkerType', + value: function parseMarkerType(_ref2) { + var _ref22 = _slicedToArray(_ref2, 2); + + var tagName = _ref22[0]; + var attributesArray = _ref22[1]; + + var attributesObject = (0, _utilsArrayUtils.kvArrayToObject)(attributesArray || []); + return this.builder.createMarkup(tagName, attributesObject); + } + }, { + key: 'parseCardTypes', + value: function parseCardTypes(cardTypes) { + var _this2 = this; + + return cardTypes.map(function (cardType) { + return _this2.parseCardType(cardType); + }); + } + }, { + key: 'parseCardType', + value: function parseCardType(_ref3) { + var _ref32 = _slicedToArray(_ref3, 2); + + var cardName = _ref32[0]; + var cardPayload = _ref32[1]; + + return [cardName, cardPayload]; + } + }, { + key: 'parseAtomTypes', + value: function parseAtomTypes(atomTypes) { + var _this3 = this; + + return atomTypes.map(function (atomType) { + return _this3.parseAtomType(atomType); + }); + } + }, { + key: 'parseAtomType', + value: function parseAtomType(_ref4) { + var _ref42 = _slicedToArray(_ref4, 3); + + var atomName = _ref42[0]; + var atomValue = _ref42[1]; + var atomPayload = _ref42[2]; + + return [atomName, atomValue, atomPayload]; + } + }, { + key: 'parseSections', + value: function parseSections(sections, post) { + var _this4 = this; + + sections.forEach(function (section) { + return _this4.parseSection(section, post); + }); + } + }, { + key: 'parseSection', + value: function parseSection(section, post) { + var _section = _slicedToArray(section, 1); + + var type = _section[0]; + + switch (type) { + case _renderersMobiledoc032.MOBILEDOC_MARKUP_SECTION_TYPE: + this.parseMarkupSection(section, post); + break; + case _renderersMobiledoc032.MOBILEDOC_IMAGE_SECTION_TYPE: + this.parseImageSection(section, post); + break; + case _renderersMobiledoc032.MOBILEDOC_CARD_SECTION_TYPE: + this.parseCardSection(section, post); + break; + case _renderersMobiledoc032.MOBILEDOC_LIST_SECTION_TYPE: + this.parseListSection(section, post); + break; + default: + (0, _utilsAssert['default'])('Unexpected section type ${type}', false); + } + } + }, { + key: 'getAtomTypeFromIndex', + value: function getAtomTypeFromIndex(index) { + var atomType = this.atomTypes[index]; + (0, _utilsAssert['default'])('No atom definition found at index ' + index, !!atomType); + return atomType; + } + }, { + key: 'getCardTypeFromIndex', + value: function getCardTypeFromIndex(index) { + var cardType = this.cardTypes[index]; + (0, _utilsAssert['default'])('No card definition found at index ' + index, !!cardType); + return cardType; + } + }, { + key: 'parseCardSection', + value: function parseCardSection(_ref5, post) { + var _ref52 = _slicedToArray(_ref5, 2); + + var cardIndex = _ref52[1]; + + var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); + + var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2); + + var name = _getCardTypeFromIndex2[0]; + var payload = _getCardTypeFromIndex2[1]; + + var section = this.builder.createCardSection(name, payload); + post.sections.append(section); + } + }, { + key: 'parseImageSection', + value: function parseImageSection(_ref6, post) { + var _ref62 = _slicedToArray(_ref6, 2); + + var src = _ref62[1]; + + var section = this.builder.createImageSection(src); + post.sections.append(section); + } + }, { + key: 'parseMarkupSection', + value: function parseMarkupSection(_ref7, post) { + var _ref72 = _slicedToArray(_ref7, 4); + + var tagName = _ref72[1]; + var markers = _ref72[2]; + var attributesArray = _ref72[3]; + + var section = this.builder.createMarkupSection(tagName); + post.sections.append(section); + if (attributesArray) { + (0, _utilsObjectUtils.entries)((0, _utilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref8) { + var _ref82 = _slicedToArray(_ref8, 2); + + var key = _ref82[0]; + var value = _ref82[1]; + + section.setAttribute(key, value); + }); + } + this.parseMarkers(markers, section); + // Strip blank markers after they have been created. This ensures any + // markup they include has been correctly populated. + (0, _utilsArrayUtils.filter)(section.markers, function (m) { + return m.isBlank; + }).forEach(function (m) { + section.markers.remove(m); + }); + } + }, { + key: 'parseListSection', + value: function parseListSection(_ref9, post) { + var _ref92 = _slicedToArray(_ref9, 4); + + var tagName = _ref92[1]; + var items = _ref92[2]; + var attributesArray = _ref92[3]; + + var section = this.builder.createListSection(tagName); + post.sections.append(section); + if (attributesArray) { + (0, _utilsObjectUtils.entries)((0, _utilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref10) { + var _ref102 = _slicedToArray(_ref10, 2); + + var key = _ref102[0]; + var value = _ref102[1]; + + section.setAttribute(key, value); + }); + } + this.parseListItems(items, section); + } + }, { + key: 'parseListItems', + value: function parseListItems(items, section) { + var _this5 = this; + + items.forEach(function (i) { + return _this5.parseListItem(i, section); + }); + } + }, { + key: 'parseListItem', + value: function parseListItem(markers, section) { + var item = this.builder.createListItem(); + this.parseMarkers(markers, item); + section.items.append(item); + } + }, { + key: 'parseMarkers', + value: function parseMarkers(markers, parent) { + var _this6 = this; + + markers.forEach(function (m) { + return _this6.parseMarker(m, parent); + }); + } + }, { + key: 'parseMarker', + value: function parseMarker(_ref11, parent) { + var _this7 = this; + + var _ref112 = _slicedToArray(_ref11, 4); + + var type = _ref112[0]; + var markerTypeIndexes = _ref112[1]; + var closeCount = _ref112[2]; + var value = _ref112[3]; + + markerTypeIndexes.forEach(function (index) { + _this7.markups.push(_this7.markerTypes[index]); + }); + + var marker = this.buildMarkerType(type, value); + parent.markers.append(marker); + + this.markups = this.markups.slice(0, this.markups.length - closeCount); + } + }, { + key: 'buildMarkerType', + value: function buildMarkerType(type, value) { + switch (type) { + case _renderersMobiledoc032.MOBILEDOC_MARKUP_MARKER_TYPE: + return this.builder.createMarker(value, this.markups.slice()); + case _renderersMobiledoc032.MOBILEDOC_ATOM_MARKER_TYPE: + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; + + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } + default: + (0, _utilsAssert['default'])('Unexpected marker type ' + type, false); + } + } + }]); + + return MobiledocParser; +})(); + +exports['default'] = MobiledocParser; \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3.js b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3.js index bb5feb4dc..6c83737a7 100644 --- a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3.js +++ b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/0-3.js @@ -31,7 +31,6 @@ var MobiledocParser = (function () { _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sections = _ref.sections; var markerTypes = _ref.markups; var cardTypes = _ref.cards; @@ -162,7 +161,6 @@ var MobiledocParser = (function () { value: function parseCardSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 2); - var type = _ref52[0]; var cardIndex = _ref52[1]; var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); @@ -180,7 +178,6 @@ var MobiledocParser = (function () { value: function parseImageSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 2); - var type = _ref62[0]; var src = _ref62[1]; var section = this.builder.createImageSection(src); @@ -191,7 +188,6 @@ var MobiledocParser = (function () { value: function parseMarkupSection(_ref7, post) { var _ref72 = _slicedToArray(_ref7, 3); - var type = _ref72[0]; var tagName = _ref72[1]; var markers = _ref72[2]; @@ -211,7 +207,6 @@ var MobiledocParser = (function () { value: function parseListSection(_ref8, post) { var _ref82 = _slicedToArray(_ref8, 3); - var type = _ref82[0]; var tagName = _ref82[1]; var items = _ref82[2]; @@ -272,13 +267,17 @@ var MobiledocParser = (function () { case _renderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); case _renderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE: - var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value), - _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3), - atomName = _getAtomTypeFromIndex2[0], - atomValue = _getAtomTypeFromIndex2[1], - atomPayload = _getAtomTypeFromIndex2[2]; + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); - return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; + + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: (0, _utilsAssert['default'])('Unexpected marker type ' + type, false); } diff --git a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/index.js b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/index.js index 77369a78b..a7173b3ce 100644 --- a/website/commonjs/mobiledoc-kit/parsers/mobiledoc/index.js +++ b/website/commonjs/mobiledoc-kit/parsers/mobiledoc/index.js @@ -6,12 +6,16 @@ var _2 = require('./0-3'); var _3 = require('./0-3-1'); +var _4 = require('./0-3-2'); + var _renderersMobiledoc02 = require('../../renderers/mobiledoc/0-2'); var _renderersMobiledoc03 = require('../../renderers/mobiledoc/0-3'); var _renderersMobiledoc031 = require('../../renderers/mobiledoc/0-3-1'); +var _renderersMobiledoc032 = require('../../renderers/mobiledoc/0-3-2'); + var _utilsAssert = require('../../utils/assert'); function parseVersion(mobiledoc) { @@ -28,6 +32,8 @@ exports['default'] = { return new _2['default'](builder).parse(mobiledoc); case _renderersMobiledoc031.MOBILEDOC_VERSION: return new _3['default'](builder).parse(mobiledoc); + case _renderersMobiledoc032.MOBILEDOC_VERSION: + return new _4['default'](builder).parse(mobiledoc); default: (0, _utilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false); } diff --git a/website/commonjs/mobiledoc-kit/parsers/section.js b/website/commonjs/mobiledoc-kit/parsers/section.js index f77ba50f5..4c619a1cf 100644 --- a/website/commonjs/mobiledoc-kit/parsers/section.js +++ b/website/commonjs/mobiledoc-kit/parsers/section.js @@ -28,8 +28,7 @@ var SKIPPABLE_ELEMENT_TAG_NAMES = ['style', 'head', 'title', 'meta'].map(_utilsD var NEWLINES = /\n/g; function sanitize(text) { - text = text.replace(NEWLINES, ''); - return text; + return text.replace(NEWLINES, ' '); } /** @@ -61,11 +60,17 @@ var SectionParser = (function () { this._updateStateFromElement(element); - var childNodes = (0, _utilsDomUtils.isTextNode)(element) ? [element] : element.childNodes; + var finished = false; + + // top-level text nodes will be run through parseNode later so avoid running + // the node through parserPlugins twice + if (!(0, _utilsDomUtils.isTextNode)(element)) { + finished = this.runPlugins(element); + } + + if (!finished) { + var childNodes = (0, _utilsDomUtils.isTextNode)(element) ? [element] : element.childNodes; - if (this.state.section.isListSection) { - this.parseListItems(childNodes); - } else { (0, _utilsArrayUtils.forEach)(childNodes, function (el) { _this.parseNode(el); }); @@ -75,39 +80,30 @@ var SectionParser = (function () { return this.sections; } - }, { - key: 'parseListItems', - value: function parseListItems(childNodes) { - var _this2 = this; - - var state = this.state; - - (0, _utilsArrayUtils.forEach)(childNodes, function (el) { - var parsed = new _this2.constructor(_this2.builder).parse(el); - var li = parsed[0]; - if (li && li.isListItem) { - state.section.items.append(li); - } - }); - } }, { key: 'runPlugins', value: function runPlugins(node) { - var _this3 = this; + var _this2 = this; var isNodeFinished = false; var env = { addSection: function addSection(section) { - _this3._closeCurrentSection(); - _this3.sections.push(section); + // avoid creating empty paragraphs due to wrapper elements around + // parser-plugin-handled elements + if (_this2.state.section.isMarkerable && !_this2.state.text && !_this2.state.section.text) { + _this2.state.section = null; + } else { + _this2._closeCurrentSection(); + } + _this2.sections.push(section); }, addMarkerable: function addMarkerable(marker) { - var state = _this3.state; + var state = _this2.state; var section = state.section; (0, _utilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable); if (state.text) { - _this3._createMarker(); + _this2._createMarker(); } section.markers.append(marker); }, @@ -124,9 +120,13 @@ var SectionParser = (function () { } return false; } + + /* eslint-disable complexity */ }, { key: 'parseNode', value: function parseNode(node) { + var _this3 = this; + if (!this.state.section) { this._updateStateFromElement(node); } @@ -136,6 +136,72 @@ var SectionParser = (function () { return; } + // handle closing the current section and starting a new one if we hit a + // new-section-creating element. + if (this.state.section && !(0, _utilsDomUtils.isTextNode)(node) && node.tagName) { + var tagName = (0, _utilsDomUtils.normalizeTagName)(node.tagName); + var isListSection = (0, _utilsArrayUtils.contains)(_modelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName); + var isListItem = (0, _utilsArrayUtils.contains)(_modelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName); + var isMarkupSection = (0, _utilsArrayUtils.contains)(_modelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName); + var isNestedListSection = isListSection && this.state.section.isListItem; + var lastSection = this.sections[this.sections.length - 1]; + + // we can hit a list item after parsing a nested list, when that happens + // and the lists are of different types we need to make sure we switch + // the list type back + if (isListItem && lastSection && lastSection.isListSection) { + var parentElement = node.parentElement; + var parentElementTagName = (0, _utilsDomUtils.normalizeTagName)(parentElement.tagName); + if (parentElementTagName !== lastSection.tagName) { + this._closeCurrentSection(); + this._updateStateFromElement(parentElement); + } + } + + // if we've broken out of a list due to nested section-level elements we + // can hit the next list item without having a list section in the current + // state. In this instance we find the parent list node and use it to + // re-initialize the state with a new list section + if (isListItem && !(this.state.section.isListItem || this.state.section.isListSection) && !lastSection.isListSection) { + this._closeCurrentSection(); + this._updateStateFromElement(node.parentElement); + } + + // if we have consecutive list sections of different types (ul, ol) then + // ensure we close the current section and start a new one + var isNewListSection = lastSection && lastSection.isListSection && this.state.section.isListItem && isListSection && tagName !== lastSection.tagName; + + if (isNewListSection || isListSection && !isNestedListSection || isMarkupSection || isListItem) { + // don't break out of the list for list items that contain a single

    . + // deals with typical case of

  • Text

  • Text

  • + if (this.state.section.isListItem && tagName === 'p' && !node.nextSibling && (0, _utilsArrayUtils.contains)(_modelsListItem.VALID_LIST_ITEM_TAGNAMES, (0, _utilsDomUtils.normalizeTagName)(node.parentElement.tagName))) { + this.parseElementNode(node); + return; + } + + // avoid creating empty paragraphs due to wrapper elements around + // section-creating elements + if (this.state.section.isMarkerable && !this.state.text && this.state.section.markers.length === 0) { + this.state.section = null; + } else { + this._closeCurrentSection(); + } + + this._updateStateFromElement(node); + } + + if (this.state.section.isListSection) { + // ensure the list section is closed and added to the sections list. + // _closeCurrentSection handles pushing list items onto the list section + this._closeCurrentSection(); + + (0, _utilsArrayUtils.forEach)(node.childNodes, function (node) { + _this3.parseNode(node); + }); + return; + } + } + switch (node.nodeType) { case _utilsDomUtils.NODE_TYPES.TEXT: this.parseTextNode(node); @@ -154,7 +220,7 @@ var SectionParser = (function () { var state = this.state; var markups = this._markupsFromElement(element); - if (markups.length && state.text.length) { + if (markups.length && state.text.length && state.section.isMarkerable) { this._createMarker(); } (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups)); @@ -163,7 +229,7 @@ var SectionParser = (function () { _this4.parseNode(node); }); - if (markups.length && state.text.length) { + if (markups.length && state.text.length && state.section.isMarkerable) { // create the marker started for this node this._createMarker(); } @@ -193,17 +259,41 @@ var SectionParser = (function () { var sections = this.sections; var state = this.state; + var lastSection = sections[sections.length - 1]; + if (!state.section) { return; } // close a trailing text node if it exists - if (state.text.length) { + if (state.text.length && state.section.isMarkerable) { this._createMarker(); } - sections.push(state.section); + // push listItems onto the listSection or add a new section + if (state.section.isListItem && lastSection && lastSection.isListSection) { + (0, _parsersDom.trimSectionText)(state.section); + lastSection.items.append(state.section); + } else { + // avoid creating empty markup sections, especially useful for indented source + if (state.section.isMarkerable && !state.section.text.trim() && !(0, _utilsArrayUtils.any)(state.section.markers, function (marker) { + return marker.isAtom; + })) { + state.section = null; + state.text = ''; + return; + } + + // remove empty list sections before creating a new section + if (lastSection && lastSection.isListSection && lastSection.items.length === 0) { + sections.pop(); + } + + sections.push(state.section); + } + state.section = null; + state.text = ''; } }, { key: '_markupsFromElement', diff --git a/website/commonjs/mobiledoc-kit/parsers/text.js b/website/commonjs/mobiledoc-kit/parsers/text.js index 690b41eb0..46487b9ae 100644 --- a/website/commonjs/mobiledoc-kit/parsers/text.js +++ b/website/commonjs/mobiledoc-kit/parsers/text.js @@ -74,10 +74,12 @@ var TextParser = (function () { switch (type) { case _modelsTypes.LIST_SECTION_TYPE: - var item = this.builder.createListItem(markers); - var list = this.builder.createListSection(tagName, [item]); - section = list; - break; + { + var item = this.builder.createListItem(markers); + var list = this.builder.createListSection(tagName, [item]); + section = list; + break; + } case _modelsTypes.MARKUP_SECTION_TYPE: section = this.builder.createMarkupSection(tagName, markers); break; diff --git a/website/commonjs/mobiledoc-kit/renderers/editor-dom.js b/website/commonjs/mobiledoc-kit/renderers/editor-dom.js index 70529e495..9c4033441 100644 --- a/website/commonjs/mobiledoc-kit/renderers/editor-dom.js +++ b/website/commonjs/mobiledoc-kit/renderers/editor-dom.js @@ -92,6 +92,12 @@ function penultimateParentOf(element, parentElement) { return element; } +function setSectionAttributesOnElement(section, element) { + section.eachAttribute(function (key, value) { + element.setAttribute(key, value); + }); +} + function renderMarkupSection(section) { var element = undefined; if (_modelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) { @@ -101,11 +107,17 @@ function renderMarkupSection(section) { (0, _utilsDomUtils.addClassName)(element, section.tagName); } + setSectionAttributesOnElement(section, element); + return element; } function renderListSection(section) { - return document.createElement(section.tagName); + var element = document.createElement(section.tagName); + + setSectionAttributesOnElement(section, element); + + return element; } function renderListItem() { @@ -635,7 +647,6 @@ var Renderer = (function () { method = postNode.type; (0, _utilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]); - // jshint -W083 this.visitor[method](renderNode, postNode, function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; @@ -643,7 +654,6 @@ var Renderer = (function () { return _this2.visit.apply(_this2, [renderTree].concat(args)); }); - // jshint +W083 renderNode.markClean(); renderNode = this.nodes.shift(); } diff --git a/website/commonjs/mobiledoc-kit/renderers/mobiledoc/0-3-2.js b/website/commonjs/mobiledoc-kit/renderers/mobiledoc/0-3-2.js new file mode 100644 index 000000000..f7e5034d8 --- /dev/null +++ b/website/commonjs/mobiledoc-kit/renderers/mobiledoc/0-3-2.js @@ -0,0 +1,148 @@ +'use strict'; + +var _visitor; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var _utilsCompiler = require('../../utils/compiler'); + +var _utilsArrayUtils = require('../../utils/array-utils'); + +var _modelsTypes = require('../../models/types'); + +var MOBILEDOC_VERSION = '0.3.2'; +exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; +var MOBILEDOC_MARKUP_SECTION_TYPE = 1; +exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE; +var MOBILEDOC_IMAGE_SECTION_TYPE = 2; +exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE; +var MOBILEDOC_LIST_SECTION_TYPE = 3; +exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE; +var MOBILEDOC_CARD_SECTION_TYPE = 10; + +exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE; +var MOBILEDOC_MARKUP_MARKER_TYPE = 0; +exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE; +var MOBILEDOC_ATOM_MARKER_TYPE = 1; + +exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE; +var visitor = (_visitor = {}, _defineProperty(_visitor, _modelsTypes.POST_TYPE, function (node, opcodes) { + opcodes.push(['openPost']); + (0, _utilsCompiler.visitArray)(visitor, node.sections, opcodes); +}), _defineProperty(_visitor, _modelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openMarkupSection', node.tagName, (0, _utilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + (0, _utilsCompiler.visitArray)(visitor, node.markers, opcodes); +}), _defineProperty(_visitor, _modelsTypes.LIST_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openListSection', node.tagName, (0, _utilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + (0, _utilsCompiler.visitArray)(visitor, node.items, opcodes); +}), _defineProperty(_visitor, _modelsTypes.LIST_ITEM_TYPE, function (node, opcodes) { + opcodes.push(['openListItem']); + (0, _utilsCompiler.visitArray)(visitor, node.markers, opcodes); +}), _defineProperty(_visitor, _modelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openImageSection', node.src]); +}), _defineProperty(_visitor, _modelsTypes.CARD_TYPE, function (node, opcodes) { + opcodes.push(['openCardSection', node.name, node.payload]); +}), _defineProperty(_visitor, _modelsTypes.MARKER_TYPE, function (node, opcodes) { + opcodes.push(['openMarker', node.closedMarkups.length, node.value]); + (0, _utilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes); +}), _defineProperty(_visitor, _modelsTypes.MARKUP_TYPE, function (node, opcodes) { + opcodes.push(['openMarkup', node.tagName, (0, _utilsArrayUtils.objectToSortedKVArray)(node.attributes)]); +}), _defineProperty(_visitor, _modelsTypes.ATOM_TYPE, function (node, opcodes) { + opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]); + (0, _utilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes); +}), _visitor); + +var postOpcodeCompiler = { + openMarker: function openMarker(closeCount, value) { + this.markupMarkerIds = []; + this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']); + }, + openMarkupSection: function openMarkupSection(tagName, attributes) { + this.markers = []; + this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]); + }, + openListSection: function openListSection(tagName, attributes) { + this.items = []; + this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]); + }, + openListItem: function openListItem() { + this.markers = []; + this.items.push(this.markers); + }, + openImageSection: function openImageSection(url) { + this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]); + }, + openCardSection: function openCardSection(name, payload) { + var index = this._addCardTypeIndex(name, payload); + this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]); + }, + openAtom: function openAtom(closeCount, name, value, payload) { + var index = this._addAtomTypeIndex(name, value, payload); + this.markupMarkerIds = []; + this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]); + }, + openPost: function openPost() { + this.atomTypes = []; + this.cardTypes = []; + this.markerTypes = []; + this.sections = []; + this.result = { + version: MOBILEDOC_VERSION, + atoms: this.atomTypes, + cards: this.cardTypes, + markups: this.markerTypes, + sections: this.sections + }; + }, + openMarkup: function openMarkup(tagName, attributes) { + var index = this._findOrAddMarkerTypeIndex(tagName, attributes); + this.markupMarkerIds.push(index); + }, + _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) { + var cardType = [cardName, payload]; + this.cardTypes.push(cardType); + return this.cardTypes.length - 1; + }, + _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) { + var atomType = [atomName, atomValue, payload]; + this.atomTypes.push(atomType); + return this.atomTypes.length - 1; + }, + _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) { + if (!this._markerTypeCache) { + this._markerTypeCache = {}; + } + var key = tagName + '-' + attributesArray.join('-'); + + var index = this._markerTypeCache[key]; + if (index === undefined) { + var markerType = [tagName]; + if (attributesArray.length) { + markerType.push(attributesArray); + } + this.markerTypes.push(markerType); + + index = this.markerTypes.length - 1; + this._markerTypeCache[key] = index; + } + + return index; + } +}; + +/** + * Render from post -> mobiledoc + */ +exports['default'] = { + /** + * @param {Post} + * @return {Mobiledoc} + */ + render: function render(post) { + var opcodes = []; + (0, _utilsCompiler.visit)(visitor, post, opcodes); + var compiler = Object.create(postOpcodeCompiler); + (0, _utilsCompiler.compile)(compiler, opcodes); + return compiler.result; + } +}; \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/renderers/mobiledoc/index.js b/website/commonjs/mobiledoc-kit/renderers/mobiledoc/index.js index a4beb6846..a1c4b33bb 100644 --- a/website/commonjs/mobiledoc-kit/renderers/mobiledoc/index.js +++ b/website/commonjs/mobiledoc-kit/renderers/mobiledoc/index.js @@ -6,9 +6,11 @@ var _2 = require('./0-3'); var _3 = require('./0-3-1'); +var _4 = require('./0-3-2'); + var _utilsAssert = require('../../utils/assert'); -var MOBILEDOC_VERSION = _3.MOBILEDOC_VERSION; +var MOBILEDOC_VERSION = _4.MOBILEDOC_VERSION; exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; exports['default'] = { @@ -18,10 +20,12 @@ exports['default'] = { return _['default'].render(post); case _2.MOBILEDOC_VERSION: return _2['default'].render(post); - case undefined: - case null: case _3.MOBILEDOC_VERSION: return _3['default'].render(post); + case undefined: + case null: + case _4.MOBILEDOC_VERSION: + return _4['default'].render(post); default: (0, _utilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false); } diff --git a/website/commonjs/mobiledoc-kit/utils/cursor/position.js b/website/commonjs/mobiledoc-kit/utils/cursor/position.js index b633b4fd7..71d776ede 100644 --- a/website/commonjs/mobiledoc-kit/utils/cursor/position.js +++ b/website/commonjs/mobiledoc-kit/utils/cursor/position.js @@ -23,7 +23,9 @@ var _range = require('./range'); var FORWARD = _utilsKey.DIRECTION.FORWARD; var BACKWARD = _utilsKey.DIRECTION.BACKWARD; -var WORD_CHAR_REGEX = /\w|_|:/; +// generated via http://xregexp.com/ to cover chars that \w misses +// (new XRegExp('\\p{Alphabetic}|[0-9]|_|:')).toString() +var WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]|[0-9]|_|:/; function findParentSectionFromNode(renderTree, node) { var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) { @@ -481,6 +483,12 @@ Position = (function () { sectionOffset += postNode.length; } position = new Position(section, sectionOffset); + } else if (offset >= elementNode.childNodes.length) { + + // This is to deal with how Firefox handles triple-click selections. + // See https://stackoverflow.com/a/21234837/1269194 for an + // explanation. + position = section.tailPosition(); } else { // The offset is 0 if the cursor is on a non-atom-wrapper element node // (e.g., a
    tag in a blank markup section) diff --git a/website/commonjs/mobiledoc-kit/utils/cursor/range.js b/website/commonjs/mobiledoc-kit/utils/cursor/range.js index ef6500920..f18e7d756 100644 --- a/website/commonjs/mobiledoc-kit/utils/cursor/range.js +++ b/website/commonjs/mobiledoc-kit/utils/cursor/range.js @@ -103,8 +103,10 @@ var Range = (function () { case _key.DIRECTION.BACKWARD: return new Range(head.move(units), tail, currentDirection); default: - var newDirection = units > 0 ? _key.DIRECTION.FORWARD : _key.DIRECTION.BACKWARD; - return new Range(head, tail, newDirection).extend(units); + { + var newDirection = units > 0 ? _key.DIRECTION.FORWARD : _key.DIRECTION.BACKWARD; + return new Range(head, tail, newDirection).extend(units); + } } } @@ -156,12 +158,20 @@ var Range = (function () { return !detectMarker(i); }; - var headMarker = head.section.markers.detect(firstNotMatchingDetect, head.marker, true); - headMarker = headMarker && headMarker.next || head.marker; + var headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true); + if (!headMarker && detectMarker(headSection.markers.head)) { + headMarker = headSection.markers.head; + } else { + headMarker = headMarker.next || head.marker; + } var headPosition = new _position['default'](headSection, headSection.offsetOfMarker(headMarker)); var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker); - tailMarker = tailMarker && tailMarker.prev || tail.marker; + if (!tailMarker && detectMarker(headSection.markers.tail)) { + tailMarker = headSection.markers.tail; + } else { + tailMarker = tailMarker.prev || tail.marker; + } var tailPosition = new _position['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length); return headPosition.toRange(tailPosition, direction); diff --git a/website/commonjs/mobiledoc-kit/utils/deprecate.js b/website/commonjs/mobiledoc-kit/utils/deprecate.js index e5e270647..4c5985be3 100644 --- a/website/commonjs/mobiledoc-kit/utils/deprecate.js +++ b/website/commonjs/mobiledoc-kit/utils/deprecate.js @@ -15,6 +15,7 @@ function deprecate(message) { var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; if (!conditional) { - console.log("[mobiledoc-kit] [DEPRECATED]: " + message); // jshint ignore:line + // eslint-disable-next-line no-console + console.log("[mobiledoc-kit] [DEPRECATED]: " + message); } } \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/utils/element-utils.js b/website/commonjs/mobiledoc-kit/utils/element-utils.js index fcb36afa1..ff7a53ec8 100644 --- a/website/commonjs/mobiledoc-kit/utils/element-utils.js +++ b/website/commonjs/mobiledoc-kit/utils/element-utils.js @@ -67,10 +67,29 @@ function setData(element, name, value) { } } +function whenElementIsNotInDOM(element, callback) { + var isCanceled = false; + var observerFn = function observerFn() { + if (isCanceled) { + return; + } + if (!element.parentNode) { + callback(); + } else { + window.requestAnimationFrame(observerFn); + } + }; + observerFn(); + return { cancel: function cancel() { + return isCanceled = true; + } }; +} + exports.setData = setData; exports.getEventTargetMatchingTag = getEventTargetMatchingTag; exports.getElementRelativeOffset = getElementRelativeOffset; exports.getElementComputedStyleNumericProp = getElementComputedStyleNumericProp; exports.positionElementToRect = positionElementToRect; exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect; -exports.positionElementCenteredBelow = positionElementCenteredBelow; \ No newline at end of file +exports.positionElementCenteredBelow = positionElementCenteredBelow; +exports.whenElementIsNotInDOM = whenElementIsNotInDOM; \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/utils/key.js b/website/commonjs/mobiledoc-kit/utils/key.js index 0cf4b1d04..ece59bcb7 100644 --- a/website/commonjs/mobiledoc-kit/utils/key.js +++ b/website/commonjs/mobiledoc-kit/utils/key.js @@ -3,11 +3,14 @@ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); exports.modifierMask = modifierMask; +exports.specialCharacterToCode = specialCharacterToCode; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _keycodes = require('./keycodes'); +var _keys = require('./keys'); + var _utilsCharacters = require('../utils/characters'); /** @@ -63,7 +66,10 @@ var SPECIAL_KEYS = { DEL: _keycodes['default'].DELETE }; -exports.SPECIAL_KEYS = SPECIAL_KEYS; +function specialCharacterToCode(specialCharacter) { + return SPECIAL_KEYS[specialCharacter]; +} + // heuristic for determining if `event` is a key event function isKeyEvent(event) { return (/^key/.test(event.type) @@ -79,6 +85,7 @@ var Key = (function () { function Key(event) { _classCallCheck(this, Key); + this.key = event.key; this.keyCode = event.keyCode; this.charCode = event.charCode; this.event = event; @@ -93,20 +100,38 @@ var Key = (function () { } return String.fromCharCode(this.charCode); } + + // See https://caniuse.com/#feat=keyboardevent-key for browser support. + }, { + key: 'isKeySupported', + value: function isKeySupported() { + return this.key; + } + }, { + key: 'isKey', + value: function isKey(identifier) { + if (this.isKeySupported()) { + (0, _assert['default'])('Must define Keys.' + identifier + '.', _keys['default'][identifier]); + return this.key === _keys['default'][identifier]; + } else { + (0, _assert['default'])('Must define Keycodes.' + identifier + '.', _keycodes['default'][identifier]); + return this.keyCode === _keycodes['default'][identifier]; + } + } }, { key: 'isEscape', value: function isEscape() { - return this.keyCode === _keycodes['default'].ESC; + return this.isKey('ESC'); } }, { key: 'isDelete', value: function isDelete() { - return this.keyCode === _keycodes['default'].BACKSPACE || this.keyCode === _keycodes['default'].DELETE; + return this.isKey('BACKSPACE') || this.isForwardDelete(); } }, { key: 'isForwardDelete', value: function isForwardDelete() { - return this.keyCode === _keycodes['default'].DELETE; + return this.isKey('DELETE'); } }, { key: 'isArrow', @@ -116,7 +141,7 @@ var Key = (function () { }, { key: 'isHorizontalArrow', value: function isHorizontalArrow() { - return this.keyCode === _keycodes['default'].LEFT || this.keyCode === _keycodes['default'].RIGHT; + return this.isLeftArrow() || this.isRightArrow(); } }, { key: 'isHorizontalArrowWithoutModifiersOtherThanShift', @@ -126,56 +151,75 @@ var Key = (function () { }, { key: 'isVerticalArrow', value: function isVerticalArrow() { - return this.keyCode === _keycodes['default'].UP || this.keyCode === _keycodes['default'].DOWN; + return this.isKey('UP') || this.isKey('DOWN'); } }, { key: 'isLeftArrow', value: function isLeftArrow() { - return this.keyCode === _keycodes['default'].LEFT; + return this.isKey('LEFT'); } }, { key: 'isRightArrow', value: function isRightArrow() { - return this.keyCode === _keycodes['default'].RIGHT; + return this.isKey('RIGHT'); } }, { key: 'isHome', value: function isHome() { - return this.keyCode === _keycodes['default'].HOME; + return this.isKey('HOME'); } }, { key: 'isEnd', value: function isEnd() { - return this.keyCode === _keycodes['default'].END; + return this.isKey('END'); + } + }, { + key: 'isPageUp', + value: function isPageUp() { + return this.isKey('PAGEUP'); + } + }, { + key: 'isPageDown', + value: function isPageDown() { + return this.isKey('PAGEDOWN'); + } + }, { + key: 'isInsert', + value: function isInsert() { + return this.isKey('INS'); + } + }, { + key: 'isClear', + value: function isClear() { + return this.isKey('CLEAR'); + } + }, { + key: 'isPause', + value: function isPause() { + return this.isKey('PAUSE'); } }, { key: 'isSpace', value: function isSpace() { - return this.keyCode === _keycodes['default'].SPACE; + return this.isKey('SPACE'); } + + // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but + // it will also fire a keydown event for the tab+modifier (ctrl). This causes + // Mobiledoc to erroneously insert a tab character before FF switches to the + // new browser tab. Chrome doesn't fire this event so the issue doesn't + // arise there. Fix this by returning false when the TAB key event includes a + // modifier. + // See: https://github.com/bustle/mobiledoc-kit/issues/565 }, { key: 'isTab', value: function isTab() { - return this.keyCode === _keycodes['default'].TAB; + return !this.hasAnyModifier() && this.isKey('TAB'); } }, { key: 'isEnter', value: function isEnter() { - return this.keyCode === _keycodes['default'].ENTER; - } - - /** - * If the shift key is depressed. - * For example, while holding down meta+shift, pressing the "v" - * key would result in an event whose `Key` had `isShift()` with a truthy value, - * because the shift key is down when pressing the "v". - * @see {isShiftKey} which checks if the key is actually the shift key itself. - * @return {bool} - */ - }, { - key: 'isShift', - value: function isShift() { - return this.shiftKey; + return this.isKey('ENTER'); } /* @@ -187,7 +231,7 @@ var Key = (function () { }, { key: 'isShiftKey', value: function isShiftKey() { - return this.keyCode === _keycodes['default'].SHIFT; + return this.isKey('SHIFT'); } /* @@ -198,7 +242,7 @@ var Key = (function () { }, { key: 'isAltKey', value: function isAltKey() { - return this.keyCode === _keycodes['default'].ALT; + return this.isKey('ALT'); } /* @@ -209,7 +253,28 @@ var Key = (function () { }, { key: 'isCtrlKey', value: function isCtrlKey() { - return this.keyCode === _keycodes['default'].CTRL; + return this.isKey('CTRL'); + } + }, { + key: 'isIME', + value: function isIME() { + // FIXME the IME action seems to get lost when we issue an + // `editor.deleteSelection` before it (in Chrome) + return this.keyCode === _keycodes['default'].IME; + } + }, { + key: 'isShift', + + /** + * If the shift key is depressed. + * For example, while holding down meta+shift, pressing the "v" + * key would result in an event whose `Key` had `isShift()` with a truthy value, + * because the shift key is down when pressing the "v". + * @see {isShiftKey} which checks if the key is actually the shift key itself. + * @return {bool} + */ + value: function isShift() { + return this.shiftKey; } }, { key: 'hasModifier', @@ -222,33 +287,60 @@ var Key = (function () { return !!this.modifierMask; } }, { - key: 'isPrintable', + key: 'isPrintableKey', + value: function isPrintableKey() { + return !(this.isArrow() || this.isHome() || this.isEnd() || this.isPageUp() || this.isPageDown() || this.isInsert() || this.isClear() || this.isPause() || this.isEscape()); + } + }, { + key: 'isNumberKey', + value: function isNumberKey() { + if (this.isKeySupported()) { + return this.key >= '0' && this.key <= '9'; + } else { + var code = this.keyCode; + return code >= _keycodes['default']['0'] && code <= _keycodes['default']['9'] || code >= _keycodes['default'].NUMPAD_0 && code <= _keycodes['default'].NUMPAD_9; // numpad keys + } + } + }, { + key: 'isLetterKey', + value: function isLetterKey() { + if (this.isKeySupported()) { + var key = this.key; + return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z'; + } else { + var code = this.keyCode; + return code >= _keycodes['default'].A && code <= _keycodes['default'].Z || code >= _keycodes['default'].a && code <= _keycodes['default'].z; + } + } + }, { + key: 'isPunctuation', + value: function isPunctuation() { + if (this.isKeySupported()) { + var key = this.key; + return key >= ';' && key <= '`' || key >= '[' && key <= '"'; + } else { + var code = this.keyCode; + return code >= _keycodes['default'][';'] && code <= _keycodes['default']['`'] || code >= _keycodes['default']['['] && code <= _keycodes['default']['"']; + } + } /** * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position * and http://stackoverflow.com/a/12467610/137784 */ + }, { + key: 'isPrintable', value: function isPrintable() { if (this.ctrlKey || this.metaKey) { return false; } - var code = this.keyCode; - - // Firefox calls keypress events for arrow keys, but they should not be - // considered printable - if (this.isArrow()) { + // Firefox calls keypress events for some keys that should not be printable + if (!this.isPrintableKey()) { return false; } - return code !== 0 || this.toString().length > 0 || code >= _keycodes['default']['0'] && code <= _keycodes['default']['9'] || // number keys - this.isSpace() || this.isTab() || this.isEnter() || code >= _keycodes['default'].A && code <= _keycodes['default'].Z || // letter keys - code >= _keycodes['default'].a && code <= _keycodes['default'].z || code >= _keycodes['default'].NUMPAD_0 && code <= _keycodes['default'].NUMPAD_9 || // numpad keys - code >= _keycodes['default'][';'] && code <= _keycodes['default']['`'] || // punctuation - code >= _keycodes['default']['['] && code <= _keycodes['default']['"'] || - // FIXME the IME action seems to get lost when we issue an `editor.deleteSelection` - // before it (in Chrome) - code === _keycodes['default'].IME; + return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME(); } }, { key: 'direction', diff --git a/website/commonjs/mobiledoc-kit/utils/keycodes.js b/website/commonjs/mobiledoc-kit/utils/keycodes.js index 64e6b4c9f..8c93249eb 100644 --- a/website/commonjs/mobiledoc-kit/utils/keycodes.js +++ b/website/commonjs/mobiledoc-kit/utils/keycodes.js @@ -28,6 +28,8 @@ exports['default'] = { IME: 229, TAB: 9, + CLEAR: 12, + PAUSE: 19, PAGEUP: 33, PAGEDOWN: 34, END: 35, diff --git a/website/commonjs/mobiledoc-kit/utils/keys.js b/website/commonjs/mobiledoc-kit/utils/keys.js new file mode 100644 index 000000000..6ec9145d9 --- /dev/null +++ b/website/commonjs/mobiledoc-kit/utils/keys.js @@ -0,0 +1,25 @@ +'use strict'; + +exports['default'] = { + BACKSPACE: 'Backspace', + SPACE: ' ', + ENTER: 'Enter', + SHIFT: 'Shift', + ESC: 'Escape', + DELETE: 'Delete', + INS: 'Insert', + HOME: 'Home', + END: 'End', + PAGEUP: 'PageUp', + PAGEDOWN: 'PageDown', + CLEAR: 'Clear', + PAUSE: 'Pause', + TAB: 'Tab', + ALT: 'Alt', + CTRL: 'Control', + + LEFT: 'ArrowLeft', + RIGHT: 'ArrowRight', + UP: 'ArrowUp', + DOWN: 'ArrowDown' +}; \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/utils/linked-list.js b/website/commonjs/mobiledoc-kit/utils/linked-list.js index 73343b6bc..82ee68118 100644 --- a/website/commonjs/mobiledoc-kit/utils/linked-list.js +++ b/website/commonjs/mobiledoc-kit/utils/linked-list.js @@ -89,25 +89,29 @@ var LinkedList = (function () { break; case 'middle': - var prevItem = nextItem.prev; - item.next = nextItem; - item.prev = prevItem; - nextItem.prev = item; - prevItem.next = item; + { + var prevItem = nextItem.prev; + item.next = nextItem; + item.prev = prevItem; + nextItem.prev = item; + prevItem.next = item; - break; + break; + } case 'end': - var tail = this.tail; - item.prev = tail; + { + var tail = this.tail; + item.prev = tail; - if (tail) { - tail.next = item; - } else { - this.head = item; - } - this.tail = item; + if (tail) { + tail.next = item; + } else { + this.head = item; + } + this.tail = item; - break; + break; + } } } }, { diff --git a/website/commonjs/mobiledoc-kit/utils/object-utils.js b/website/commonjs/mobiledoc-kit/utils/object-utils.js new file mode 100644 index 000000000..012943e1d --- /dev/null +++ b/website/commonjs/mobiledoc-kit/utils/object-utils.js @@ -0,0 +1,15 @@ +"use strict"; + +exports.entries = entries; + +function entries(obj) { + var ownProps = Object.keys(obj); + var i = ownProps.length; + var resArray = new Array(i); + + while (i--) { + resArray[i] = [ownProps[i], obj[ownProps[i]]]; + } + + return resArray; +} \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/utils/selection-utils.js b/website/commonjs/mobiledoc-kit/utils/selection-utils.js index ee637cdc4..31dffaa1c 100644 --- a/website/commonjs/mobiledoc-kit/utils/selection-utils.js +++ b/website/commonjs/mobiledoc-kit/utils/selection-utils.js @@ -37,6 +37,7 @@ function findOffsetInTextNode(node, coords) { * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js * @return {Object} {node, offset} */ +/* eslint-disable complexity */ function findOffsetInNode(_x, _x2) { var _again = true; @@ -94,6 +95,7 @@ function findOffsetInNode(_x, _x2) { return { node: node, offset: offset }; } } +/* eslint-enable complexity */ function constrainNodeTo(node, parentNode, existingOffset) { var compare = parentNode.compareDocumentPosition(node); diff --git a/website/commonjs/mobiledoc-kit/version.js b/website/commonjs/mobiledoc-kit/version.js index 099134ede..dd4570c60 100644 --- a/website/commonjs/mobiledoc-kit/version.js +++ b/website/commonjs/mobiledoc-kit/version.js @@ -1,3 +1,3 @@ 'use strict'; -exports['default'] = '0.10.16'; \ No newline at end of file +exports['default'] = '0.12.2'; \ No newline at end of file diff --git a/website/commonjs/mobiledoc-kit/views/tooltip.js b/website/commonjs/mobiledoc-kit/views/tooltip.js index 13533f2cb..bbd240552 100644 --- a/website/commonjs/mobiledoc-kit/views/tooltip.js +++ b/website/commonjs/mobiledoc-kit/views/tooltip.js @@ -39,6 +39,9 @@ var Tooltip = (function (_View) { this.addEventListener(rootElement, 'mouseout', function (e) { clearTimeout(timeout); + if (_this.elementObserver) { + _this.elementObserver.cancel(); + } var toElement = e.toElement || e.relatedTarget; if (toElement && toElement.className !== _this.element.className) { _this.hide(); @@ -57,8 +60,13 @@ var Tooltip = (function (_View) { }, { key: 'showLink', value: function showLink(link, element) { + var _this2 = this; + var message = '' + link + ''; this.showMessage(message, element); + this.elementObserver = (0, _utilsElementUtils.whenElementIsNotInDOM)(element, function () { + return _this2.hide(); + }); } }]); diff --git a/website/css/mobiledoc-kit.css b/website/css/mobiledoc-kit.css index 7c56c6447..18af81e69 100644 --- a/website/css/mobiledoc-kit.css +++ b/website/css/mobiledoc-kit.css @@ -62,6 +62,27 @@ max-width: 100%; } +.__mobiledoc-editor [data-md-text-align='left'] { + text-align: left; +} + +.__mobiledoc-editor [data-md-text-align='center'] { + text-align: center; +} + +.__mobiledoc-editor [data-md-text-align='right'] { + text-align: right; +} + +.__mobiledoc-editor [data-md-text-align='justify'] { + text-align: justify; +} + +.__mobiledoc-editor ol, +.__mobiledoc-editor ul { + list-style-position: inside; +} + /** * Cards */ diff --git a/website/demo/debug.js b/website/demo/debug.js index 03f9890b3..a50e84dd9 100644 --- a/website/demo/debug.js +++ b/website/demo/debug.js @@ -1,12 +1,10 @@ /* global Mobiledoc */ 'use strict'; -var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); - var editor; function renderError(event) { - var error = event.error; + let error = event.error; $('#error .name').text(error.name); $('#error .message').text(error.message); } @@ -37,29 +35,28 @@ function updateCursor() { document.addEventListener('selectionchange', renderNativeSelection); function renderNativeSelection(event) { - var sel = window.getSelection(); - var anchorNode = sel.anchorNode; - var focusNode = sel.focusNode; - var anchorOffset = sel.anchorOffset; - var focusOffset = sel.focusOffset; - var isCollapsed = sel.isCollapsed; - var rangeCount = sel.rangeCount; - + let sel = window.getSelection(); + let { anchorNode, focusNode, anchorOffset, focusOffset, isCollapsed, rangeCount } = sel; if (anchorNode === null && focusNode === null) { - $('#selection').html('None'); + $('#selection').html(`None`); return; } - $('#selection').html('\n
    Anchor: ' + renderNode(anchorNode) + ' (' + anchorOffset + ')
    \n
    Focus: ' + renderNode(focusNode) + ' (' + focusOffset + ')
    \n
    ' + (isCollapsed ? 'Collapsed' : 'Not collapsed') + '
    \n
    Ranges: ' + rangeCount + '
    \n '); + $('#selection').html(` +
    Anchor: ${renderNode(anchorNode)} (${anchorOffset})
    +
    Focus: ${renderNode(focusNode)} (${focusOffset})
    +
    ${isCollapsed ? 'Collapsed' : 'Not collapsed'}
    +
    Ranges: ${rangeCount}
    + `); } function renderNode(node) { - var text = node.textContent.slice(0, 22); + let text = node.textContent.slice(0, 22); if (node.textContent.length > 22) { text += '...'; } - var type = node.nodeType === Node.TEXT_NODE ? 'text' : 'el (' + node.tagName + ')'; - return '' + type + ': ' + text; + let type = node.nodeType === Node.TEXT_NODE ? 'text' : `el (${node.tagName})`; + return `${type}: ${text}`; } function renderMarkup(markup) { @@ -87,17 +84,15 @@ function updateInputMode() { } function updateButtons() { - var activeSectionTagNames = editor.activeSections.map(function (section) { + let activeSectionTagNames = editor.activeSections.map(section => { return section.tagName; }); - var activeMarkupTagNames = editor.activeMarkups.map(function (markup) { - return markup.tagName; - }); + let activeMarkupTagNames = editor.activeMarkups.map(markup => markup.tagName); $('#toolbar button').each(function () { - var toggle = $(this).data('toggle'); + let toggle = $(this).data('toggle'); - var hasSection = false, + let hasSection = false, hasMarkup = false; if (activeSectionTagNames.indexOf(toggle) !== -1) { hasSection = true; @@ -113,29 +108,23 @@ function updateButtons() { }); } -var mentionAtom = { +let mentionAtom = { name: 'mention', type: 'dom', - render: function render(_ref) { - var value = _ref.value; - - var el = $('@' + value + '')[0]; + render({ value }) { + let el = $(`@${value}`)[0]; return el; } }; -var clickAtom = { +let clickAtom = { name: 'click', type: 'dom', - render: function render(_ref2) { - var env = _ref2.env; - var value = _ref2.value; - var payload = _ref2.payload; - - var el = document.createElement('button'); - var clicks = payload.clicks || 0; + render({ env, value, payload }) { + let el = document.createElement('button'); + let clicks = payload.clicks || 0; el.appendChild(document.createTextNode('Clicks: ' + clicks)); - el.onclick = function () { + el.onclick = () => { payload.clicks = payload.clicks || 0; payload.clicks++; env.save(value, payload); @@ -144,19 +133,11 @@ var clickAtom = { } }; -var tableCard = { +let tableCard = { name: 'table', type: 'dom', - render: function render() { - var _map = ['table', 'tr', 'td'].map(function (tagName) { - return document.createElement(tagName); - }); - - var _map2 = _slicedToArray(_map, 3); - - var table = _map2[0]; - var tr = _map2[1]; - var td = _map2[2]; + render() { + let [table, tr, td] = ['table', 'tr', 'td'].map(tagName => document.createElement(tagName)); table.appendChild(tr); tr.appendChild(td); @@ -167,7 +148,7 @@ var tableCard = { }; function moveCard(section, dir) { - editor.run(function (postEditor) { + editor.run(postEditor => { if (dir === 'up') { postEditor.moveSectionUp(section); } else { @@ -176,70 +157,48 @@ function moveCard(section, dir) { }); } -var movableCard = { +let movableCard = { name: 'movable', type: 'dom', - render: function render(_ref3) { - var env = _ref3.env; - var payload = _ref3.payload; - - var cardSection = env.postModel; - var text = payload.text || 'new'; - var up = $('').click(function () { - return moveCard(cardSection, 'up'); - }); - var down = $('').click(function () { - return moveCard(cardSection, 'down'); - }); - var x = $('').click(env.remove); + render({ env, payload }) { + let cardSection = env.postModel; + let text = payload.text || 'new'; + let up = $('').click(() => moveCard(cardSection, 'up')); + let down = $('').click(() => moveCard(cardSection, 'down')); + let x = $('').click(env.remove); - var edit = $('').click(env.edit); + let edit = $('').click(env.edit); - var el = $('
    ').append([text, up, down, x, edit])[0]; + let el = $('
    ').append([text, up, down, x, edit])[0]; return el; }, - edit: function edit(_ref4) { - var env = _ref4.env; - var payload = _ref4.payload; - - var cardSection = env.postModel; - var text = payload.text || 'new'; - var up = $('').click(function () { - return moveCard(cardSection, 'up'); - }); - var down = $('').click(function () { - return moveCard(cardSection, 'down'); - }); - var x = $('').click(env.remove); - - var input = $(''); - var save = $('').click(function () { + edit({ env, payload }) { + let cardSection = env.postModel; + let text = payload.text || 'new'; + let up = $('').click(() => moveCard(cardSection, 'up')); + let down = $('').click(() => moveCard(cardSection, 'down')); + let x = $('').click(env.remove); + + let input = $(''); + let save = $('').click(() => { payload.text = input.val(); env.save(payload); }); - var el = $('
    ').append([text, up, down, x, input, save])[0]; + let el = $('
    ').append([text, up, down, x, input, save])[0]; return el; } }; -function speakingPlugin(node, builder, _ref5) { - var addSection = _ref5.addSection; - var addMarkerable = _ref5.addMarkerable; - var nodeFinished = _ref5.nodeFinished; - +function speakingPlugin(node, builder, { addSection, addMarkerable, nodeFinished }) { console.log('got node!', node); } -function tableConverterPlugin(node, builder, _ref6) { - var addSection = _ref6.addSection; - var addMarkerable = _ref6.addMarkerable; - var nodeFinished = _ref6.nodeFinished; - +function tableConverterPlugin(node, builder, { addSection, addMarkerable, nodeFinished }) { if (node.tagName !== 'TABLE') { return; } - var tableCard = builder.createCardSection("table"); + let tableCard = builder.createCardSection("table"); addSection(tableCard); nodeFinished(); } @@ -263,32 +222,32 @@ $(function () { editor.render(el); $('#toolbar button.toggle').click(function () { - var action = $(this).data('action'); - var toggle = $(this).data('toggle'); + let action = $(this).data('action'); + let toggle = $(this).data('toggle'); editor[action](toggle); }); $('#toolbar button.toggle-method').click(function () { - var isOn = $(this).data('is-on') === 'true'; - var methodOn = $(this).data('on'); - var methodOff = $(this).data('off'); + let isOn = $(this).data('is-on') === 'true'; + let methodOn = $(this).data('on'); + let methodOff = $(this).data('off'); - var nextState = isOn ? 'false' : 'true'; - var method = isOn ? methodOff : methodOn; + let nextState = isOn ? 'false' : 'true'; + let method = isOn ? methodOff : methodOn; $(this).data('is-on', nextState); editor[method](); }); $('#toolbar button.insert-atom').click(function () { - var name = $(this).data('name'); - var value = $(this).data('value') || ''; + let name = $(this).data('name'); + let value = $(this).data('value') || ''; editor.insertAtom(name, value); }); $('#toolbar button.insert-card').click(function () { - var name = $(this).data('name'); + let name = $(this).data('name'); editor.insertCard(name); }); }); \ No newline at end of file diff --git a/website/demo/demo.css b/website/demo/demo.css index 063dedd74..30c96d0ab 100644 --- a/website/demo/demo.css +++ b/website/demo/demo.css @@ -87,9 +87,6 @@ table tr { border: 2px solid #ccc; } -.editor { -} - .two-column { display: -webkit-flex; display: flex; @@ -125,6 +122,26 @@ table tr { .toolbar { text-align: center; + display: flex; +} + +.toolbar-section { + display: flex; + margin: 0 12px; +} +.toolbar-section:first-child { margin-left: 0; } +.toolbar-section:last-child { margin-right: 0; } + +.toolbar-section button { + display: flex; + align-items: center; + margin: 0 4px; +} +.toolbar-section button:first-child { margin-left: 0; } +.toolbar-section button:last-child { margin-right: 0; } + +.toolbar-section button svg { + height: 24px; } #editor-wrapper { diff --git a/website/demo/demo.js b/website/demo/demo.js index b826dc773..7274acfa0 100644 --- a/website/demo/demo.js +++ b/website/demo/demo.js @@ -1,51 +1,51 @@ /* global Mobiledoc */ 'use strict'; -$(function () { +$(() => { bootstrapEditor(); bootstrapSimpleDemo(); bootstrapToolbarEditor(); bootstrapCardEditor(); }); -var bootstrapEditor = function bootstrapEditor() { - var el = $('#editor')[0]; - var editor = new Mobiledoc.Editor({ +let bootstrapEditor = () => { + let el = $('#editor')[0]; + let editor = new Mobiledoc.Editor({ placeholder: 'Type here', autofocus: true }); editor.render(el); activateButtons('#editor-wrapper', editor); - var displayMobiledoc = function displayMobiledoc() { - var mobiledoc = editor.serialize(); - var html = mobiledocPrettyJSONRenderer(mobiledoc); + let displayMobiledoc = () => { + let mobiledoc = editor.serialize(); + let html = mobiledocPrettyJSONRenderer(mobiledoc); $('#editor-output').html(html); }; editor.postDidChange(displayMobiledoc); displayMobiledoc(); }; -var bootstrapSimpleDemo = function bootstrapSimpleDemo() { - var el = $('#editor-basic')[0]; - var editor = new Mobiledoc.Editor({ +let bootstrapSimpleDemo = () => { + let el = $('#editor-basic')[0]; + let editor = new Mobiledoc.Editor({ placeholder: 'Welcome to Mobiledoc' }); editor.render(el); }; -var activateButtons = function activateButtons(parentSelector, editor) { - $(parentSelector + ' button').click(function () { - var button = $(this); - var action = button.data('action'); - var arg = button.data('arg'); +let activateButtons = (parentSelector, editor) => { + $(`${parentSelector} button`).click(function () { + let button = $(this); + let action = button.data('action'); + let args = button.data('args').split(','); - editor[action](arg); + editor[action](...args); }); }; -var bootstrapToolbarEditor = function bootstrapToolbarEditor() { - var el = $('#editor-toolbar')[0]; - var editor = new Mobiledoc.Editor({ +let bootstrapToolbarEditor = () => { + let el = $('#editor-toolbar')[0]; + let editor = new Mobiledoc.Editor({ placeholder: 'Editor with toolbar' }); editor.render(el); @@ -53,25 +53,27 @@ var bootstrapToolbarEditor = function bootstrapToolbarEditor() { activateButtons('#editor-toolbar-wrapper', editor); }; -var bootstrapCardEditor = function bootstrapCardEditor() { - var card = { +let bootstrapCardEditor = () => { + let card = { name: 'kitten', type: 'dom', - render: function render() { - var el = $('
    \n
    Image of a kitten
    \n
    '); + render() { + let el = $(`
    +
    Image of a kitten
    +
    `); return el[0]; } }; - var atom = { + let atom = { name: 'mention', type: 'dom', - render: function render() { - var el = $('@hello'); + render() { + let el = $(`@hello`); return el[0]; } }; - var el = $('#editor-card')[0]; - var editor = new Mobiledoc.Editor({ + let el = $('#editor-card')[0]; + let editor = new Mobiledoc.Editor({ placeholder: 'Editor with card', cards: [card], atoms: [atom] diff --git a/website/demo/docs/Editor.html b/website/demo/docs/Editor.html index 490349708..a8a45a3d0 100644 --- a/website/demo/docs/Editor.html +++ b/website/demo/docs/Editor.html @@ -28,7 +28,7 @@

    Class: Editor

    -

    Editor

    +

    Editor(optionsopt)

    The Editor is a core component of mobiledoc-kit. After instantiating an editor, use Editor#render to display the editor on the web page.

    @@ -49,6 +49,8 @@

    Editor

    a custom toolbar.
  • Editor#onTextInput -- Register callbacks when the user enters text that matches a given string or regex.
  • +
  • Editor#beforeToggleMarkup -- Register callbacks that will be run before +applying changes from Editor#toggleMarkup
  • @@ -63,7 +65,9 @@

    Editor

    Constructor

    +

    new Editor(optionsopt)

    + @@ -546,6 +550,45 @@
    Properties
    + + + showLinkTooltips + + + + + +Boolean + + + + + + + + + <optional>
    + + + + + + + + + + + + true + + + + +

    Whether to show the url tooltip for links

    + + + + undoDepth @@ -629,7 +672,7 @@
    Properties
    Source:
    @@ -655,6 +698,8 @@
    Properties
    + +
    @@ -664,7 +709,9 @@
    Properties
    - + + + @@ -673,7 +720,7 @@

    Members

    -

    activeMarkups :Array.<Markup>

    +

    activeMarkups :Array.<Markup>

    @@ -684,7 +731,7 @@
    Type:
    @@ -5180,8 +5797,12 @@
    Parameters:
    Type + Attributes + + Default + Description @@ -5205,13 +5826,64 @@
    Parameters:
    + + + + + + + + + + + +

    E.g. "b", "em", "a"

    + + + + attributes + + + + + +Object + + + + + + + + + <optional>
    + + + + + + + + + + + + {} + + + + +

    E.g. {href: "http://bustle.com"}

    + + + @@ -5249,7 +5921,7 @@
    Parameters:
    Source:
    @@ -5282,12 +5954,16 @@
    Parameters:
    + + +

    toggleSection(tagName)

    + @@ -5389,7 +6065,7 @@
    Parameters:
    Source:
    @@ -5422,12 +6098,16 @@
    Parameters:
    + + +

    unregisterAllTextInputHandlers()

    + @@ -5478,7 +6158,7 @@

    Source:
    @@ -5504,12 +6184,16 @@

    unregisterKeyCommands(name)

    + @@ -5605,7 +6289,7 @@
    Parameters:
    Source:
    @@ -5631,12 +6315,16 @@
    Parameters:
    + + +

    unregisterTextInputHandler(name)

    + @@ -5736,7 +6424,7 @@
    Parameters:
    Source:
    @@ -5762,12 +6450,16 @@
    Parameters:
    + + +

    willDelete(callback)

    + @@ -5863,7 +6555,7 @@
    Parameters:
    Source:
    @@ -5889,12 +6581,16 @@
    Parameters:
    + + +

    willHandleNewline(callback)

    + @@ -5990,7 +6686,7 @@
    Parameters:
    Source:
    @@ -6016,12 +6712,16 @@
    Parameters:
    + + +

    willRender(callback)

    + @@ -6118,7 +6818,7 @@
    Parameters:
    Source:
    @@ -6144,6 +6844,8 @@
    Parameters:
    + + @@ -6160,13 +6862,13 @@
    Parameters:


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/Key.html b/website/demo/docs/Key.html index f87df2f14..59eaf4922 100644 --- a/website/demo/docs/Key.html +++ b/website/demo/docs/Key.html @@ -28,7 +28,7 @@

    Class: Key

    -

    Key

    +

    Key()

    An abstraction around a KeyEvent that key listeners in the editor can use @@ -46,7 +46,9 @@

    Key

    Constructor

    +

    new Key()

    + @@ -93,7 +95,7 @@

    new KeySource:
    @@ -119,6 +121,8 @@

    new Key @@ -128,7 +132,9 @@

    new KeyMethods

    +

    isPrintable()

    + @@ -194,7 +202,7 @@

    isPrintabl
    Source:
    @@ -220,12 +228,16 @@

    isPrintabl + + +

    isShift() → {bool}

    + @@ -279,7 +291,7 @@

    isShiftSource:
    @@ -330,6 +342,8 @@
    Returns:
    + + @@ -346,13 +360,13 @@
    Returns:


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/Markup.html b/website/demo/docs/Markup.html new file mode 100644 index 000000000..1dcf62096 --- /dev/null +++ b/website/demo/docs/Markup.html @@ -0,0 +1,361 @@ + + + + + JSDoc: Class: Markup + + + + + + + + + + +
    + +

    Class: Markup

    + + + + + + +
    + +
    + +

    Markup()

    + +

    A Markup is similar with an inline HTML tag that might be added to +text to modify its meaning and/or display. Examples of types of markup +that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and a tags (links).

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Markup()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tagName + + +String + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + +

    Methods

    + + + + + + + +

    getAttribute(name,)

    + + + + + + +
    +

    Returns the attribute value

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name, + + +String + + + +

    e.g. "href"

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + +
    + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST) +
    + + + + + \ No newline at end of file diff --git a/website/demo/docs/Position.html b/website/demo/docs/Position.html index 2ada2374d..7ecae1f82 100644 --- a/website/demo/docs/Position.html +++ b/website/demo/docs/Position.html @@ -28,7 +28,7 @@

    Class: Position

    -

    Position

    +

    Position()

    @@ -40,7 +40,9 @@

    Position

    +

    new Position()

    + @@ -93,7 +95,7 @@

    new Position<
    Source:
    @@ -119,6 +121,8 @@

    new Position< + +

    @@ -128,7 +132,9 @@

    new Position< - + + + @@ -182,7 +188,7 @@

    markerSource:
    @@ -209,7 +215,9 @@

    Methods

    +

    (static) atPoint(x, y, editor) → {Position|null}

    + @@ -351,7 +359,7 @@
    Parameters:
    Source:
    @@ -398,12 +406,16 @@
    Returns:
    + + +

    isHead() → {Boolean}

    + @@ -450,7 +462,7 @@

    isHeadSource:
    @@ -498,12 +510,16 @@
    Returns:
    + + +

    isHeadOfPost() → {Boolean}

    + @@ -550,7 +566,7 @@

    isHeadOfP
    Source:
    @@ -598,12 +614,16 @@

    Returns:
    + + +

    isTail() → {Boolean}

    + @@ -650,7 +670,7 @@

    isTailSource:
    @@ -698,12 +718,16 @@
    Returns:
    + + +

    isTailOfPost() → {Boolean}

    + @@ -750,7 +774,7 @@

    isTailOfP
    Source:
    @@ -798,12 +822,16 @@

    Returns:
    + + +

    markerIn(direction) → {Marker|undefined}

    + @@ -907,7 +935,7 @@
    Parameters:
    Source:
    @@ -954,12 +982,16 @@
    Returns:
    + + +

    move(units) → {Position}

    + @@ -1059,7 +1091,7 @@
    Parameters:
    Source:
    @@ -1110,12 +1142,16 @@
    Returns:
    + + +

    moveWord(direction) → {Position}

    + @@ -1211,7 +1247,7 @@
    Parameters:
    Source:
    @@ -1259,12 +1295,16 @@
    Returns:
    + + +

    toRange(tailopt) → {Range}

    + @@ -1385,7 +1425,7 @@
    Parameters:
    Source:
    @@ -1429,6 +1469,8 @@
    Returns:
    + + @@ -1445,13 +1487,13 @@
    Returns:


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/Post.html b/website/demo/docs/Post.html index a46b8dabc..a560a8c8f 100644 --- a/website/demo/docs/Post.html +++ b/website/demo/docs/Post.html @@ -28,7 +28,7 @@

    Class: Post

    -

    Post

    +

    Post()

    The Post is an in-memory representation of an editor's document. An editor always has a single post. The post is organized into a list of @@ -49,7 +49,9 @@

    Post

    Constructor

    +

    new Post()

    + @@ -122,6 +124,8 @@

    new Post @@ -131,7 +135,9 @@

    new PostMethods

    +

    headPosition() → {Position}

    + @@ -308,12 +316,16 @@
    Returns:
    + + +

    markersContainedByRange(range) → {Array}

    + @@ -457,12 +469,16 @@
    Returns:
    + + +

    tailPosition() → {Position}

    + @@ -558,12 +574,16 @@
    Returns:
    + + +

    toRange() → {Range}

    + @@ -658,12 +678,16 @@
    Returns:
    + + +

    trimTo(range) → {Post}

    + @@ -807,6 +831,8 @@
    Returns:
    + + @@ -823,13 +849,13 @@
    Returns:


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/PostEditor.html b/website/demo/docs/PostEditor.html index 40bc88ffd..819cd3457 100644 --- a/website/demo/docs/PostEditor.html +++ b/website/demo/docs/PostEditor.html @@ -28,7 +28,7 @@

    Class: PostEditor

    -

    PostEditor

    +

    PostEditor()

    The PostEditor is used to modify a post. It should not be instantiated directly. Instead, a new instance of a PostEditor is created by the editor and passed @@ -51,7 +51,9 @@

    PostEditor

    Constructor

    +

    new PostEditor()

    + @@ -124,6 +126,8 @@

    new PostEdi + +

    @@ -133,7 +137,9 @@

    new PostEdi - + + + @@ -147,7 +153,9 @@

    Methods

    +

    addMarkupToRange(range, markup)

    + @@ -229,7 +237,7 @@
    Parameters:
    -Markup +Markup @@ -306,12 +314,16 @@
    Parameters:
    + + +

    deleteAtPosition(position, directionopt, optionsopt) → {Position}

    + @@ -627,12 +639,16 @@
    Returns:
    + + +

    deleteFrom(position, direction) → {Position}

    + @@ -801,12 +817,16 @@
    Returns:
    + + +

    deleteRange(range) → {Position}

    + @@ -960,12 +980,16 @@
    Returns:
    + + +

    insertMarkers(position, markers) → {Position}

    + @@ -1137,12 +1161,16 @@
    Returns:
    + + +

    insertSection(section)

    + @@ -1243,7 +1271,7 @@
    Parameters:
    Source:
    @@ -1269,12 +1297,16 @@
    Parameters:
    + + +

    insertSectionAtEnd(section)

    + @@ -1374,7 +1406,7 @@
    Parameters:
    Source:
    @@ -1400,12 +1432,16 @@
    Parameters:
    + + +

    insertSectionBefore(collection, section, beforeSection)

    + @@ -1561,7 +1597,7 @@
    Parameters:
    Source:
    @@ -1587,12 +1623,16 @@
    Parameters:
    + + +

    insertText(position, text) → {Position}

    + @@ -1764,12 +1804,16 @@
    Returns:
    + + +

    insertTextWithMarkup(position, text, markups) → {Position}

    + @@ -1865,7 +1909,7 @@
    Parameters:
    -Array.<Markup> +Array.<Markup> @@ -1964,12 +2008,16 @@
    Returns:
    + + +

    moveSectionDown(section)

    + @@ -2091,12 +2139,16 @@
    Parameters:
    + + +

    moveSectionUp(section)

    + @@ -2218,12 +2270,16 @@
    Parameters:
    + + +

    removeSection(section)

    + @@ -2329,7 +2385,7 @@
    Parameters:
    Source:
    @@ -2355,12 +2411,16 @@
    Parameters:
    + + +

    replaceSection(section, newSection)

    + @@ -2515,12 +2575,16 @@
    Returns:
    + + +

    schedule(callback, onceopt)

    + @@ -2675,7 +2739,7 @@
    Parameters:
    Source:
    @@ -2701,12 +2765,16 @@
    Parameters:
    + + +

    scheduleDidUpdate()

    + @@ -2759,7 +2827,7 @@

    sche
    Source:
    @@ -2785,12 +2853,16 @@

    sche + + +

    scheduleOnce(callback)

    + @@ -2892,7 +2964,7 @@
    Parameters:
    Source:
    @@ -2918,12 +2990,16 @@
    Parameters:
    + + +

    scheduleRerender()

    + @@ -2974,7 +3050,7 @@

    sched
    Source:
    @@ -3000,12 +3076,16 @@

    sched + + +

    setRange(range)

    + @@ -3144,12 +3224,16 @@
    Parameters:
    + + +

    splitSection(position) → {Array}

    + @@ -3306,12 +3390,16 @@
    Returns:
    + + +

    toggleMarkup(markupOrString, range)

    + @@ -3372,7 +3460,7 @@
    Parameters:
    -Markup +Markup | String @@ -3480,12 +3568,16 @@
    Parameters:
    + + +

    toggleSection(sectionTagName, range)

    + @@ -3641,6 +3733,8 @@
    Parameters:
    + + @@ -3657,13 +3751,13 @@
    Parameters:

    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/PostNodeBuilder.html b/website/demo/docs/PostNodeBuilder.html index a83f93d8d..7c840ecfa 100644 --- a/website/demo/docs/PostNodeBuilder.html +++ b/website/demo/docs/PostNodeBuilder.html @@ -28,7 +28,7 @@

    Class: PostNodeBuilder

    -

    PostNodeBuilder

    +

    PostNodeBuilder()

    The PostNodeBuilder is used to create new Post primitives, such as a MarkupSection, a CardSection, a Markup, etc. Every instance of an @@ -49,7 +49,9 @@

    PostNodeBuilder

    Constructor

    +

    new PostNodeBuilder()

    + @@ -122,6 +124,8 @@

    new Po + +

    @@ -131,7 +135,9 @@

    new Po - + + + @@ -145,7 +151,9 @@

    Methods

    +

    createAtom(name, valueopt, payloadopt, markupsopt) → {Atom}

    + @@ -307,7 +315,7 @@
    Parameters:
    -Array.<Markup> +Array.<Markup> @@ -418,12 +426,16 @@
    Returns:
    + + +

    createCardSection(name, payloadopt) → {CardSection}

    + @@ -618,12 +630,16 @@
    Returns:
    + + +

    createMarker(value, markupsopt) → {Marker}

    + @@ -707,7 +723,7 @@
    Parameters:
    -Array.<Markup> +Array.<Markup> @@ -818,12 +834,16 @@
    Returns:
    + + -

    createMarkup(tagName, attributes) → {Markup}

    + +

    createMarkup(tagName, attributes) → {Markup}

    + @@ -976,7 +996,7 @@
    Returns:
    -Markup +Markup
    @@ -986,12 +1006,16 @@
    Returns:
    + + +

    createMarkupSection(tagNameopt, markersopt) → {MarkupSection}

    + @@ -1190,12 +1214,16 @@
    Returns:
    + + +

    createPost() → {Post}

    + @@ -1290,6 +1318,8 @@
    Returns:
    + + @@ -1306,13 +1336,13 @@
    Returns:

    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/Range.html b/website/demo/docs/Range.html index b69ac3dd1..083610b27 100644 --- a/website/demo/docs/Range.html +++ b/website/demo/docs/Range.html @@ -28,7 +28,7 @@

    Class: Range

    -

    Range

    +

    Range(head, tailopt, directionopt)

    A logical range of a Post. Usually an instance of Range will be read from the Editor#range property, @@ -46,7 +46,9 @@

    Range

    Constructor

    +

    new Range(head, tailopt, directionopt)

    + @@ -262,6 +264,8 @@
    Parameters:
    + +
    @@ -271,7 +275,9 @@
    Parameters:
    - + + + @@ -619,7 +625,9 @@

    Methods

    +

    (static) create(headSection, headOffset, tailSectionopt, tailOffsetopt, directionopt) → {Range}

    + @@ -932,12 +940,16 @@
    Returns:
    + + +

    expandByMarker(detectMarker) → {Range}

    + @@ -1037,7 +1049,7 @@
    Parameters:
    Source:
    @@ -1085,12 +1097,16 @@
    Returns:
    + + +

    extend(units) → {Range}

    + @@ -1237,12 +1253,16 @@
    Returns:
    + + +

    move(direction) → {Range}

    + @@ -1345,7 +1365,7 @@
    Parameters:
    Source:
    @@ -1389,6 +1409,8 @@
    Returns:
    + + @@ -1405,13 +1427,13 @@
    Returns:

    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/editor_edit-state.js.html b/website/demo/docs/editor_edit-state.js.html index 21b879c43..6b72a2f40 100644 --- a/website/demo/docs/editor_edit-state.js.html +++ b/website/demo/docs/editor_edit-state.js.html @@ -26,7 +26,11 @@

    Source: editor/edit-state.js

    -
    import { contains, isArrayEqual } from 'mobiledoc-kit/utils/array-utils';
    +            
    import {
    +  contains,
    +  isArrayEqual,
    +  objectToSortedKVArray
    +} from 'mobiledoc-kit/utils/array-utils';
     import Range from 'mobiledoc-kit/utils/cursor/range';
     
     /**
    @@ -42,7 +46,8 @@ 

    Source: editor/edit-state.js

    range: Range.blankRange(), activeMarkups: [], activeSections: [], - activeSectionTagNames: [] + activeSectionTagNames: [], + activeSectionAttributes: {} }; this.prevState = this.state = defaultState; @@ -74,7 +79,8 @@

    Source: editor/edit-state.js

    inputModeDidChange() { let { state, prevState } = this; return (!isArrayEqual(state.activeMarkups, prevState.activeMarkups) || - !isArrayEqual(state.activeSectionTagNames, prevState.activeSectionTagNames)); + !isArrayEqual(state.activeSectionTagNames, prevState.activeSectionTagNames) || + !isArrayEqual(objectToSortedKVArray(state.activeSectionAttributes), objectToSortedKVArray(prevState.activeSectionAttributes))); } /** @@ -91,6 +97,14 @@

    Source: editor/edit-state.js

    return this.state.activeSections; } + + /** + * @return {Object} + */ + get activeSectionAttributes() { + return this.state.activeSectionAttributes; + } + /** * @return {Markup[]} */ @@ -125,6 +139,7 @@

    Source: editor/edit-state.js

    state.activeSectionTagNames = state.activeSections.map(s => { return s.isNested ? s.parent.tagName : s.tagName; }); + state.activeSectionAttributes = this._readSectionAttributes(state.activeSections); return state; } @@ -143,6 +158,21 @@

    Source: editor/edit-state.js

    return post.markupsInRange(range); } + _readSectionAttributes(sections) { + return sections.reduce((sectionAttributes, s) => { + let attributes = s.isNested ? s.parent.attributes : s.attributes; + Object.keys(attributes || {}).forEach(attrName => { + let camelizedAttrName = attrName.replace(/^data-md-/, ''); + let attrValue = attributes[attrName]; + sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || []; + if (!contains(sectionAttributes[camelizedAttrName], attrValue)) { + sectionAttributes[camelizedAttrName].push(attrValue); + } + }); + return sectionAttributes; + }, {}); + } + _removeActiveMarkup(markup) { let index = this.state.activeMarkups.indexOf(markup); this.state.activeMarkups.splice(index, 1); @@ -164,13 +194,13 @@

    Source: editor/edit-state.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/editor_editor.js.html b/website/demo/docs/editor_editor.js.html index 99257f408..978bc9761 100644 --- a/website/demo/docs/editor_editor.js.html +++ b/website/demo/docs/editor_editor.js.html @@ -71,6 +71,7 @@

    Source: editor/editor.js

    placeholder: 'Write here...', spellcheck: true, autofocus: true, + showLinkTooltips: true, undoDepth: 5, undoBlockTimeout: 5000, // ms for an undo event cards: [], @@ -120,6 +121,8 @@

    Source: editor/editor.js

    * a custom toolbar. * * {@link Editor#onTextInput} -- Register callbacks when the user enters text * that matches a given string or regex. + * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before + * applying changes from {@link Editor#toggleMarkup} */ class Editor { /** @@ -139,6 +142,7 @@

    Source: editor/editor.js

    * @param {String} [options.placeholder] Default text to show before user starts typing. * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered. + * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links * @param {number} [options.undoDepth=5] How many undo levels will be available. * Set to 0 to disable undo/redo functionality. * @return {Editor} @@ -148,7 +152,7 @@

    Source: editor/editor.js

    assert('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', (options && !options.nodeType)); this._views = []; - this.isEditable = null; + this.isEditable = true; this._parserPlugins = options.parserPlugins || []; // FIXME: This should merge onto this.options @@ -170,6 +174,7 @@

    Source: editor/editor.js

    this._mutationHandler = new MutationHandler(this); this._editState = new EditState(this); this._callbacks = new LifecycleCallbacks(values(CALLBACK_QUEUES)); + this._beforeHooks = { toggleMarkup: [] }; DEFAULT_TEXT_INPUT_HANDLERS.forEach(handler => this.onTextInput(handler)); @@ -264,12 +269,10 @@

    Source: editor/editor.js

    this.element = element; - if (this.isEditable === null) { - this.enableEditing(); + if (this.showLinkTooltips) { + this._addTooltip(); } - this._addTooltip(); - // A call to `run` will trigger the didUpdatePostCallbacks hooks with a // postEditor. this.run(() => {}); @@ -283,6 +286,12 @@

    Source: editor/editor.js

    this._mutationHandler.init(); this._eventManager.init(); + if (this.isEditable === false) { + this.disableEditing(); + } else { + this.enableEditing(); + } + if (this.autofocus) { this.selectRange(this.post.headPosition()); } @@ -510,6 +519,10 @@

    Source: editor/editor.js

    return activeSections[activeSections.length - 1]; } + get activeSectionAttributes() { + return this._editState.activeSectionAttributes; + } + detectMarkupInRange(range, markupTagName) { let markups = this.post.markupsInRange(range); return detect(markups, markup => { @@ -589,7 +602,7 @@

    Source: editor/editor.js

    let rendererOptions = { unknownCardHandler, unknownAtomHandler }; switch (format) { - case 'html': + case 'html': { let result; if (Environment.hasDOM()) { rendered = new DOMRenderer(rendererOptions).render(mobiledoc); @@ -599,6 +612,7 @@

    Source: editor/editor.js

    result = this.serializePost(post, 'text', options); } return result; + } case 'text': rendered = new TextRenderer(rendererOptions).render(mobiledoc); return rendered.result; @@ -653,10 +667,9 @@

    Source: editor/editor.js

    * @public */ disableEditing() { - if (this.isEditable === false) { return; } - this.isEditable = false; if (this.hasRendered) { + this._eventManager.stop(); this.element.setAttribute('contentEditable', false); this.setPlaceholder(''); this.selectRange(Range.blankRange()); @@ -672,7 +685,8 @@

    Source: editor/editor.js

    */ enableEditing() { this.isEditable = true; - if (this.element) { + if (this.hasRendered) { + this._eventManager.start(); this.element.setAttribute('contentEditable', true); this.setPlaceholder(this.placeholder); } @@ -875,19 +889,46 @@

    Source: editor/editor.js

    }); } + /** + * @callback editorBeforeCallback + * @param { Object } details + * @param { Markup } details.markup + * @param { Range } details.range + * @param { boolean } details.willAdd Whether the markup will be applied + */ + + /** + * Register a callback that will be run before {@link Editor#toggleMarkup} is applied. + * If any callback returns literal `false`, the toggling of markup will be canceled. + * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and + * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks. + * @param {editorBeforeCallback} + */ + beforeToggleMarkup(callback) { + this._beforeHooks.toggleMarkup.push(callback); + } + /** * Toggles the given markup at the editor's current {@link Range}. * If the range is collapsed this changes the editor's state so that the * next characters typed will be affected. If there is text selected * (aka a non-collapsed range), the selections' markup will be toggled. * If the editor is not focused and has no active range, nothing happens. + * Hooks added using #beforeToggleMarkup will be run before toggling, + * and if any of them returns literal false, toggling the markup will be canceled + * and no change will be applied. * @param {String} markup E.g. "b", "em", "a" + * @param {Object} [attributes={}] E.g. {href: "http://bustle.com"} * @public * @see PostEditor#toggleMarkup */ - toggleMarkup(markup) { - markup = this.builder.createMarkup(markup); + toggleMarkup(markup, attributes={}) { + markup = this.builder.createMarkup(markup, attributes); let { range } = this; + let willAdd = !this.detectMarkupInRange(range, markup.tagName); + let shouldCancel = this._runBeforeHooks('toggleMarkup', {markup, range, willAdd}); + if (shouldCancel) { return; } + if (range.isCollapsed) { this._editState.toggleMarkupState(markup); this._inputModeDidChange(); @@ -944,6 +985,29 @@

    Source: editor/editor.js

    this.run(postEditor => postEditor.toggleSection(tagName, this.range)); } + /** + * Sets an attribute for the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @param {String} value The value of the attribute. + * @public + * @see PostEditor#setAttribute + */ + setAttribute(key, value) { + this.run(postEditor => postEditor.setAttribute(key, value, this.range)); + } + + /** + * Removes an attribute from the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @public + * @see PostEditor#removeAttribute + */ + removeAttribute(key) { + this.run(postEditor => postEditor.removeAttribute(key, this.range)); + } + /** * Finds and runs the first matching key command for the event * @@ -1119,6 +1183,21 @@

    Source: editor/editor.js

    } this._callbacks.runCallbacks(...args); } + + /** + * Runs each callback for the given hookName. + * Only the hookName 'toggleMarkup' is currently supported + * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled + * @private + */ + _runBeforeHooks(hookName, ...args) { + let hooks = this._beforeHooks[hookName] || []; + for (let i = 0; i < hooks.length; i++) { + if (hooks[i](...args) === false) { + return true; + } + } + } } export default Editor; @@ -1132,13 +1211,13 @@

    Source: editor/editor.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/editor_mutation-handler.js.html b/website/demo/docs/editor_mutation-handler.js.html index ac27ad878..86d462353 100644 --- a/website/demo/docs/editor_mutation-handler.js.html +++ b/website/demo/docs/editor_mutation-handler.js.html @@ -192,13 +192,13 @@

    Source: editor/mutation-handler.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/editor_post.js.html b/website/demo/docs/editor_post.js.html index cde3abd09..6f0451ef9 100644 --- a/website/demo/docs/editor_post.js.html +++ b/website/demo/docs/editor_post.js.html @@ -28,7 +28,7 @@

    Source: editor/post.js

    import Position from '../utils/cursor/position';
     import Range from 'mobiledoc-kit/utils/cursor/range';
    -import { forEach, reduce, filter, values, commonItems } from '../utils/array-utils';
    +import { detect, forEach, reduce, filter, values, commonItems } from '../utils/array-utils';
     import { DIRECTION } from '../utils/key';
     import LifecycleCallbacks from '../models/lifecycle-callbacks';
     import assert from '../utils/assert';
    @@ -818,7 +818,6 @@ 

    Source: editor/post.js

    sectionTagName = normalizeTagName(sectionTagName); let { post } = this.editor; - let nextRange = range; let everySectionHasTagName = true; post.walkMarkerableSections(range, section => { @@ -828,18 +827,83 @@

    Source: editor/post.js

    }); let tagName = everySectionHasTagName ? 'p' : sectionTagName; - let firstChanged; + let sectionTransformations = []; post.walkMarkerableSections(range, section => { let changedSection = this.changeSectionTagName(section, tagName); - firstChanged = firstChanged || changedSection; + sectionTransformations.push({ + from: section, + to: changedSection + }); }); - if (firstChanged) { - nextRange = firstChanged.headPosition().toRange(); - } + let nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations); this.setRange(nextRange); } + _determineNextRangeAfterToggleSection(range, sectionTransformations) { + if (sectionTransformations.length) { + let changedHeadSection = detect(sectionTransformations, ({ from }) => { + return from === range.headSection; + }).to; + let changedTailSection = detect(sectionTransformations, ({ from }) => { + return from === range.tailSection; + }).to; + + if (changedHeadSection.isListSection || changedTailSection.isListSection) { + // We don't know to which ListItem's the original sections point at, so + // we don't have enough information to reconstruct the range when + // dealing with lists. + return sectionTransformations[0].to.headPosition().toRange(); + } else { + return Range.create( + changedHeadSection, + range.headSectionOffset, + changedTailSection, + range.tailSectionOffset, + range.direction + ); + } + } else { + return range; + } + } + + setAttribute(key, value, range=this._range) { + this._mutateAttribute(key, range, (section, attribute) => { + if (section.getAttribute(attribute) !== value) { + section.setAttribute(attribute, value); + return true; + } + }); + } + + removeAttribute(key, range=this._range) { + this._mutateAttribute(key, range, (section, attribute) => { + if (section.hasAttribute(attribute)) { + section.removeAttribute(attribute); + return true; + } + }); + } + + _mutateAttribute(key, range, cb) { + range = toRange(range); + let { post } = this.editor; + let attribute = `data-md-${key}`; + + post.walkMarkerableSections(range, section => { + if (section.isListItem) { + section = section.parent; + } + + if (cb(section, attribute) === true) { + this._markDirty(section); + } + }); + + this.setRange(range); + } + _isSameSectionType(section, sectionTagName) { return section.isListItem ? section.parent.tagName === sectionTagName : @@ -912,7 +976,7 @@

    Source: editor/post.js

    let positionIsMiddle = !position.isHead() && !position.isTail(); if (positionIsMiddle) { let item = position.section; - let [pre, post] = // jshint ignore:line + let [pre,] = this._splitListItem(item, position); position = pre.tailPosition(); } @@ -950,7 +1014,7 @@

    Source: editor/post.js

    */ _splitListAtItem(list, item) { let next = list; - let prev = this.builder.createListSection(next.tagName); + let prev = this.builder.createListSection(next.tagName, [], next.attributes); let mid = this.builder.createListSection(next.tagName); let addToPrev = true; @@ -998,7 +1062,7 @@

    Source: editor/post.js

    let markupSection = this.builder.createMarkupSection(newTagName); markupSection.join(section); - let [prev, mid, next] = this._splitListAtItem(listSection, section); // jshint ignore:line + let [, mid,] = this._splitListAtItem(listSection, section); this.replaceSection(mid, markupSection); return markupSection; } @@ -1016,7 +1080,7 @@

    Source: editor/post.js

    let sectionToReplace; if (section.isListItem) { - let [prev, mid, next] = this._splitListAtItem(section.parent, section); // jshint ignore:line + let [, mid,] = this._splitListAtItem(section.parent, section); sectionToReplace = mid; } else { sectionToReplace = section; @@ -1230,13 +1294,13 @@

    Source: editor/post.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/editor_text-input-handlers.js.html b/website/demo/docs/editor_text-input-handlers.js.html index f6de85118..2e4e97775 100644 --- a/website/demo/docs/editor_text-input-handlers.js.html +++ b/website/demo/docs/editor_text-input-handlers.js.html @@ -124,13 +124,13 @@

    Source: editor/text-input-handlers.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/editor_ui.js.html b/website/demo/docs/editor_ui.js.html index fb6ed4e2b..2919202f3 100644 --- a/website/demo/docs/editor_ui.js.html +++ b/website/demo/docs/editor_ui.js.html @@ -83,15 +83,12 @@

    Source: editor/ui.js

    let hasLink = editor.detectMarkupInRange(range, 'a'); if (hasLink) { - editor.run(postEditor => postEditor.toggleMarkup('a')); + editor.toggleMarkup('a'); } else { showPrompt('Enter a URL', defaultUrl, url => { if (!url) { return; } - editor.run(postEditor => { - let markup = postEditor.builder.createMarkup('a', {href: url}); - postEditor.toggleMarkup(markup); - }); + editor.toggleMarkup('a', {href: url}); }); } } @@ -105,13 +102,13 @@

    Source: editor/ui.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/global.html b/website/demo/docs/global.html index d10a1b6d1..e48123e7c 100644 --- a/website/demo/docs/global.html +++ b/website/demo/docs/global.html @@ -87,7 +87,9 @@

    - + + + @@ -221,7 +223,7 @@
    Properties:
    Source:
    @@ -306,7 +308,9 @@

    Methods

    +

    _handleMutations()

    + @@ -401,12 +405,16 @@

    _hand + + +

    findRenderNodeFromElement(element)

    + @@ -528,12 +536,16 @@
    Parameters:
    + + +

    headPosition() → {Position}

    + @@ -628,12 +640,16 @@
    Returns:
    + + +

    join(other)

    + @@ -736,7 +752,7 @@
    Parameters:
    Source:
    @@ -772,12 +788,16 @@
    Returns:
    + + +

    markersFor() → {Array}

    + @@ -873,12 +893,16 @@
    Returns:
    + + +

    offsetOfMarker(marker, markerOffset) → {Number}

    + @@ -1057,12 +1081,16 @@
    Returns:
    + + -

    parse(text) → {Post}

    + +

    parse() → {Post}

    + @@ -1083,8 +1111,6 @@
    Parameters:
    - Name - Type @@ -1101,13 +1127,11 @@
    Parameters:
    - text - -String +Mobiledoc @@ -1117,7 +1141,7 @@
    Parameters:
    -

    to parse

    + @@ -1158,7 +1182,7 @@
    Parameters:
    Source:
    @@ -1184,10 +1208,6 @@
    Parameters:
    Returns:
    -
    -

    a post abstract

    -
    -
    @@ -1206,12 +1226,16 @@
    Returns:
    + + +

    parse() → {Post}

    + @@ -1303,7 +1327,7 @@
    Parameters:
    Source:
    @@ -1347,12 +1371,16 @@
    Returns:
    + + -

    parse() → {Post}

    + +

    parse(html) → {Post}

    + @@ -1373,6 +1401,8 @@
    Parameters:
    + Name + Type @@ -1389,11 +1419,13 @@
    Parameters:
    + html + -Mobiledoc +String @@ -1403,7 +1435,7 @@
    Parameters:
    - +

    to parse

    @@ -1444,7 +1476,7 @@
    Parameters:
    Source:
    @@ -1470,6 +1502,10 @@
    Parameters:
    Returns:
    +
    +

    A post abstract

    +
    +
    @@ -1488,12 +1524,16 @@
    Returns:
    + + -

    parse(html) → {Post}

    + +

    parse() → {Post}

    + @@ -1514,8 +1554,6 @@
    Parameters:
    - Name - Type @@ -1532,13 +1570,11 @@
    Parameters:
    - html - -String +Mobiledoc @@ -1548,7 +1584,7 @@
    Parameters:
    -

    to parse

    + @@ -1589,7 +1625,7 @@
    Parameters:
    Source:
    @@ -1615,10 +1651,6 @@
    Parameters:
    Returns:
    -
    -

    A post abstract

    -
    -
    @@ -1637,12 +1669,16 @@
    Returns:
    + + +

    parse() → {Post}

    + @@ -1734,7 +1770,7 @@
    Parameters:
    Source:
    @@ -1778,21 +1814,20 @@
    Returns:
    + + -

    replaceWithHeaderSection(editor, headingTagName)

    - + +

    parse(text) → {Post}

    + -
    -

    Convert section at the editor's cursor position into a header section. -Does nothing if the cursor position is not at the start of the section.

    -
    @@ -1827,30 +1862,7 @@
    Parameters:
    - editor - - - - - -Editor - - - - - - - - - - - - - - - - - headingTagName + text @@ -1866,7 +1878,7 @@
    Parameters:
    -

    ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')

    +

    to parse

    @@ -1907,7 +1919,7 @@
    Parameters:
    Source:
    @@ -1930,6 +1942,30 @@
    Parameters:
    +
    Returns:
    + + +
    +

    a post abstract

    +
    + + + +
    +
    + Type +
    +
    + +Post + + +
    +
    + + + + @@ -1938,16 +1974,17 @@
    Parameters:
    -

    replaceWithListSection(editor, listTagName)

    + +

    replaceWithHeaderSection(editor, headingTagName)

    +
    -

    Convert section at the editor's cursor position into a list. -Does nothing if the cursor position is not at the start of the section, -or if the section is already a list item.

    +

    Convert section at the editor's cursor position into a header section. +Does nothing if the cursor position is not at the start of the section.

    @@ -2006,7 +2043,7 @@
    Parameters:
    - listTagName + headingTagName @@ -2022,7 +2059,7 @@
    Parameters:
    -

    ("ul" or "ol")

    +

    ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')

    @@ -2063,7 +2100,7 @@
    Parameters:
    Source:
    @@ -2089,21 +2126,25 @@
    Parameters:
    + + -

    splitMarkerAtOffset(sectionOffset) → {EditObject}

    + +

    replaceWithListSection(editor, listTagName)

    +
    -

    Split this section's marker (if any) at the given offset, so that -there is now a marker boundary at that offset (useful for later applying -a markup to a range)

    +

    Convert section at the editor's cursor position into a list. +Does nothing if the cursor position is not at the start of the section, +or if the section is already a list item.

    @@ -2139,13 +2180,13 @@
    Parameters:
    - sectionOffset + editor -Number +Editor @@ -2155,7 +2196,30 @@
    Parameters:
    -

    The offset relative to start of this section

    + + + + + + + + listTagName + + + + + +String + + + + + + + + + +

    ("ul" or "ol")

    @@ -2196,7 +2260,7 @@
    Parameters:
    Source:
    @@ -2219,30 +2283,8 @@
    Parameters:
    -
    Returns:
    - - -
    -

    An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank. -After calling splitMarkerAtOffset(offset), there will always be a valid -result returned from markerBeforeOffset(offset).

    -
    - - - -
    -
    - Type -
    -
    - -EditObject - -
    -
    - @@ -2251,7 +2293,9 @@
    Returns:
    +

    splitMarkerAtOffset()

    + @@ -2328,13 +2372,178 @@

    sp + + -

    tailPosition() → {Position}

    - + +

    splitMarkerAtOffset(sectionOffset) → {EditObject}

    + + + + + + +
    +

    Split this section's marker (if any) at the given offset, so that +there is now a marker boundary at that offset (useful for later applying +a markup to a range)

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    sectionOffset + + +Number + + + +

    The offset relative to start of this section

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank. +After calling splitMarkerAtOffset(offset), there will always be a valid +result returned from markerBeforeOffset(offset).

    +
    + + + +
    +
    + Type +
    +
    + +EditObject + + +
    +
    + + + + + + + + + + + + + +

    tailPosition() → {Position}

    + + @@ -2428,12 +2637,16 @@
    Returns:
    + + +

    toPosition(offset) → {Position}

    + @@ -2577,12 +2790,16 @@
    Returns:
    + + +

    toRange() → {Range}

    + @@ -2677,9 +2894,241 @@
    Returns:
    + + + + + + +

    Type Definitions

    + + + + + + + +

    editorBeforeCallback(details)

    + + + + + + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    details + + +Object + + + + +
    Properties
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    markup + + +Markup + + + +
    range + + +Range + + + +
    willAdd + + +boolean + + + +

    Whether the markup will be applied

    + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + @@ -2693,13 +3142,13 @@
    Returns:

    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/index.html b/website/demo/docs/index.html index a92136bae..d173ad803 100644 --- a/website/demo/docs/index.html +++ b/website/demo/docs/index.html @@ -43,11 +43,12 @@

    -

    Mobiledoc Kit

    Sauce Test Status

    +

    Mobiledoc Kit

    Travis CI Build Status

    +

    Sauce Test Status

    Dependency Status devDependency Status

    Mobiledoc Logo

    -

    Mobiledoc Kit (warning: beta) is a library for building WYSIWYG editors +

    Mobiledoc Kit (beta) is a framework-agnostic library for building WYSIWYG editors supporting rich content via cards.

    Libraries

    This repository hosts the core Mobiledoc-Kit library. If you want to use Mobiledoc-Kit to create a WYSIWYG editor you have the following options:

    @@ -101,6 +102,10 @@

    Libraries

    This repository hosts the core Mobiledoc-Kit library. If yo

    + + + +
    In-Browser (DOM) Rendering, with Ember ember-mobiledoc-dom-renderer
    React Server and Browser Renderermobiledoc-react-renderer

    Mobiledoc is a deliberately simple and terse format, and you are encouraged to write your own renderer if you have other target output formats (e.g., a PDF renderer, an iOS Native Views Renderer, etc.).

    @@ -148,7 +153,7 @@

    Usage

    The Mobiledoc.Editor class is invoked with an elem var editor = new Mobiledoc.Editor(options); editor.render(element);

    options is an object which may include the following properties:

      -
    • modiledoc - [object] A mobiledoc object to load and edit.
    • +
    • mobiledoc - [object] A mobiledoc object to load and edit.
    • placeholder - [string] default text to show before a user starts typing.
    • spellcheck - [boolean] whether to enable spellcheck. Defaults to true.
    • autofocus - [boolean] When true, focuses on the editor when it is rendered.
    • @@ -172,7 +177,7 @@

      Usage

      The Mobiledoc.Editor class is invoked with an elem

    • editor.destroy() - teardown the editor event listeners, free memory etc.
    • editor.disableEditing() - stop the user from being able to edit the current post with their cursor. Programmatic edits are still allowed.
    • -
    • editor.enableEditing() - allow the user to make direct edits directly +
    • editor.enableEditing() - allow the user to make edits directly to a post's text.
    • editor.editCard(cardSection) - change the card to its edit mode (will change immediately if the card is already rendered, or will ensure that when the card @@ -253,9 +258,14 @@

      Editor Lifecycle Hooks

      API consumers may want to react to given inter

    • editor.cursorDidChange() - When the cursor (or selection) changes as a result of arrow-key movement or clicking in the document.
    • editor.onTextInput() - When the user adds text to the document (see example)
    • -
    • editor.inputModeDidChange() - The active section(s) or markup(s) at the current cursor position or selection have changed. This hook can be used with Editor#activeMarkups and Editor#activeSections to implement a custom toolbar.
    • +
    • editor.inputModeDidChange() - The active section(s) or markup(s) at the current cursor position or selection have changed. This hook can be used with Editor#activeMarkups, Editor#activeSections, and Editor#activeSectionAttributes to implement a custom toolbar.
    • +
    • editor.beforeToggleMarkup(({markup, range, willAdd} => {...}) - Register a +callback that will be called before editor#toggleMarkup is applied. If any +callback returns literal false, the toggling of markup will be canceled. +(Toggling markup done via the postEditor, e.g. editor.run(postEditor => +postEditor.toggleMarkup(...)) will skip this callback.
    -

    For more details on the lifecycle hooks, see the Editor documentation.

    +

    For more details on the lifecycle hooks, see the Editor documentation.

    Programmatic Post Editing

    A major goal of the Mobiledoc kit is to allow complete customization of user interfaces using the editing surface. The programmatic editing API allows the creation of completely custom interfaces for buttons, hot-keys, and @@ -319,8 +329,19 @@

    Responding to text input

    The editor exposes a hook onTextInput< } });

    The editor has several default text input handlers that are defined in src/js/editor/text-input-handlers.js.

    -

    To remove default text input handlers, simply call the unregister function.

    -
    editor.unregisterAllTextInputHandlers();

    DOM Parsing hooks

    A developer can override the default parsing behavior for leaf DOM nodes in +

    To remove default text input handlers call the unregister function.

    +
    editor.unregisterAllTextInputHandlers();

    \n special-case match character

    When writing a matching string it is common to use \s at the end of a match +regex, thus triggering the handler for a given string when the users presses +the space or tab key.

    +

    When the enter key is pressed no actual characters are added to a document. +Instead a new section is created following the current section. Despite this, +you may use \n in a match regex to capture moments when the enter key is +pressed. For example if you wanted to process a URL for auto-linking you +might want to process the string on both the space key and when the user hits +enter.

    +

    Since \s is a superset of \n, that makes the following regex a valid match +for a hand-typed URL after the user presses space or enter:

    +
    /\b(https?:\/\/[^\s]+)\s$/

    DOM Parsing hooks

    A developer can override the default parsing behavior for leaf DOM nodes in pasted HTML.

    For example, when an img tag is pasted it may be appropriate to fetch that image, upload it to an authoritative source, and create a specific @@ -384,13 +405,18 @@

    Releasing (Implementer notes)

    • np <version> (e.g. np 0.12.0)
    • git push <origin> --tags
    -

    Deploy the demo

    The demo website is hosted at github pages. To publish a new version:

    +

    Deploy the demo

    The demo website is hosted at +bustle.github.io/mobiledoc-kit/demo.

    +

    To preview the website, start the server and visit +http://localhost:4200/demo/. The code for +this website can be found in assets/demo/. Note that the development server +does not rebuild jsdoc.

    +

    To publish a new version:

    • npm run build:website - This builds the website into website/ and commits it
    • npm run deploy:website - Pushes the website/ subtree to the gh-pages branch of your origin at github
    -

    Visit bustle.github.io/mobiledoc-kit/demo.

    Development of Mobiledoc and the supporting libraries was generously funded by Bustle Labs. Bustle Labs is the tech team behind the editorial staff at Bustle, a fantastic and successful feminist and women’s interest site based in NYC.

    @@ -402,13 +428,13 @@

    Deploy the demo

    The demo website is hosted at github pages. To publis


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models__markerable.js.html b/website/demo/docs/models__markerable.js.html index 914739737..f5e8c1667 100644 --- a/website/demo/docs/models__markerable.js.html +++ b/website/demo/docs/models__markerable.js.html @@ -313,13 +313,13 @@

    Source: models/_markerable.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models__section.js.html b/website/demo/docs/models__section.js.html index af4558636..a6a983f42 100644 --- a/website/demo/docs/models__section.js.html +++ b/website/demo/docs/models__section.js.html @@ -134,7 +134,7 @@

    Source: models/_section.js

    nextLeafSection() { const next = this.next; if (next) { - if (!!next.items) { + if (next.items) { return next.items.head; } else { return next; @@ -158,7 +158,7 @@

    Source: models/_section.js

    const prev = this.prev; if (prev) { - if (!!prev.items) { + if (prev.items) { return prev.items.tail; } else { return prev; @@ -180,13 +180,13 @@

    Source: models/_section.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models_list-section.js.html b/website/demo/docs/models_list-section.js.html index 8d6debba3..b77eef874 100644 --- a/website/demo/docs/models_list-section.js.html +++ b/website/demo/docs/models_list-section.js.html @@ -26,12 +26,15 @@

    Source: models/list-section.js

    -
    import LinkedList from '../utils/linked-list';
    -import { forEach, contains } from '../utils/array-utils';
    -import { LIST_SECTION_TYPE } from './types';
    +            
    import { LIST_SECTION_TYPE } from './types';
     import Section from './_section';
    +import { attributable } from './_attributable';
    +
    +import LinkedList from '../utils/linked-list';
    +import { forEach, contains } from '../utils/array-utils';
     import { normalizeTagName } from '../utils/dom-utils';
     import assert from '../utils/assert';
    +import { entries } from '../utils/object-utils';
     
     export const VALID_LIST_SECTION_TAGNAMES = [
       'ul', 'ol'
    @@ -40,12 +43,15 @@ 

    Source: models/list-section.js

    export const DEFAULT_TAG_NAME = VALID_LIST_SECTION_TAGNAMES[0]; export default class ListSection extends Section { - constructor(tagName=DEFAULT_TAG_NAME, items=[]) { + constructor(tagName=DEFAULT_TAG_NAME, items=[], attributes={}) { super(LIST_SECTION_TYPE); this.tagName = tagName; this.isListSection = true; this.isLeafSection = false; + attributable(this); + entries(attributes).forEach(([k,v]) => this.setAttribute(k, v)); + this.items = new LinkedList({ adoptItem: i => { assert(`Cannot insert non-list-item to list (is: ${i.type})`, @@ -110,13 +116,13 @@

    Source: models/list-section.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models_marker.js.html b/website/demo/docs/models_marker.js.html index 982fad470..6a9729671 100644 --- a/website/demo/docs/models_marker.js.html +++ b/website/demo/docs/models_marker.js.html @@ -161,13 +161,13 @@

    Source: models/marker.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models_markup.js.html b/website/demo/docs/models_markup.js.html new file mode 100644 index 000000000..2a79e9c6f --- /dev/null +++ b/website/demo/docs/models_markup.js.html @@ -0,0 +1,129 @@ + + + + + JSDoc: Source: models/markup.js + + + + + + + + + + +
    + +

    Source: models/markup.js

    + + + + + + +
    +
    +
    import { normalizeTagName } from '../utils/dom-utils';
    +import { filterObject } from '../utils/array-utils';
    +import { MARKUP_TYPE } from './types';
    +import assert from '../utils/assert';
    +
    +export const VALID_MARKUP_TAGNAMES = [
    +  'a',
    +  'b',
    +  'code',
    +  'em',
    +  'i',
    +  's',   // strikethrough
    +  'strong',
    +  'sub', // subscript
    +  'sup', // superscript
    +  'u'
    +].map(normalizeTagName);
    +
    +export const VALID_ATTRIBUTES = [
    +  'href',
    +  'rel'
    +];
    +
    +/**
    + * A Markup is similar with an inline HTML tag that might be added to
    + * text to modify its meaning and/or display. Examples of types of markup
    + * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links).
    + * @property {String} tagName
    + */
    +class Markup {
    +  /*
    +   * @param {Object} attributes key-values
    +   */
    +  constructor(tagName, attributes={}) {
    +    this.tagName = normalizeTagName(tagName);
    +
    +    assert('Must use attributes object param (not array) for Markup',
    +           !Array.isArray(attributes));
    +
    +    this.attributes = filterObject(attributes, VALID_ATTRIBUTES);
    +    this.type = MARKUP_TYPE;
    +
    +    assert(`Cannot create markup of tagName ${tagName}`,
    +           VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1);
    +  }
    +
    +  /**
    +   * Whether text in the forward direction of the cursor (i.e. to the right in ltr text)
    +   * should be considered to have this markup applied to it.
    +   * @private
    +   */
    +  isForwardInclusive() {
    +    return this.tagName === normalizeTagName("a") ? false : true;
    +  }
    +
    +  isBackwardInclusive() {
    +    return false;
    +  }
    +
    +  hasTag(tagName) {
    +    return this.tagName === normalizeTagName(tagName);
    +  }
    +
    +  /**
    +   * Returns the attribute value
    +   * @param {String} name, e.g. "href"
    +   */
    +  getAttribute(name) {
    +    return this.attributes[name];
    +  }
    +
    +  static isValidElement(element) {
    +    const tagName = normalizeTagName(element.tagName);
    +    return VALID_MARKUP_TAGNAMES.indexOf(tagName) !== -1;
    +  }
    +}
    +
    +export default Markup;
    +
    +
    +
    + + + + +
    + + + +
    + +
    + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST) +
    + + + + + diff --git a/website/demo/docs/models_post-node-builder.js.html b/website/demo/docs/models_post-node-builder.js.html index 9f9f1a1e6..6b9a377f7 100644 --- a/website/demo/docs/models_post-node-builder.js.html +++ b/website/demo/docs/models_post-node-builder.js.html @@ -106,9 +106,9 @@

    Source: models/post-node-builder.js

    * @param {Marker[]} [markers=[]] * @return {MarkupSection} */ - createMarkupSection(tagName=DEFAULT_MARKUP_SECTION_TAG_NAME, markers=[], isGenerated=false) { + createMarkupSection(tagName=DEFAULT_MARKUP_SECTION_TAG_NAME, markers=[], isGenerated=false, attributes={}) { tagName = normalizeTagName(tagName); - const section = new MarkupSection(tagName, markers); + const section = new MarkupSection(tagName, markers, attributes); if (isGenerated) { section.isGenerated = true; } @@ -116,9 +116,9 @@

    Source: models/post-node-builder.js

    return section; } - createListSection(tagName=DEFAULT_LIST_SECTION_TAG_NAME, items=[]) { + createListSection(tagName=DEFAULT_LIST_SECTION_TAG_NAME, items=[], attributes={}) { tagName = normalizeTagName(tagName); - const section = new ListSection(tagName, items); + const section = new ListSection(tagName, items, attributes); section.builder = this; return section; } @@ -203,13 +203,13 @@

    Source: models/post-node-builder.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models_post.js.html b/website/demo/docs/models_post.js.html index 9d5288bc6..2ee861561 100644 --- a/website/demo/docs/models_post.js.html +++ b/website/demo/docs/models_post.js.html @@ -201,7 +201,7 @@

    Source: models/post.js

    if (next) { if (next.isLeafSection) { return next; - } else if (!!next.items) { + } else if (next.items) { return next.items.head; } else { assert('Cannot determine next section from non-leaf-section', false); @@ -250,6 +250,7 @@

    Source: models/post.js

    ); } else { newSection = section.clone(); + sectionParent = post; } if (sectionParent) { sectionParent.sections.append(newSection); @@ -270,13 +271,13 @@

    Source: models/post.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/models_render-tree.js.html b/website/demo/docs/models_render-tree.js.html index b58a26f3e..68c217f20 100644 --- a/website/demo/docs/models_render-tree.js.html +++ b/website/demo/docs/models_render-tree.js.html @@ -106,13 +106,13 @@

    Source: models/render-tree.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/module-UI.html b/website/demo/docs/module-UI.html index aa246348e..04ebf784d 100644 --- a/website/demo/docs/module-UI.html +++ b/website/demo/docs/module-UI.html @@ -47,7 +47,9 @@

    Module: UI

    - + + + @@ -61,7 +63,9 @@

    Methods

    +

    (inner) defaultShowPrompt(editor, showPromptopt)

    + @@ -233,6 +237,8 @@
    Parameters:
    + +
    Example
    let myPrompt = (message, defaultURL, promptCallback) => {
    @@ -260,7 +266,9 @@ 

    Type Definitions

    +

    promptCallback(url)

    + @@ -383,12 +391,16 @@
    Parameters:
    + + +

    showPrompt(message, defaultValue, callback)

    + @@ -558,6 +570,8 @@
    Parameters:
    + + @@ -572,13 +586,13 @@
    Parameters:

    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/parsers_html.js.html b/website/demo/docs/parsers_html.js.html index 53b36e59c..ea47eccf7 100644 --- a/website/demo/docs/parsers_html.js.html +++ b/website/demo/docs/parsers_html.js.html @@ -57,13 +57,13 @@

    Source: parsers/html.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/parsers_mobiledoc_0-2.js.html b/website/demo/docs/parsers_mobiledoc_0-2.js.html index a21343be7..c6cc7cacb 100644 --- a/website/demo/docs/parsers_mobiledoc_0-2.js.html +++ b/website/demo/docs/parsers_mobiledoc_0-2.js.html @@ -47,7 +47,7 @@

    Source: parsers/mobiledoc/0-2.js

    * @param {Mobiledoc} * @return {Post} */ - parse({version, sections: sectionData}) { + parse({sections: sectionData}) { try { const markerTypes = sectionData[0]; const sections = sectionData[1]; @@ -97,17 +97,17 @@

    Source: parsers/mobiledoc/0-2.js

    } } - parseCardSection([type, name, payload], post) { + parseCardSection([, name, payload], post) { const section = this.builder.createCardSection(name, payload); post.sections.append(section); } - parseImageSection([type, src], post) { + parseImageSection([, src], post) { const section = this.builder.createImageSection(src); post.sections.append(section); } - parseMarkupSection([type, tagName, markers], post) { + parseMarkupSection([, tagName, markers], post) { const section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName); post.sections.append(section); this.parseMarkers(markers, section); @@ -118,7 +118,7 @@

    Source: parsers/mobiledoc/0-2.js

    }); } - parseListSection([type, tagName, items], post) { + parseListSection([, tagName, items], post) { const section = this.builder.createListSection(tagName); post.sections.append(section); this.parseListItems(items, section); @@ -157,13 +157,13 @@

    Source: parsers/mobiledoc/0-2.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/parsers_mobiledoc_0-3-1.js.html b/website/demo/docs/parsers_mobiledoc_0-3-1.js.html index 742725491..ea8d85133 100644 --- a/website/demo/docs/parsers_mobiledoc_0-3-1.js.html +++ b/website/demo/docs/parsers_mobiledoc_0-3-1.js.html @@ -49,7 +49,7 @@

    Source: parsers/mobiledoc/0-3-1.js

    * @param {Mobiledoc} * @return {Post} */ - parse({ version, sections, markups: markerTypes, cards: cardTypes, atoms: atomTypes }) { + parse({ sections, markups: markerTypes, cards: cardTypes, atoms: atomTypes }) { try { const post = this.builder.createPost(); @@ -126,18 +126,18 @@

    Source: parsers/mobiledoc/0-3-1.js

    return cardType; } - parseCardSection([type, cardIndex], post) { + parseCardSection([, cardIndex], post) { const [name, payload] = this.getCardTypeFromIndex(cardIndex); const section = this.builder.createCardSection(name, payload); post.sections.append(section); } - parseImageSection([type, src], post) { + parseImageSection([, src], post) { const section = this.builder.createImageSection(src); post.sections.append(section); } - parseMarkupSection([type, tagName, markers], post) { + parseMarkupSection([, tagName, markers], post) { const section = this.builder.createMarkupSection(tagName); post.sections.append(section); this.parseMarkers(markers, section); @@ -148,7 +148,7 @@

    Source: parsers/mobiledoc/0-3-1.js

    }); } - parseListSection([type, tagName, items], post) { + parseListSection([, tagName, items], post) { const section = this.builder.createListSection(tagName); post.sections.append(section); this.parseListItems(items, section); @@ -183,9 +183,10 @@

    Source: parsers/mobiledoc/0-3-1.js

    switch (type) { case MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); - case MOBILEDOC_ATOM_MARKER_TYPE: + case MOBILEDOC_ATOM_MARKER_TYPE: { const [atomName, atomValue, atomPayload] = this.getAtomTypeFromIndex(value); return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: assert(`Unexpected marker type ${type}`, false); } @@ -201,13 +202,13 @@

    Source: parsers/mobiledoc/0-3-1.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/parsers_mobiledoc_0-3-2.js.html b/website/demo/docs/parsers_mobiledoc_0-3-2.js.html new file mode 100644 index 000000000..161a76c62 --- /dev/null +++ b/website/demo/docs/parsers_mobiledoc_0-3-2.js.html @@ -0,0 +1,229 @@ + + + + + JSDoc: Source: parsers/mobiledoc/0-3-2.js + + + + + + + + + + +
    + +

    Source: parsers/mobiledoc/0-3-2.js

    + + + + + + +
    +
    +
    import {
    +  MOBILEDOC_MARKUP_SECTION_TYPE,
    +  MOBILEDOC_IMAGE_SECTION_TYPE,
    +  MOBILEDOC_LIST_SECTION_TYPE,
    +  MOBILEDOC_CARD_SECTION_TYPE,
    +  MOBILEDOC_MARKUP_MARKER_TYPE,
    +  MOBILEDOC_ATOM_MARKER_TYPE
    +} from '../../renderers/mobiledoc/0-3-2';
    +
    +import { kvArrayToObject, filter } from '../../utils/array-utils';
    +import assert from '../../utils/assert';
    +import { entries } from '../../utils/object-utils';
    +
    +/*
    + * Parses from mobiledoc -> post
    + */
    +export default class MobiledocParser {
    +  constructor(builder) {
    +    this.builder = builder;
    +  }
    +
    +  /**
    +   * @param {Mobiledoc}
    +   * @return {Post}
    +   */
    +  parse({ sections, markups: markerTypes, cards: cardTypes, atoms: atomTypes }) {
    +    try {
    +      const post = this.builder.createPost();
    +
    +      this.markups = [];
    +      this.markerTypes = this.parseMarkerTypes(markerTypes);
    +      this.cardTypes = this.parseCardTypes(cardTypes);
    +      this.atomTypes = this.parseAtomTypes(atomTypes);
    +      this.parseSections(sections, post);
    +
    +      return post;
    +    } catch (e) {
    +      assert(`Unable to parse mobiledoc: ${e.message}`, false);
    +    }
    +  }
    +
    +  parseMarkerTypes(markerTypes) {
    +    return markerTypes.map((markerType) => this.parseMarkerType(markerType));
    +  }
    +
    +  parseMarkerType([tagName, attributesArray]) {
    +    const attributesObject = kvArrayToObject(attributesArray || []);
    +    return this.builder.createMarkup(tagName, attributesObject);
    +  }
    +
    +  parseCardTypes(cardTypes) {
    +    return cardTypes.map((cardType) => this.parseCardType(cardType));
    +  }
    +
    +  parseCardType([cardName, cardPayload]) {
    +    return [cardName, cardPayload];
    +  }
    +
    +  parseAtomTypes(atomTypes) {
    +    return atomTypes.map((atomType) => this.parseAtomType(atomType));
    +  }
    +
    +  parseAtomType([atomName, atomValue, atomPayload]) {
    +    return [atomName, atomValue, atomPayload];
    +  }
    +
    +  parseSections(sections, post) {
    +    sections.forEach((section) => this.parseSection(section, post));
    +  }
    +
    +  parseSection(section, post) {
    +    let [type] = section;
    +    switch(type) {
    +      case MOBILEDOC_MARKUP_SECTION_TYPE:
    +        this.parseMarkupSection(section, post);
    +        break;
    +      case MOBILEDOC_IMAGE_SECTION_TYPE:
    +        this.parseImageSection(section, post);
    +        break;
    +      case MOBILEDOC_CARD_SECTION_TYPE:
    +        this.parseCardSection(section, post);
    +        break;
    +      case MOBILEDOC_LIST_SECTION_TYPE:
    +        this.parseListSection(section, post);
    +        break;
    +      default:
    +        assert('Unexpected section type ${type}', false);
    +    }
    +  }
    +
    +  getAtomTypeFromIndex(index) {
    +    const atomType = this.atomTypes[index];
    +    assert(`No atom definition found at index ${index}`, !!atomType);
    +    return atomType;
    +  }
    +
    +  getCardTypeFromIndex(index) {
    +    const cardType = this.cardTypes[index];
    +    assert(`No card definition found at index ${index}`, !!cardType);
    +    return cardType;
    +  }
    +
    +  parseCardSection([, cardIndex], post) {
    +    const [name, payload] = this.getCardTypeFromIndex(cardIndex);
    +    const section = this.builder.createCardSection(name, payload);
    +    post.sections.append(section);
    +  }
    +
    +  parseImageSection([, src], post) {
    +    const section = this.builder.createImageSection(src);
    +    post.sections.append(section);
    +  }
    +
    +  parseMarkupSection([, tagName, markers, attributesArray], post) {
    +    const section = this.builder.createMarkupSection(tagName);
    +    post.sections.append(section);
    +    if (attributesArray) {
    +      entries(kvArrayToObject(attributesArray)).forEach(([key, value]) => {
    +        section.setAttribute(key, value);
    +      });
    +    }
    +    this.parseMarkers(markers, section);
    +    // Strip blank markers after they have been created. This ensures any
    +    // markup they include has been correctly populated.
    +    filter(section.markers, m => m.isBlank).forEach(m => {
    +      section.markers.remove(m);
    +    });
    +  }
    +
    +  parseListSection([, tagName, items, attributesArray], post) {
    +    const section = this.builder.createListSection(tagName);
    +    post.sections.append(section);
    +    if (attributesArray) {
    +      entries(kvArrayToObject(attributesArray)).forEach(([key, value]) => {
    +        section.setAttribute(key, value);
    +      });
    +    }
    +    this.parseListItems(items, section);
    +  }
    +
    +  parseListItems(items, section) {
    +    items.forEach(i => this.parseListItem(i, section));
    +  }
    +
    +  parseListItem(markers, section) {
    +    const item = this.builder.createListItem();
    +    this.parseMarkers(markers, item);
    +    section.items.append(item);
    +  }
    +
    +  parseMarkers(markers, parent) {
    +    markers.forEach(m => this.parseMarker(m, parent));
    +  }
    +
    +  parseMarker([type, markerTypeIndexes, closeCount, value], parent) {
    +    markerTypeIndexes.forEach(index => {
    +      this.markups.push(this.markerTypes[index]);
    +    });
    +
    +    const marker = this.buildMarkerType(type, value);
    +    parent.markers.append(marker);
    +
    +    this.markups = this.markups.slice(0, this.markups.length-closeCount);
    +  }
    +
    +  buildMarkerType(type, value) {
    +    switch (type) {
    +      case MOBILEDOC_MARKUP_MARKER_TYPE:
    +        return this.builder.createMarker(value, this.markups.slice());
    +      case MOBILEDOC_ATOM_MARKER_TYPE: {
    +        const [atomName, atomValue, atomPayload] = this.getAtomTypeFromIndex(value);
    +        return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());
    +      }
    +      default:
    +        assert(`Unexpected marker type ${type}`, false);
    +    }
    +  }
    +}
    +
    +
    +
    + + + + +
    + + + +
    + +
    + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST) +
    + + + + + diff --git a/website/demo/docs/parsers_mobiledoc_0-3.js.html b/website/demo/docs/parsers_mobiledoc_0-3.js.html index 4e535b17f..7b35974c6 100644 --- a/website/demo/docs/parsers_mobiledoc_0-3.js.html +++ b/website/demo/docs/parsers_mobiledoc_0-3.js.html @@ -49,7 +49,7 @@

    Source: parsers/mobiledoc/0-3.js

    * @param {Mobiledoc} * @return {Post} */ - parse({ version, sections, markups: markerTypes, cards: cardTypes, atoms: atomTypes }) { + parse({ sections, markups: markerTypes, cards: cardTypes, atoms: atomTypes }) { try { const post = this.builder.createPost(); @@ -126,18 +126,18 @@

    Source: parsers/mobiledoc/0-3.js

    return cardType; } - parseCardSection([type, cardIndex], post) { + parseCardSection([, cardIndex], post) { const [name, payload] = this.getCardTypeFromIndex(cardIndex); const section = this.builder.createCardSection(name, payload); post.sections.append(section); } - parseImageSection([type, src], post) { + parseImageSection([, src], post) { const section = this.builder.createImageSection(src); post.sections.append(section); } - parseMarkupSection([type, tagName, markers], post) { + parseMarkupSection([, tagName, markers], post) { const section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName); post.sections.append(section); this.parseMarkers(markers, section); @@ -148,7 +148,7 @@

    Source: parsers/mobiledoc/0-3.js

    }); } - parseListSection([type, tagName, items], post) { + parseListSection([, tagName, items], post) { const section = this.builder.createListSection(tagName); post.sections.append(section); this.parseListItems(items, section); @@ -183,9 +183,10 @@

    Source: parsers/mobiledoc/0-3.js

    switch (type) { case MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); - case MOBILEDOC_ATOM_MARKER_TYPE: + case MOBILEDOC_ATOM_MARKER_TYPE: { const [atomName, atomValue, atomPayload] = this.getAtomTypeFromIndex(value); return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: assert(`Unexpected marker type ${type}`, false); } @@ -201,13 +202,13 @@

    Source: parsers/mobiledoc/0-3.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/parsers_text.js.html b/website/demo/docs/parsers_text.js.html index 71d166569..3ddb70932 100644 --- a/website/demo/docs/parsers_text.js.html +++ b/website/demo/docs/parsers_text.js.html @@ -90,11 +90,12 @@

    Source: parsers/text.js

    let markers = [this.builder.createMarker(text)]; switch (type) { - case LIST_SECTION_TYPE: + case LIST_SECTION_TYPE: { let item = this.builder.createListItem(markers); let list = this.builder.createListSection(tagName, [item]); section = list; break; + } case MARKUP_SECTION_TYPE: section = this.builder.createMarkupSection(tagName, markers); break; @@ -131,13 +132,13 @@

    Source: parsers/text.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/renderers_mobiledoc_0-2.js.html b/website/demo/docs/renderers_mobiledoc_0-2.js.html index 3cc260d1a..1a8ea8871 100644 --- a/website/demo/docs/renderers_mobiledoc_0-2.js.html +++ b/website/demo/docs/renderers_mobiledoc_0-2.js.html @@ -160,13 +160,13 @@

    Source: renderers/mobiledoc/0-2.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/renderers_mobiledoc_0-3-1.js.html b/website/demo/docs/renderers_mobiledoc_0-3-1.js.html index b44d2c095..7a31b0ee7 100644 --- a/website/demo/docs/renderers_mobiledoc_0-3-1.js.html +++ b/website/demo/docs/renderers_mobiledoc_0-3-1.js.html @@ -195,13 +195,13 @@

    Source: renderers/mobiledoc/0-3-1.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/renderers_mobiledoc_0-3-2.js.html b/website/demo/docs/renderers_mobiledoc_0-3-2.js.html new file mode 100644 index 000000000..a9cca4af9 --- /dev/null +++ b/website/demo/docs/renderers_mobiledoc_0-3-2.js.html @@ -0,0 +1,210 @@ + + + + + JSDoc: Source: renderers/mobiledoc/0-3-2.js + + + + + + + + + + +
    + +

    Source: renderers/mobiledoc/0-3-2.js

    + + + + + + +
    +
    +
    import {visit, visitArray, compile} from '../../utils/compiler';
    +import { objectToSortedKVArray } from '../../utils/array-utils';
    +import {
    +  POST_TYPE,
    +  MARKUP_SECTION_TYPE,
    +  LIST_SECTION_TYPE,
    +  LIST_ITEM_TYPE,
    +  MARKER_TYPE,
    +  MARKUP_TYPE,
    +  IMAGE_SECTION_TYPE,
    +  CARD_TYPE,
    +  ATOM_TYPE
    +} from '../../models/types';
    +
    +export const MOBILEDOC_VERSION = '0.3.2';
    +export const MOBILEDOC_MARKUP_SECTION_TYPE = 1;
    +export const MOBILEDOC_IMAGE_SECTION_TYPE = 2;
    +export const MOBILEDOC_LIST_SECTION_TYPE = 3;
    +export const MOBILEDOC_CARD_SECTION_TYPE = 10;
    +
    +export const MOBILEDOC_MARKUP_MARKER_TYPE = 0;
    +export const MOBILEDOC_ATOM_MARKER_TYPE = 1;
    +
    +const visitor = {
    +  [POST_TYPE](node, opcodes) {
    +    opcodes.push(['openPost']);
    +    visitArray(visitor, node.sections, opcodes);
    +  },
    +  [MARKUP_SECTION_TYPE](node, opcodes) {
    +    opcodes.push(['openMarkupSection', node.tagName, objectToSortedKVArray(node.attributes)]);
    +    visitArray(visitor, node.markers, opcodes);
    +  },
    +  [LIST_SECTION_TYPE](node, opcodes) {
    +    opcodes.push(['openListSection', node.tagName, objectToSortedKVArray(node.attributes)]);
    +    visitArray(visitor, node.items, opcodes);
    +  },
    +  [LIST_ITEM_TYPE](node, opcodes) {
    +    opcodes.push(['openListItem']);
    +    visitArray(visitor, node.markers, opcodes);
    +  },
    +  [IMAGE_SECTION_TYPE](node, opcodes) {
    +    opcodes.push(['openImageSection', node.src]);
    +  },
    +  [CARD_TYPE](node, opcodes) {
    +    opcodes.push(['openCardSection', node.name, node.payload]);
    +  },
    +  [MARKER_TYPE](node, opcodes) {
    +    opcodes.push(['openMarker', node.closedMarkups.length, node.value]);
    +    visitArray(visitor, node.openedMarkups, opcodes);
    +  },
    +  [MARKUP_TYPE](node, opcodes) {
    +    opcodes.push(['openMarkup', node.tagName, objectToSortedKVArray(node.attributes)]);
    +  },
    +  [ATOM_TYPE](node, opcodes) {
    +    opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);
    +    visitArray(visitor, node.openedMarkups, opcodes);
    +  }
    +};
    +
    +const postOpcodeCompiler = {
    +  openMarker(closeCount, value) {
    +    this.markupMarkerIds = [];
    +    this.markers.push([
    +      MOBILEDOC_MARKUP_MARKER_TYPE,
    +      this.markupMarkerIds,
    +      closeCount,
    +      value || ''
    +    ]);
    +  },
    +  openMarkupSection(tagName, attributes) {
    +    this.markers = [];
    +    this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]);
    +  },
    +  openListSection(tagName, attributes) {
    +    this.items = [];
    +    this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]);
    +  },
    +  openListItem() {
    +    this.markers = [];
    +    this.items.push(this.markers);
    +  },
    +  openImageSection(url) {
    +    this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);
    +  },
    +  openCardSection(name, payload) {
    +    const index = this._addCardTypeIndex(name, payload);
    +    this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);
    +  },
    +  openAtom(closeCount, name, value, payload) {
    +    const index = this._addAtomTypeIndex(name, value, payload);
    +    this.markupMarkerIds = [];
    +    this.markers.push([
    +      MOBILEDOC_ATOM_MARKER_TYPE,
    +      this.markupMarkerIds,
    +      closeCount,
    +      index
    +    ]);
    +  },
    +  openPost() {
    +    this.atomTypes = [];
    +    this.cardTypes = [];
    +    this.markerTypes = [];
    +    this.sections = [];
    +    this.result = {
    +      version: MOBILEDOC_VERSION,
    +      atoms: this.atomTypes,
    +      cards: this.cardTypes,
    +      markups: this.markerTypes,
    +      sections: this.sections
    +    };
    +  },
    +  openMarkup(tagName, attributes) {
    +    const index = this._findOrAddMarkerTypeIndex(tagName, attributes);
    +    this.markupMarkerIds.push(index);
    +  },
    +  _addCardTypeIndex(cardName, payload) {
    +    let cardType = [cardName, payload];
    +    this.cardTypes.push(cardType);
    +    return this.cardTypes.length - 1;
    +  },
    +  _addAtomTypeIndex(atomName, atomValue, payload) {
    +    let atomType = [atomName, atomValue, payload];
    +    this.atomTypes.push(atomType);
    +    return this.atomTypes.length - 1;
    +  },
    +  _findOrAddMarkerTypeIndex(tagName, attributesArray) {
    +    if (!this._markerTypeCache) { this._markerTypeCache = {}; }
    +    const key = `${tagName}-${attributesArray.join('-')}`;
    +
    +    let index = this._markerTypeCache[key];
    +    if (index === undefined) {
    +      let markerType = [tagName];
    +      if (attributesArray.length) { markerType.push(attributesArray); }
    +      this.markerTypes.push(markerType);
    +
    +      index =  this.markerTypes.length - 1;
    +      this._markerTypeCache[key] = index;
    +    }
    +
    +    return index;
    +  }
    +};
    +
    +/**
    + * Render from post -> mobiledoc
    + */
    +export default {
    +  /**
    +   * @param {Post}
    +   * @return {Mobiledoc}
    +   */
    +  render(post) {
    +    let opcodes = [];
    +    visit(visitor, post, opcodes);
    +    let compiler = Object.create(postOpcodeCompiler);
    +    compile(compiler, opcodes);
    +    return compiler.result;
    +  }
    +};
    +
    +
    +
    + + + + +
    + + + +
    + +
    + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST) +
    + + + + + diff --git a/website/demo/docs/renderers_mobiledoc_0-3.js.html b/website/demo/docs/renderers_mobiledoc_0-3.js.html index 80a7591a1..5a229aac7 100644 --- a/website/demo/docs/renderers_mobiledoc_0-3.js.html +++ b/website/demo/docs/renderers_mobiledoc_0-3.js.html @@ -195,13 +195,13 @@

    Source: renderers/mobiledoc/0-3.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/styles/jsdoc-default.css b/website/demo/docs/styles/jsdoc-default.css index ede191943..9207bc824 100644 --- a/website/demo/docs/styles/jsdoc-default.css +++ b/website/demo/docs/styles/jsdoc-default.css @@ -78,6 +78,10 @@ article dl { margin-bottom: 40px; } +article img { + max-width: 100%; +} + section { display: block; @@ -218,8 +222,8 @@ thead tr th { border-right: 1px solid #aaa; } tr > th:last-child { border-right: 1px solid #ddd; } -.ancestors { color: #999; } -.ancestors a +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a { color: #999 !important; text-decoration: none; diff --git a/website/demo/docs/utils_cursor.js.html b/website/demo/docs/utils_cursor.js.html index 5427cdf6e..a7f592410 100644 --- a/website/demo/docs/utils_cursor.js.html +++ b/website/demo/docs/utils_cursor.js.html @@ -222,13 +222,13 @@

    Source: utils/cursor.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/utils_cursor_position.js.html b/website/demo/docs/utils_cursor_position.js.html index 3b9c9e7a0..a96179b73 100644 --- a/website/demo/docs/utils_cursor_position.js.html +++ b/website/demo/docs/utils_cursor_position.js.html @@ -39,7 +39,9 @@

    Source: utils/cursor/position.js

    const { FORWARD, BACKWARD } = DIRECTION; -const WORD_CHAR_REGEX = /\w|_|:/; +// generated via http://xregexp.com/ to cover chars that \w misses +// (new XRegExp('\\p{Alphabetic}|[0-9]|_|:')).toString() +const WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]|[0-9]|_|:/; function findParentSectionFromNode(renderTree, node) { let renderNode = renderTree.findRenderNodeFromElement( @@ -437,6 +439,12 @@

    Source: utils/cursor/position.js

    sectionOffset += postNode.length; } position = new Position(section, sectionOffset); + } else if (offset >= elementNode.childNodes.length) { + + // This is to deal with how Firefox handles triple-click selections. + // See https://stackoverflow.com/a/21234837/1269194 for an + // explanation. + position = section.tailPosition(); } else { // The offset is 0 if the cursor is on a non-atom-wrapper element node // (e.g., a <br> tag in a blank markup section) @@ -493,13 +501,13 @@

    Source: utils/cursor/position.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/utils_cursor_range.js.html b/website/demo/docs/utils_cursor_range.js.html index d9c561cbf..b9f0887f7 100644 --- a/website/demo/docs/utils_cursor_range.js.html +++ b/website/demo/docs/utils_cursor_range.js.html @@ -117,9 +117,10 @@

    Source: utils/cursor/range.js

    return new Range(head, tail.move(units), currentDirection); case DIRECTION.BACKWARD: return new Range(head.move(units), tail, currentDirection); - default: + default: { let newDirection = units > 0 ? DIRECTION.FORWARD : DIRECTION.BACKWARD; return new Range(head, tail, newDirection).extend(units); + } } } @@ -168,12 +169,20 @@

    Source: utils/cursor/range.js

    return !detectMarker(i); }; - let headMarker = head.section.markers.detect(firstNotMatchingDetect, head.marker, true); - headMarker = (headMarker && headMarker.next) || head.marker; + let headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true); + if (!headMarker && detectMarker(headSection.markers.head)) { + headMarker = headSection.markers.head; + } else { + headMarker = headMarker.next || head.marker; + } let headPosition = new Position(headSection, headSection.offsetOfMarker(headMarker)); let tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker); - tailMarker = (tailMarker && tailMarker.prev) || tail.marker; + if (!tailMarker && detectMarker(headSection.markers.tail)) { + tailMarker = headSection.markers.tail; + } else { + tailMarker = tailMarker.prev || tail.marker; + } let tailPosition = new Position(tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length); return headPosition.toRange(tailPosition, direction); @@ -238,13 +247,13 @@

    Source: utils/cursor/range.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/utils_deprecate.js.html b/website/demo/docs/utils_deprecate.js.html index 713a09920..1284cd75e 100644 --- a/website/demo/docs/utils_deprecate.js.html +++ b/website/demo/docs/utils_deprecate.js.html @@ -37,7 +37,8 @@

    Source: utils/deprecate.js

    */ export default function deprecate(message, conditional=false) { if (!conditional) { - console.log(`[mobiledoc-kit] [DEPRECATED]: ${message}`); // jshint ignore:line + // eslint-disable-next-line no-console + console.log(`[mobiledoc-kit] [DEPRECATED]: ${message}`); } }
    @@ -50,13 +51,13 @@

    Source: utils/deprecate.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/docs/utils_key.js.html b/website/demo/docs/utils_key.js.html index 32a493211..999f95239 100644 --- a/website/demo/docs/utils_key.js.html +++ b/website/demo/docs/utils_key.js.html @@ -27,6 +27,7 @@

    Source: utils/key.js

    import Keycodes from './keycodes';
    +import Keys from './keys';
     import { TAB } from 'mobiledoc-kit/utils/characters';
     
     /**
    @@ -61,7 +62,7 @@ 

    Source: utils/key.js

    modVal(altKey, MODIFIERS.ALT); } -export const SPECIAL_KEYS = { +const SPECIAL_KEYS = { BACKSPACE: Keycodes.BACKSPACE, TAB: Keycodes.TAB, ENTER: Keycodes.ENTER, @@ -79,6 +80,10 @@

    Source: utils/key.js

    DEL: Keycodes.DELETE }; +export function specialCharacterToCode(specialCharacter) { + return SPECIAL_KEYS[specialCharacter]; +} + // heuristic for determining if `event` is a key event function isKeyEvent(event) { return /^key/.test(event.type); @@ -91,6 +96,7 @@

    Source: utils/key.js

    */ const Key = class Key { constructor(event) { + this.key = event.key; this.keyCode = event.keyCode; this.charCode = event.charCode; this.event = event; @@ -108,17 +114,31 @@

    Source: utils/key.js

    return String.fromCharCode(this.charCode); } + // See https://caniuse.com/#feat=keyboardevent-key for browser support. + isKeySupported() { + return this.key; + } + + isKey(identifier) { + if (this.isKeySupported()) { + assert(`Must define Keys.${identifier}.`, Keys[identifier]); + return this.key === Keys[identifier]; + } else { + assert(`Must define Keycodes.${identifier}.`, Keycodes[identifier]); + return this.keyCode === Keycodes[identifier]; + } + } + isEscape() { - return this.keyCode === Keycodes.ESC; + return this.isKey('ESC'); } isDelete() { - return this.keyCode === Keycodes.BACKSPACE || - this.keyCode === Keycodes.DELETE; + return this.isKey('BACKSPACE') || this.isForwardDelete(); } isForwardDelete() { - return this.keyCode === Keycodes.DELETE; + return this.isKey('DELETE'); } isArrow() { @@ -126,8 +146,7 @@

    Source: utils/key.js

    } isHorizontalArrow() { - return this.keyCode === Keycodes.LEFT || - this.keyCode === Keycodes.RIGHT; + return this.isLeftArrow() || this.isRightArrow(); } isHorizontalArrowWithoutModifiersOtherThanShift() { @@ -136,57 +155,62 @@

    Source: utils/key.js

    } isVerticalArrow() { - return this.keyCode === Keycodes.UP || - this.keyCode === Keycodes.DOWN; + return this.isKey('UP') || this.isKey('DOWN'); } isLeftArrow() { - return this.keyCode === Keycodes.LEFT; + return this.isKey('LEFT'); } isRightArrow() { - return this.keyCode === Keycodes.RIGHT; + return this.isKey('RIGHT'); } isHome() { - return this.keyCode === Keycodes.HOME; + return this.isKey('HOME'); } isEnd() { - return this.keyCode === Keycodes.END; + return this.isKey('END'); } - get direction() { - switch (true) { - case this.isDelete(): - return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; - case this.isHorizontalArrow(): - return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; - } + isPageUp() { + return this.isKey('PAGEUP'); + } + + isPageDown() { + return this.isKey('PAGEDOWN'); + } + + isInsert() { + return this.isKey('INS'); + } + + isClear() { + return this.isKey('CLEAR'); + } + + isPause() { + return this.isKey('PAUSE'); } isSpace() { - return this.keyCode === Keycodes.SPACE; + return this.isKey('SPACE'); } + // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but + // it will also fire a keydown event for the tab+modifier (ctrl). This causes + // Mobiledoc to erroneously insert a tab character before FF switches to the + // new browser tab. Chrome doesn't fire this event so the issue doesn't + // arise there. Fix this by returning false when the TAB key event includes a + // modifier. + // See: https://github.com/bustle/mobiledoc-kit/issues/565 isTab() { - return this.keyCode === Keycodes.TAB; + return !this.hasAnyModifier() && this.isKey('TAB'); } isEnter() { - return this.keyCode === Keycodes.ENTER; - } - - /** - * If the shift key is depressed. - * For example, while holding down meta+shift, pressing the "v" - * key would result in an event whose `Key` had `isShift()` with a truthy value, - * because the shift key is down when pressing the "v". - * @see {isShiftKey} which checks if the key is actually the shift key itself. - * @return {bool} - */ - isShift() { - return this.shiftKey; + return this.isKey('ENTER'); } /* @@ -196,7 +220,7 @@

    Source: utils/key.js

    * @return {bool} */ isShiftKey() { - return this.keyCode === Keycodes.SHIFT; + return this.isKey('SHIFT'); } /* @@ -205,7 +229,7 @@

    Source: utils/key.js

    * @return {bool} */ isAltKey() { - return this.keyCode === Keycodes.ALT; + return this.isKey('ALT'); } /* @@ -214,7 +238,34 @@

    Source: utils/key.js

    * @return {bool} */ isCtrlKey() { - return this.keyCode === Keycodes.CTRL; + return this.isKey('CTRL'); + } + + isIME() { + // FIXME the IME action seems to get lost when we issue an + // `editor.deleteSelection` before it (in Chrome) + return this.keyCode === Keycodes.IME; + } + + get direction() { + switch (true) { + case this.isDelete(): + return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; + case this.isHorizontalArrow(): + return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; + } + } + + /** + * If the shift key is depressed. + * For example, while holding down meta+shift, pressing the "v" + * key would result in an event whose `Key` had `isShift()` with a truthy value, + * because the shift key is down when pressing the "v". + * @see {isShiftKey} which checks if the key is actually the shift key itself. + * @return {bool} + */ + isShift() { + return this.shiftKey; } hasModifier(modifier) { @@ -241,6 +292,50 @@

    Source: utils/key.js

    return MODIFIERS.ALT & this.modifierMask; } + isPrintableKey() { + return !( + this.isArrow() || + this.isHome() || this.isEnd() || + this.isPageUp() || this.isPageDown() || + this.isInsert() || this.isClear() || this.isPause() || + this.isEscape() + ); + } + + isNumberKey() { + if (this.isKeySupported()) { + return this.key >= '0' && this.key <= '9'; + } else { + const code = this.keyCode; + return (code >= Keycodes['0'] && code <= Keycodes['9']) || + (code >= Keycodes.NUMPAD_0 && code <= Keycodes.NUMPAD_9); // numpad keys + } + } + + isLetterKey() { + if (this.isKeySupported()) { + const key = this.key; + return (key >= 'a' && key <= 'z') || + (key >= 'A' && key <= 'Z'); + } else { + const code = this.keyCode; + return (code >= Keycodes.A && code <= Keycodes.Z) || + (code >= Keycodes.a && code <= Keycodes.z); + } + } + + isPunctuation() { + if (this.isKeySupported()) { + const key = this.key; + return (key >= ';' && key <= '`') || + (key >= '[' && key <= '"'); + } else { + const code = this.keyCode; + return (code >= Keycodes[';'] && code <= Keycodes['`']) || + (code >= Keycodes['['] && code <= Keycodes['"']); + } + } + /** * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position * and http://stackoverflow.com/a/12467610/137784 @@ -250,31 +345,21 @@

    Source: utils/key.js

    return false; } - const {keyCode:code} = this; - - // Firefox calls keypress events for arrow keys, but they should not be - // considered printable - if (this.isArrow()) { + // Firefox calls keypress events for some keys that should not be printable + if (!this.isPrintableKey()) { return false; } return ( - code !== 0 || + this.keyCode !== 0 || this.toString().length > 0 || - (code >= Keycodes['0'] && code <= Keycodes['9']) || // number keys + this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || - ( - (code >= Keycodes.A && code <= Keycodes.Z) || // letter keys - (code >= Keycodes.a && code <= Keycodes.z) - ) || - (code >= Keycodes.NUMPAD_0 && code <= Keycodes.NUMPAD_9) || // numpad keys - (code >= Keycodes[';'] && code <= Keycodes['`']) || // punctuation - (code >= Keycodes['['] && code <= Keycodes['"']) || - // FIXME the IME action seems to get lost when we issue an `editor.deleteSelection` - // before it (in Chrome) - code === Keycodes.IME + this.isLetterKey() || + this.isPunctuation() || + this.isIME() ); } }; @@ -290,13 +375,13 @@

    Source: utils/key.js


    - Documentation generated by JSDoc 3.4.3 on Tue Jun 06 2017 10:05:08 GMT-0700 (PDT) + Documentation generated by JSDoc 3.5.5 on Fri Jan 10 2020 08:57:41 GMT-0500 (EST)
    diff --git a/website/demo/index.html b/website/demo/index.html index 2c42ba2b1..a242cfd91 100644 --- a/website/demo/index.html +++ b/website/demo/index.html @@ -56,12 +56,42 @@
    - - - - - - + +
    + + + +
    +
    + + +
    +
    + + +
    +
    + + + + +
    @@ -173,8 +203,7 @@

    Basic Editor

    Toolbar Buttons

    - Use the editor.toggleMarkup and editor.toggleSection methods to modify - the text. + Use the editor.toggleMarkup, editor.toggleSection and editor.setAttribute methods to modify the text.

    @@ -186,15 +215,18 @@

    Toolbar Buttons

    $('button.strong').click(() => { editor.toggleMarkup('strong'); }); + $('button.center').click(() => { + editor.setAttribute('text-align', 'center'); + });
    - - - - + + + +
    @@ -240,8 +272,8 @@

    Cards and Atoms

    - - + +
    diff --git a/website/demo/vendor/mobiledoc-pretty-json-renderer.js b/website/demo/vendor/mobiledoc-pretty-json-renderer.js index 876e8ebbb..3591b3399 100644 --- a/website/demo/vendor/mobiledoc-pretty-json-renderer.js +++ b/website/demo/vendor/mobiledoc-pretty-json-renderer.js @@ -1,7 +1,5 @@ -'use strict'; - var mobiledocPrettyJSONRenderer = -/******/(function (modules) { +/******/function (modules) { // webpackBootstrap /******/ // The module cache /******/var installedModules = {}; @@ -43,11 +41,11 @@ var mobiledocPrettyJSONRenderer = /******/ // Load entry module and return exports /******/return __webpack_require__(0); /******/ -})( +}( /************************************************************************/ /******/[ /* 0 */ -function (module, exports, __webpack_require__) { +/***/function (module, exports, __webpack_require__) { var utils = __webpack_require__(1); var formatters = __webpack_require__(2); @@ -97,7 +95,7 @@ function (module, exports, __webpack_require__) { /***/ }, /* 1 */ -function (module, exports) { +/***/function (module, exports) { function indent(multiline, depth) { var indent = []; @@ -145,7 +143,7 @@ function (module, exports) { /***/ }, /* 2 */ -function (module, exports, __webpack_require__) { +/***/function (module, exports, __webpack_require__) { var utils = __webpack_require__(1); var stringify = JSON.stringify; @@ -205,5 +203,4 @@ function (module, exports, __webpack_require__) { /***/ } -/******/]); -/***/ /***/ /***/ \ No newline at end of file +/******/]); \ No newline at end of file diff --git a/website/global/mobiledoc-kit.js b/website/global/mobiledoc-kit.js index 6cb61c287..d56c969b3 100644 --- a/website/global/mobiledoc-kit.js +++ b/website/global/mobiledoc-kit.js @@ -4,8 +4,6 @@ var loader, define, requireModule, require, requirejs; (function (global) { 'use strict'; - var heimdall = global.heimdall; - function dict() { var obj = Object.create(null); obj['__'] = undefined; @@ -22,9 +20,9 @@ var loader, define, requireModule, require, requirejs; requirejs: requirejs }; - requirejs = require = requireModule = function (name) { + requirejs = require = requireModule = function (id) { var pending = []; - var mod = findModule(name, '(require)', pending); + var mod = findModule(id, '(require)', pending); for (var i = pending.length - 1; i >= 0; i--) { pending[i].exports(); @@ -47,32 +45,25 @@ var loader, define, requireModule, require, requirejs; } } } - } + }, + // Option to enable or disable the generation of default exports + makeDefaultExport: true }; - var _isArray; - if (!Array.isArray) { - _isArray = function (x) { - return Object.prototype.toString.call(x) === '[object Array]'; - }; - } else { - _isArray = Array.isArray; - } - var registry = dict(); var seen = dict(); var uuid = 0; function unsupportedModule(length) { - throw new Error('an unsupported module was defined, expected `define(name, deps, module)` instead got: `' + length + '` arguments to define`'); + throw new Error('an unsupported module was defined, expected `define(id, deps, module)` instead got: `' + length + '` arguments to define`'); } var defaultDeps = ['require', 'exports', 'module']; - function Module(name, deps, callback, alias) { - this.id = uuid++; - this.name = name; + function Module(id, deps, callback, alias) { + this.uuid = uuid++; + this.id = id; this.deps = !deps.length && callback.length ? defaultDeps : deps; this.module = { exports: {} }; this.callback = callback; @@ -106,19 +97,23 @@ var loader, define, requireModule, require, requirejs; return this.module.exports; } + if (loader.wrapModules) { - this.callback = loader.wrapModules(this.name, this.callback); + this.callback = loader.wrapModules(this.id, this.callback); } this.reify(); var result = this.callback.apply(this, this.reified); + this.reified.length = 0; this.state = 'finalized'; if (!(this.hasExportsAsDep && result === undefined)) { this.module.exports = result; } - this.makeDefaultExport(); + if (loader.makeDefaultExport) { + this.makeDefaultExport(); + } return this.module.exports; }; @@ -171,27 +166,28 @@ var loader, define, requireModule, require, requirejs; } else if (dep === 'module') { entry.exports = this.module; } else { - entry.module = findModule(resolve(dep, this.name), this.name, pending); + entry.module = findModule(resolve(dep, this.id), this.id, pending); } } }; Module.prototype.makeRequire = function () { - var name = this.name; + var id = this.id; var r = function (dep) { - return require(resolve(dep, name)); + return require(resolve(dep, id)); }; r['default'] = r; + r.moduleId = id; r.has = function (dep) { - return has(resolve(dep, name)); + return has(resolve(dep, id)); }; return r; }; - define = function (name, deps, callback) { - var module = registry[name]; + define = function (id, deps, callback) { + var module = registry[id]; - // If a module for this name has already been defined and is in any state + // If a module for this id has already been defined and is in any state // other than `new` (meaning it has been or is currently being required), // then we return early to avoid redefinition. if (module && module.state !== 'new') { @@ -202,42 +198,65 @@ var loader, define, requireModule, require, requirejs; unsupportedModule(arguments.length); } - if (!_isArray(deps)) { + if (!Array.isArray(deps)) { callback = deps; deps = []; } if (callback instanceof Alias) { - registry[name] = new Module(callback.name, deps, callback, true); + registry[id] = new Module(callback.id, deps, callback, true); } else { - registry[name] = new Module(name, deps, callback, false); + registry[id] = new Module(id, deps, callback, false); + } + }; + + define.exports = function (name, defaultExport) { + var module = registry[name]; + + // If a module for this name has already been defined and is in any state + // other than `new` (meaning it has been or is currently being required), + // then we return early to avoid redefinition. + if (module && module.state !== 'new') { + return; } + + module = new Module(name, [], noop, null); + module.module.exports = defaultExport; + module.state = 'finalized'; + registry[name] = module; + + return module; }; + function noop() {} // we don't support all of AMD // define.amd = {}; - function Alias(path) { - this.name = path; + function Alias(id) { + this.id = id; } - define.alias = function (path) { - return new Alias(path); + define.alias = function (id, target) { + if (arguments.length === 2) { + return define(target, new Alias(id)); + } + + return new Alias(id); }; - function missingModule(name, referrer) { - throw new Error('Could not find module `' + name + '` imported from `' + referrer + '`'); + function missingModule(id, referrer) { + throw new Error('Could not find module `' + id + '` imported from `' + referrer + '`'); } - function findModule(name, referrer, pending) { - var mod = registry[name] || registry[name + '/index']; + function findModule(id, referrer, pending) { + var mod = registry[id] || registry[id + '/index']; while (mod && mod.isAlias) { - mod = registry[mod.name]; + mod = registry[mod.id] || registry[mod.id + '/index']; } if (!mod) { - missingModule(name, referrer); + missingModule(id, referrer); } if (pending && mod.state !== 'pending' && mod.state !== 'finalized') { @@ -247,13 +266,14 @@ var loader, define, requireModule, require, requirejs; return mod; } - function resolve(child, name) { + function resolve(child, id) { if (child.charAt(0) !== '.') { return child; } + var parts = child.split('/'); - var nameParts = name.split('/'); + var nameParts = id.split('/'); var parentBase = nameParts.slice(0, -1); for (var i = 0, l = parts.length; i < l; i++) { @@ -274,14 +294,14 @@ var loader, define, requireModule, require, requirejs; return parentBase.join('/'); } - function has(name) { - return !!(registry[name] || registry[name + '/index']); + function has(id) { + return !!(registry[id] || registry[id + '/index']); } requirejs.entries = requirejs._eak_seen = registry; requirejs.has = has; - requirejs.unsee = function (moduleName) { - findModule(moduleName, '(unsee)', false).unsee(); + requirejs.unsee = function (id) { + findModule(id, '(unsee)', false).unsee(); }; requirejs.clear = function () { @@ -300,9 +320,12 @@ var loader, define, requireModule, require, requirejs; }); define('foo/baz', [], define.alias('foo')); define('foo/quz', define.alias('foo')); + define.alias('foo', 'foo/qux'); define('foo/bar', ['foo', './quz', './baz', './asdf', './bar', '../foo'], function () {}); define('foo/main', ['foo/bar'], function () {}); + define.exports('foo/exports', {}); + require('foo/exports'); require('foo/main'); require.unsee('foo/bar'); @@ -442,6 +465,7 @@ define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-ren return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render(); case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0: case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1: + case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_2: return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render(); default: throw new Error('Unexpected Mobiledoc version "' + version + '"'); @@ -821,15 +845,16 @@ define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-render exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0; var MOBILEDOC_VERSION_0_3_1 = '0.3.1'; exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1; - var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_0; + var MOBILEDOC_VERSION_0_3_2 = '0.3.2'; - exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; + exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2; var IMAGE_SECTION_TAG_NAME = 'img'; function validateVersion(version) { switch (version) { case MOBILEDOC_VERSION_0_3_0: case MOBILEDOC_VERSION_0_3_1: + case MOBILEDOC_VERSION_0_3_2: return; default: throw new Error('Unexpected Mobiledoc version "' + version + '"'); @@ -1248,19 +1273,22 @@ define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-render }, { key: 'renderMarkupSection', value: function renderMarkupSection(_ref5) { - var _ref52 = _slicedToArray(_ref5, 3); + var _ref52 = _slicedToArray(_ref5, 4); var type = _ref52[0]; var tagName = _ref52[1]; var markers = _ref52[2]; + var _ref52$3 = _ref52[3]; + var attributes = _ref52$3 === undefined ? [] : _ref52$3; tagName = tagName.toLowerCase(); if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) { return; } + var attrsObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attributes); var renderer = this.sectionElementRendererFor(tagName); - var element = renderer(tagName, this.dom); + var element = renderer(tagName, this.dom, attrsObj); this.renderMarkersOnElement(element, markers); return element; @@ -1299,6 +1327,8 @@ define("mobiledoc-dom-renderer/utils/array-utils", ["exports"], function (export "use strict"; exports.includes = includes; + exports.kvArrayToObject = kvArrayToObject; + exports.objectToSortedKVArray = objectToSortedKVArray; function includes(array, detectValue) { for (var i = 0; i < array.length; i++) { @@ -1309,6 +1339,43 @@ define("mobiledoc-dom-renderer/utils/array-utils", ["exports"], function (export } return false; } + + /** + * @param {Array} array of key1,value1,key2,value2,... + * @return {Object} {key1:value1, key2:value2, ...} + * @private + */ + + function kvArrayToObject(array) { + if (!Array.isArray(array)) { + return {}; + } + + var obj = {}; + for (var i = 0; i < array.length; i += 2) { + var key = array[i]; + var value = array[i + 1]; + + obj[key] = value; + } + return obj; + } + + /** + * @param {Object} {key1:value1, key2:value2, ...} + * @return {Array} array of key1,value1,key2,value2,... + * @private + */ + + function objectToSortedKVArray(obj) { + var keys = Object.keys(obj).sort(); + var result = []; + keys.forEach(function (k) { + result.push(k); + result.push(obj[k]); + }); + return result; + } }); define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) { 'use strict'; @@ -1346,11 +1413,31 @@ define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-r exports.defaultSectionElementRenderer = defaultSectionElementRenderer; exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer; + var VALID_ATTRIBUTES = ['data-md-text-align']; + + exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + function _isValidAttribute(attr) { + return VALID_ATTRIBUTES.indexOf(attr) !== -1; + } + + function handleMarkupSectionAttribute(element, attributeKey, attributeValue) { + if (!_isValidAttribute(attributeKey)) { + throw new Error('Cannot use attribute: ' + attributeKey); + } + + element.setAttribute(attributeKey, attributeValue); + } function defaultSectionElementRenderer(tagName, dom) { + var attrsObj = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; + var element = undefined; if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { element = dom.createElement(tagName); + + Object.keys(attrsObj).forEach(function (k) { + handleMarkupSectionAttribute(element, k, attrsObj[k]); + }); } else { element = dom.createElement('div'); element.setAttribute('class', tagName); @@ -1396,7 +1483,7 @@ define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc } function sanitizeHref(url) { - var protocol = getProtocol(url); + var protocol = getProtocol(url).toLowerCase(); if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) { return 'unsafe:' + url; } @@ -1480,8 +1567,6 @@ define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder type: 'dom', render: function render(_ref) { - var env = _ref.env; - var options = _ref.options; var payload = _ref.payload; var img = document.createElement('img'); @@ -1690,7 +1775,8 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array range: _mobiledocKitUtilsCursorRange['default'].blankRange(), activeMarkups: [], activeSections: [], - activeSectionTagNames: [] + activeSectionTagNames: [], + activeSectionAttributes: {} }; this.prevState = this.state = defaultState; @@ -1731,7 +1817,7 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array var state = this.state; var prevState = this.prevState; - return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames); + return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)((0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes)); } /** @@ -1768,6 +1854,7 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array state.activeSectionTagNames = state.activeSections.map(function (s) { return s.isNested ? s.parent.tagName : s.tagName; }); + state.activeSectionAttributes = this._readSectionAttributes(state.activeSections); return state; } }, { @@ -1790,6 +1877,22 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array return post.markupsInRange(range); } + }, { + key: '_readSectionAttributes', + value: function _readSectionAttributes(sections) { + return sections.reduce(function (sectionAttributes, s) { + var attributes = s.isNested ? s.parent.attributes : s.attributes; + Object.keys(attributes || {}).forEach(function (attrName) { + var camelizedAttrName = attrName.replace(/^data-md-/, ''); + var attrValue = attributes[attrName]; + sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || []; + if (!(0, _mobiledocKitUtilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) { + sectionAttributes[camelizedAttrName].push(attrValue); + } + }); + return sectionAttributes; + }, {}); + } }, { key: '_removeActiveMarkup', value: function _removeActiveMarkup(markup) { @@ -1816,6 +1919,15 @@ define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array return this.state.activeSections; } + /** + * @return {Object} + */ + }, { + key: 'activeSectionAttributes', + get: function get() { + return this.state.activeSectionAttributes; + } + /** * @return {Markup[]} */ @@ -1851,6 +1963,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', placeholder: 'Write here...', spellcheck: true, autofocus: true, + showLinkTooltips: true, undoDepth: 5, undoBlockTimeout: 5000, // ms for an undo event cards: [], @@ -1904,6 +2017,8 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', * a custom toolbar. * * {@link Editor#onTextInput} -- Register callbacks when the user enters text * that matches a given string or regex. + * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before + * applying changes from {@link Editor#toggleMarkup} */ var Editor = (function () { @@ -1924,6 +2039,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', * @param {String} [options.placeholder] Default text to show before user starts typing. * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered. + * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links * @param {number} [options.undoDepth=5] How many undo levels will be available. * Set to 0 to disable undo/redo functionality. * @return {Editor} @@ -1939,7 +2055,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType); this._views = []; - this.isEditable = null; + this.isEditable = true; this._parserPlugins = options.parserPlugins || []; // FIXME: This should merge onto this.options @@ -1968,6 +2084,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this); this._editState = new _mobiledocKitEditorEditState['default'](this); this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES)); + this._beforeHooks = { toggleMarkup: [] }; _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) { return _this.onTextInput(handler); @@ -2074,12 +2191,10 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', this.element = element; - if (this.isEditable === null) { - this.enableEditing(); + if (this.showLinkTooltips) { + this._addTooltip(); } - this._addTooltip(); - // A call to `run` will trigger the didUpdatePostCallbacks hooks with a // postEditor. this.run(function () {}); @@ -2093,6 +2208,12 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', this._mutationHandler.init(); this._eventManager.init(); + if (this.isEditable === false) { + this.disableEditing(); + } else { + this.enableEditing(); + } + if (this.autofocus) { this.selectRange(this.post.headPosition()); } @@ -2420,15 +2541,17 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', switch (format) { case 'html': - var result = undefined; - if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) { - rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc); - result = '
    ' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
    '; - } else { - // Fallback to text serialization - result = this.serializePost(post, 'text', options); + { + var result = undefined; + if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) { + rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc); + result = '
    ' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
    '; + } else { + // Fallback to text serialization + result = this.serializePost(post, 'text', options); + } + return result; } - return result; case 'text': rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc); return rendered.result; @@ -2493,12 +2616,9 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }, { key: 'disableEditing', value: function disableEditing() { - if (this.isEditable === false) { - return; - } - this.isEditable = false; if (this.hasRendered) { + this._eventManager.stop(); this.element.setAttribute('contentEditable', false); this.setPlaceholder(''); this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange()); @@ -2516,7 +2636,8 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', key: 'enableEditing', value: function enableEditing() { this.isEditable = true; - if (this.element) { + if (this.hasRendered) { + this._eventManager.start(); this.element.setAttribute('contentEditable', true); this.setPlaceholder(this.placeholder); } @@ -2754,22 +2875,55 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }); } + /** + * @callback editorBeforeCallback + * @param { Object } details + * @param { Markup } details.markup + * @param { Range } details.range + * @param { boolean } details.willAdd Whether the markup will be applied + */ + + /** + * Register a callback that will be run before {@link Editor#toggleMarkup} is applied. + * If any callback returns literal `false`, the toggling of markup will be canceled. + * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and + * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks. + * @param {editorBeforeCallback} + */ + }, { + key: 'beforeToggleMarkup', + value: function beforeToggleMarkup(callback) { + this._beforeHooks.toggleMarkup.push(callback); + } + /** * Toggles the given markup at the editor's current {@link Range}. * If the range is collapsed this changes the editor's state so that the * next characters typed will be affected. If there is text selected * (aka a non-collapsed range), the selections' markup will be toggled. * If the editor is not focused and has no active range, nothing happens. + * Hooks added using #beforeToggleMarkup will be run before toggling, + * and if any of them returns literal false, toggling the markup will be canceled + * and no change will be applied. * @param {String} markup E.g. "b", "em", "a" + * @param {Object} [attributes={}] E.g. {href: "http://bustle.com"} * @public * @see PostEditor#toggleMarkup */ }, { key: 'toggleMarkup', value: function toggleMarkup(markup) { - markup = this.builder.createMarkup(markup); + var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + + markup = this.builder.createMarkup(markup, attributes); var range = this.range; + var willAdd = !this.detectMarkupInRange(range, markup.tagName); + var shouldCancel = this._runBeforeHooks('toggleMarkup', { markup: markup, range: range, willAdd: willAdd }); + if (shouldCancel) { + return; + } + if (range.isCollapsed) { this._editState.toggleMarkupState(markup); this._inputModeDidChange(); @@ -2842,6 +2996,41 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }); } + /** + * Sets an attribute for the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @param {String} value The value of the attribute. + * @public + * @see PostEditor#setAttribute + */ + }, { + key: 'setAttribute', + value: function setAttribute(key, value) { + var _this7 = this; + + this.run(function (postEditor) { + return postEditor.setAttribute(key, value, _this7.range); + }); + } + + /** + * Removes an attribute from the current active section(s). + * + * @param {String} key The attribute. The only valid attribute is 'text-align'. + * @public + * @see PostEditor#removeAttribute + */ + }, { + key: 'removeAttribute', + value: function removeAttribute(key) { + var _this8 = this; + + this.run(function (postEditor) { + return postEditor.removeAttribute(key, _this8.range); + }); + } + /** * Finds and runs the first matching key command for the event * @@ -2953,7 +3142,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', }, { key: 'insertCard', value: function insertCard(cardName) { - var _this7 = this; + var _this9 = this; var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; @@ -2972,7 +3161,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', var position = range.tail; card = postEditor.builder.createCardSection(cardName, cardPayload); if (inEditMode) { - _this7.editCard(card); + _this9.editCard(card); } if (!range.isCollapsed) { @@ -2987,7 +3176,7 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', if (section.isBlank) { postEditor.replaceSection(section, card); } else { - var collection = _this7.post.sections; + var collection = _this9.post.sections; postEditor.insertSectionBefore(collection, card, section.next); } @@ -3059,6 +3248,28 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', } (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments); } + + /** + * Runs each callback for the given hookName. + * Only the hookName 'toggleMarkup' is currently supported + * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled + * @private + */ + }, { + key: '_runBeforeHooks', + value: function _runBeforeHooks(hookName) { + var hooks = this._beforeHooks[hookName] || []; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < hooks.length; i++) { + if (hooks[i].apply(hooks, args) === false) { + return true; + } + } + } }, { key: 'builder', get: function get() { @@ -3113,6 +3324,11 @@ define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', return activeSections[activeSections.length - 1]; } + }, { + key: 'activeSectionAttributes', + get: function get() { + return this._editState.activeSectionAttributes; + } }, { key: 'activeMarkups', get: function get() { @@ -3145,12 +3361,11 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor); this._listeners = []; this.modifierKeys = { - shift: false, - alt: false, - ctrl: false + shift: false }; this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this)); + this.started = true; } _createClass(EventManager, [{ @@ -3168,6 +3383,16 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as this._selectionManager.start(); } + }, { + key: 'start', + value: function start() { + this.started = true; + } + }, { + key: 'stop', + value: function stop() { + this.started = false; + } }, { key: 'registerInputHandler', value: function registerInputHandler(inputHandler) { @@ -3228,7 +3453,6 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as var _ref42 = _slicedToArray(_ref4, 3); var context = _ref42[0]; - var type = _ref42[1]; var listener = _ref42[2]; listener.call(context, event); @@ -3246,6 +3470,11 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as value: function _handleEvent(type, event) { var element = event.target; + if (!this.started) { + // abort handling this event + return true; + } + if (!this.isElementAddressable(element)) { // abort handling this event return true; @@ -3328,29 +3557,34 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as switch (true) { // FIXME This should be restricted to only card/atom boundaries case key.isHorizontalArrowWithoutModifiersOtherThanShift(): - var newRange = undefined; - if (key.isShift()) { - newRange = range.extend(key.direction * 1); - } else { - newRange = range.move(key.direction); - } + { + var newRange = undefined; + if (key.isShift()) { + newRange = range.extend(key.direction * 1); + } else { + newRange = range.move(key.direction); + } - editor.selectRange(newRange); - event.preventDefault(); - break; + editor.selectRange(newRange); + event.preventDefault(); + break; + } case key.isDelete(): - var direction = key.direction; - - var unit = 'char'; - if (this.modifierKeys.alt && _mobiledocKitUtilsBrowser['default'].isMac()) { - unit = 'word'; - } else if (this.modifierKeys.ctrl && _mobiledocKitUtilsBrowser['default'].isWin()) { - unit = 'word'; + { + var direction = key.direction; + + var unit = 'char'; + if (key.altKey && _mobiledocKitUtilsBrowser['default'].isMac()) { + unit = 'word'; + } else if (key.ctrlKey && !_mobiledocKitUtilsBrowser['default'].isMac()) { + unit = 'word'; + } + editor.performDelete({ direction: direction, unit: unit }); + event.preventDefault(); + break; } - editor.performDelete({ direction: direction, unit: unit }); - event.preventDefault(); - break; case key.isEnter(): + this._textInputHandler.handleNewLine(); editor.handleNewline(event); break; case key.isTab(): @@ -3458,10 +3692,6 @@ define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/as if (key.isShiftKey()) { this.modifierKeys.shift = isDown; - } else if (key.isAltKey()) { - this.modifierKeys.alt = isDown; - } else if (key.isCtrlKey()) { - this.modifierKeys.ctrl = isDown; } } }]); @@ -3636,7 +3866,7 @@ define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key function characterToCode(character) { var upperCharacter = character.toUpperCase(); - var special = _mobiledocKitUtilsKey.SPECIAL_KEYS[upperCharacter]; + var special = (0, _mobiledocKitUtilsKey.specialCharacterToCode)(upperCharacter); if (special) { return special; } else { @@ -4791,8 +5021,6 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName); var post = this.editor.post; - var nextRange = range; - var everySectionHasTagName = true; post.walkMarkerableSections(range, function (section) { if (!_this13._isSameSectionType(section, sectionTagName)) { @@ -4801,17 +5029,91 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi }); var tagName = everySectionHasTagName ? 'p' : sectionTagName; - var firstChanged = undefined; + var sectionTransformations = []; post.walkMarkerableSections(range, function (section) { var changedSection = _this13.changeSectionTagName(section, tagName); - firstChanged = firstChanged || changedSection; + sectionTransformations.push({ + from: section, + to: changedSection + }); }); - if (firstChanged) { - nextRange = firstChanged.headPosition().toRange(); - } + var nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations); this.setRange(nextRange); } + }, { + key: '_determineNextRangeAfterToggleSection', + value: function _determineNextRangeAfterToggleSection(range, sectionTransformations) { + if (sectionTransformations.length) { + var changedHeadSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref2) { + var from = _ref2.from; + + return from === range.headSection; + }).to; + var changedTailSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref3) { + var from = _ref3.from; + + return from === range.tailSection; + }).to; + + if (changedHeadSection.isListSection || changedTailSection.isListSection) { + // We don't know to which ListItem's the original sections point at, so + // we don't have enough information to reconstruct the range when + // dealing with lists. + return sectionTransformations[0].to.headPosition().toRange(); + } else { + return _mobiledocKitUtilsCursorRange['default'].create(changedHeadSection, range.headSectionOffset, changedTailSection, range.tailSectionOffset, range.direction); + } + } else { + return range; + } + } + }, { + key: 'setAttribute', + value: function setAttribute(key, value) { + var range = arguments.length <= 2 || arguments[2] === undefined ? this._range : arguments[2]; + + this._mutateAttribute(key, range, function (section, attribute) { + if (section.getAttribute(attribute) !== value) { + section.setAttribute(attribute, value); + return true; + } + }); + } + }, { + key: 'removeAttribute', + value: function removeAttribute(key) { + var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1]; + + this._mutateAttribute(key, range, function (section, attribute) { + if (section.hasAttribute(attribute)) { + section.removeAttribute(attribute); + return true; + } + }); + } + }, { + key: '_mutateAttribute', + value: function _mutateAttribute(key, range, cb) { + var _this14 = this; + + range = (0, _mobiledocKitUtilsToRange['default'])(range); + var post = this.editor.post; + + var attribute = 'data-md-' + key; + + post.walkMarkerableSections(range, function (section) { + if (section.isListItem) { + section = section.parent; + } + + if (cb(section, attribute) === true) { + _this14._markDirty(section); + } + }); + + this.setRange(range); + } }, { key: '_isSameSectionType', value: function _isSameSectionType(section, sectionTagName) { @@ -4890,13 +5192,11 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi if (positionIsMiddle) { var item = position.section; - var _splitListItem3 = // jshint ignore:line - this._splitListItem(item, position); + var _splitListItem3 = this._splitListItem(item, position); - var _splitListItem32 = _slicedToArray(_splitListItem3, 2); + var _splitListItem32 = _slicedToArray(_splitListItem3, 1); var pre = _splitListItem32[0]; - var post = _splitListItem32[1]; position = pre.tailPosition(); } @@ -4935,10 +5235,10 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi }, { key: '_splitListAtItem', value: function _splitListAtItem(list, item) { - var _this14 = this; + var _this15 = this; var next = list; - var prev = this.builder.createListSection(next.tagName); + var prev = this.builder.createListSection(next.tagName, [], next.attributes); var mid = this.builder.createListSection(next.tagName); var addToPrev = true; @@ -4956,7 +5256,7 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi return; // break after iterating prev and mid parts of the list } listToAppend.join(i); - _this14.removeSection(i); + _this15.removeSection(i); }); var found = !addToPrev; (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found); @@ -4970,7 +5270,7 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi [prev, next].forEach(function (_list) { var isAttached = !!_list.parent; if (_list.isBlank && isAttached) { - _this14.removeSection(_list); + _this15.removeSection(_list); } }); }); @@ -4988,12 +5288,10 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi var _splitListAtItem2 = this._splitListAtItem(listSection, section); - var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 3); + var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 2); - var prev = _splitListAtItem22[0]; var mid = _splitListAtItem22[1]; - var next = _splitListAtItem22[2]; - // jshint ignore:line + this.replaceSection(mid, markupSection); return markupSection; } @@ -5013,12 +5311,10 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi if (section.isListItem) { var _splitListAtItem3 = this._splitListAtItem(section.parent, section); - var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 3); + var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 2); - var prev = _splitListAtItem32[0]; var mid = _splitListAtItem32[1]; - var next = _splitListAtItem32[2]; - // jshint ignore:line + sectionToReplace = mid; } else { sectionToReplace = section; @@ -5124,33 +5420,33 @@ define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/posi }, { key: 'removeAllSections', value: function removeAllSections() { - var _this15 = this; + var _this16 = this; this.editor.post.sections.toArray().forEach(function (section) { - _this15.removeSection(section); + _this16.removeSection(section); }); } }, { key: 'migrateSectionsFromPost', value: function migrateSectionsFromPost(post) { - var _this16 = this; + var _this17 = this; post.sections.toArray().forEach(function (section) { post.sections.remove(section); - _this16.insertSectionBefore(_this16.editor.post.sections, section, null); + _this17.insertSectionBefore(_this17.editor.post.sections, section, null); }); } }, { key: '_scheduleListRemovalIfEmpty', value: function _scheduleListRemovalIfEmpty(listSection) { - var _this17 = this; + var _this18 = this; this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () { // if the list is attached and blank after we do other rendering stuff, // remove it var isAttached = !!listSection.parent; if (isAttached && listSection.isBlank) { - _this17.removeSection(listSection); + _this18.removeSection(listSection); } }); } @@ -5417,12 +5713,10 @@ define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/uti } else { var _breakListAtCursor2 = this._breakListAtCursor(); - var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 3); + var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 2); - var pre = _breakListAtCursor22[0]; var blank = _breakListAtCursor22[1]; - var post = _breakListAtCursor22[2]; - // jshint ignore:line + this.cursorPosition = blank.tailPosition(); } } @@ -5497,13 +5791,11 @@ define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/uti }, { key: '_breakMarkerableAtCursor', value: function _breakMarkerableAtCursor() { - var _postEditor$splitSection = // jshint ignore:line - this.postEditor.splitSection(this.cursorPosition); + var _postEditor$splitSection = this.postEditor.splitSection(this.cursorPosition); - var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 2); + var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 1); var pre = _postEditor$splitSection2[0]; - var post = _postEditor$splitSection2[1]; this.cursorPosition = pre.tailPosition(); } @@ -5609,7 +5901,9 @@ define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/uti key: 'insert', value: function insert(cursorPosition, newPost) { var visitor = new Visitor(this, cursorPosition); - visitor.visit(newPost); + if (!newPost.isBlank) { + visitor.visit(newPost); + } return visitor.cursorPosition; } }]); @@ -5806,7 +6100,7 @@ define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/edit exports['default'] = SelectionManager; }); -define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate) { +define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsCharacters) { 'use strict'; var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); @@ -5857,13 +6151,29 @@ define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/uti } } }, { + key: 'handleNewLine', + value: function handleNewLine() { + var editor = this.editor; + + var matchedHandler = this._findHandler(_mobiledocKitUtilsCharacters.ENTER); + if (matchedHandler) { + var _matchedHandler2 = _slicedToArray(matchedHandler, 2); + + var handler = _matchedHandler2[0]; + var matches = _matchedHandler2[1]; + + handler.run(editor, matches); + } + } + }, { key: '_findHandler', value: function _findHandler() { + var string = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0]; var _editor$range = this.editor.range; var head = _editor$range.head; var section = _editor$range.head.section; - var preText = section.textUntil(head); + var preText = section.textUntil(head) + string; for (var i = 0; i < this._handlers.length; i++) { var handler = this._handlers[i]; @@ -6066,24 +6376,19 @@ define('mobiledoc-kit/editor/ui', ['exports'], function (exports) { var hasLink = editor.detectMarkupInRange(range, 'a'); if (hasLink) { - editor.run(function (postEditor) { - return postEditor.toggleMarkup('a'); - }); + editor.toggleMarkup('a'); } else { showPrompt('Enter a URL', defaultUrl, function (url) { if (!url) { return; } - editor.run(function (postEditor) { - var markup = postEditor.builder.createMarkup('a', { href: url }); - postEditor.toggleMarkup(markup); - }); + editor.toggleMarkup('a', { href: url }); }); } } }); -define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion) { +define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version', 'mobiledoc-kit/renderers/mobiledoc'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion, _mobiledocKitRenderersMobiledoc) { 'use strict'; exports.registerGlobal = registerGlobal; @@ -6095,7 +6400,8 @@ define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-ki Range: _mobiledocKitUtilsCursorRange['default'], Position: _mobiledocKitUtilsCursorPosition['default'], Error: _mobiledocKitUtilsMobiledocError['default'], - VERSION: _mobiledocKitVersion['default'] + VERSION: _mobiledocKitVersion['default'], + MOBILEDOC_VERSION: _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION }; function registerGlobal(global) { @@ -6106,22 +6412,67 @@ define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-ki exports.UI = _mobiledocKitEditorUi; exports.Range = _mobiledocKitUtilsCursorRange['default']; exports.Position = _mobiledocKitUtilsCursorPosition['default']; + exports.MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION; exports['default'] = Mobiledoc; }); -define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/models/_attributable', ['exports', 'mobiledoc-kit/utils/object-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsObjectUtils, _mobiledocKitUtilsArrayUtils) { 'use strict'; - var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - - var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); - function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } + exports.attributable = attributable; + var VALID_ATTRIBUTES = ['data-md-text-align']; - function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + /* + * A "mixin" to add section attribute support + * to markup and list sections. + */ - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + function attributable(ctx) { + ctx.attributes = {}; - function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + ctx.hasAttribute = function (key) { + return key in ctx.attributes; + }; + + ctx.setAttribute = function (key, value) { + if (!(0, _mobiledocKitUtilsArrayUtils.contains)(VALID_ATTRIBUTES, key)) { + throw new Error('Invalid attribute "' + key + '" was passed. Constrain attributes to the spec-compliant whitelist.'); + } + ctx.attributes[key] = value; + }; + ctx.removeAttribute = function (key) { + delete ctx.attributes[key]; + }; + ctx.getAttribute = function (key) { + return ctx.attributes[key]; + }; + ctx.eachAttribute = function (cb) { + (0, _mobiledocKitUtilsObjectUtils.entries)(ctx.attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return cb(k, v); + }); + }; + } +}); +define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) { + 'use strict'; + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } + + function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Markerable = (function (_Section) { _inherits(Markerable, _Section); @@ -6582,7 +6933,7 @@ define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-uti value: function nextLeafSection() { var next = this.next; if (next) { - if (!!next.items) { + if (next.items) { return next.items.head; } else { return next; @@ -6608,7 +6959,7 @@ define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-uti var prev = this.prev; if (prev) { - if (!!prev.items) { + if (prev.items) { return prev.items.tail; } else { return prev; @@ -7263,12 +7614,14 @@ define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_mark exports['default'] = ListItem; }); -define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitModels_attributable, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) { 'use strict'; + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -7285,10 +7638,12 @@ define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/lin _inherits(ListSection, _Section); function ListSection() { + var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; + var _this = this; - var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, ListSection); @@ -7297,6 +7652,15 @@ define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/lin this.isListSection = true; this.isLeafSection = false; + (0, _mobiledocKitModels_attributable.attributable)(this); + (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return _this.setAttribute(k, v); + }); + this.items = new _mobiledocKitUtilsLinkedList['default']({ adoptItem: function adoptItem(i) { (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem); @@ -7536,12 +7900,14 @@ define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', exports['default'] = Marker; }); -define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { +define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModels_attributable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsObjectUtils) { 'use strict'; + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -7564,11 +7930,25 @@ define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/ function MarkupSection() { var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0]; + + var _this = this; + var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; _classCallCheck(this, MarkupSection); _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers); + + (0, _mobiledocKitModels_attributable.attributable)(this); + (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var k = _ref2[0]; + var v = _ref2[1]; + return _this.setAttribute(k, v); + }); + this.isMarkupSection = true; } @@ -7581,7 +7961,7 @@ define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/ key: 'splitAtMarker', value: function splitAtMarker(marker) { var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; - var beforeSection = this.builder.createMarkupSection(this.tagName, []); + var beforeSection = this.builder.createMarkupSection(this.tagName, [], false, this.attributes); var afterSection = this.builder.createMarkupSection(); return this._redistributeMarkers(beforeSection, afterSection, marker, offset); @@ -7609,6 +7989,12 @@ define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils var VALID_ATTRIBUTES = ['href', 'rel']; exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + /** + * A Markup is similar with an inline HTML tag that might be added to + * text to modify its meaning and/or display. Examples of types of markup + * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links). + * @property {String} tagName + */ var Markup = (function () { /* @@ -7630,6 +8016,12 @@ define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1); } + /** + * Whether text in the forward direction of the cursor (i.e. to the right in ltr text) + * should be considered to have this markup applied to it. + * @private + */ + _createClass(Markup, [{ key: 'isForwardInclusive', value: function isForwardInclusive() { @@ -7645,6 +8037,11 @@ define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils value: function hasTag(tagName) { return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName); } + + /** + * Returns the attribute value + * @param {String} name, e.g. "href" + */ }, { key: 'getAttribute', value: function getAttribute(name) { @@ -7747,9 +8144,10 @@ define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/mode var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0]; var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; + var attributes = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName); - var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers); + var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers, attributes); if (isGenerated) { section.isGenerated = true; } @@ -7761,9 +8159,10 @@ define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/mode value: function createListSection() { var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0]; var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; + var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName); - var section = new _mobiledocKitModelsListSection['default'](tagName, items); + var section = new _mobiledocKitModelsListSection['default'](tagName, items, attributes); section.builder = this; return section; } @@ -8054,7 +8453,7 @@ define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'm if (next) { if (next.isLeafSection) { return next; - } else if (!!next.items) { + } else if (next.items) { return next.items.head; } else { (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false); @@ -8104,6 +8503,7 @@ define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'm }); } else { newSection = section.clone(); + sectionParent = post; } if (sectionParent) { sectionParent.sections.append(newSection); @@ -8413,6 +8813,7 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); exports.transformHTMLText = transformHTMLText; + exports.trimSectionText = trimSectionText; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -8428,6 +8829,17 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- return text; } + function trimSectionText(section) { + if (section.isMarkerable && section.markers.length) { + var _section$markers = section.markers; + var head = _section$markers.head; + var tail = _section$markers.tail; + + head.value = head.value.replace(/^\s+/, ''); + tail.value = tail.value.replace(/\s+$/, ''); + } + } + function isGoogleDocsContainer(element) { return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id); } @@ -8500,6 +8912,12 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- _this.appendSections(post, sections); }); + // trim leading/trailing whitespace of markerable sections to avoid + // unnessary whitespace from indented HTML input + (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) { + return trimSectionText(section); + }); + return post; } }, { @@ -8514,7 +8932,9 @@ define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor- }, { key: 'appendSection', value: function appendSection(post, section) { - if (section.isBlank || section.isMarkerable && trim(section.text) === '') { + if (section.isBlank || section.isMarkerable && trim(section.text) === "" && !(0, _mobiledocKitUtilsArrayUtils.any)(section.markers, function (marker) { + return marker.isAtom; + })) { return; } @@ -8788,7 +9208,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sectionData = _ref.sections; try { @@ -8864,7 +9283,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseCardSection(_ref3, post) { var _ref32 = _slicedToArray(_ref3, 3); - var type = _ref32[0]; var name = _ref32[1]; var payload = _ref32[2]; @@ -8876,7 +9294,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseImageSection(_ref4, post) { var _ref42 = _slicedToArray(_ref4, 2); - var type = _ref42[0]; var src = _ref42[1]; var section = this.builder.createImageSection(src); @@ -8887,7 +9304,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseMarkupSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 3); - var type = _ref52[0]; var tagName = _ref52[1]; var markers = _ref52[2]; @@ -8907,7 +9323,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/rendere value: function parseListSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 3); - var type = _ref62[0]; var tagName = _ref62[1]; var items = _ref62[2]; @@ -8993,7 +9408,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sections = _ref.sections; var markerTypes = _ref.markups; var cardTypes = _ref.cards; @@ -9124,7 +9538,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseCardSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 2); - var type = _ref52[0]; var cardIndex = _ref52[1]; var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); @@ -9142,7 +9555,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseImageSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 2); - var type = _ref62[0]; var src = _ref62[1]; var section = this.builder.createImageSection(src); @@ -9153,7 +9565,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseMarkupSection(_ref7, post) { var _ref72 = _slicedToArray(_ref7, 3); - var type = _ref72[0]; var tagName = _ref72[1]; var markers = _ref72[2]; @@ -9173,7 +9584,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende value: function parseListSection(_ref8, post) { var _ref82 = _slicedToArray(_ref8, 3); - var type = _ref82[0]; var tagName = _ref82[1]; var items = _ref82[2]; @@ -9234,13 +9644,325 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/rende case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE: - var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value), - _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3), - atomName = _getAtomTypeFromIndex2[0], - atomValue = _getAtomTypeFromIndex2[1], - atomPayload = _getAtomTypeFromIndex2[2]; + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; + + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } + default: + (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false); + } + } + }]); + + return MobiledocParser; + })(); + + exports['default'] = MobiledocParser; +}); +define('mobiledoc-kit/parsers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) { + 'use strict'; + + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + /* + * Parses from mobiledoc -> post + */ + + var MobiledocParser = (function () { + function MobiledocParser(builder) { + _classCallCheck(this, MobiledocParser); + + this.builder = builder; + } + + /** + * @param {Mobiledoc} + * @return {Post} + */ + + _createClass(MobiledocParser, [{ + key: 'parse', + value: function parse(_ref) { + var sections = _ref.sections; + var markerTypes = _ref.markups; + var cardTypes = _ref.cards; + var atomTypes = _ref.atoms; + + try { + var post = this.builder.createPost(); + + this.markups = []; + this.markerTypes = this.parseMarkerTypes(markerTypes); + this.cardTypes = this.parseCardTypes(cardTypes); + this.atomTypes = this.parseAtomTypes(atomTypes); + this.parseSections(sections, post); + + return post; + } catch (e) { + (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false); + } + } + }, { + key: 'parseMarkerTypes', + value: function parseMarkerTypes(markerTypes) { + var _this = this; + + return markerTypes.map(function (markerType) { + return _this.parseMarkerType(markerType); + }); + } + }, { + key: 'parseMarkerType', + value: function parseMarkerType(_ref2) { + var _ref22 = _slicedToArray(_ref2, 2); + + var tagName = _ref22[0]; + var attributesArray = _ref22[1]; + + var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []); + return this.builder.createMarkup(tagName, attributesObject); + } + }, { + key: 'parseCardTypes', + value: function parseCardTypes(cardTypes) { + var _this2 = this; + + return cardTypes.map(function (cardType) { + return _this2.parseCardType(cardType); + }); + } + }, { + key: 'parseCardType', + value: function parseCardType(_ref3) { + var _ref32 = _slicedToArray(_ref3, 2); + + var cardName = _ref32[0]; + var cardPayload = _ref32[1]; + + return [cardName, cardPayload]; + } + }, { + key: 'parseAtomTypes', + value: function parseAtomTypes(atomTypes) { + var _this3 = this; + + return atomTypes.map(function (atomType) { + return _this3.parseAtomType(atomType); + }); + } + }, { + key: 'parseAtomType', + value: function parseAtomType(_ref4) { + var _ref42 = _slicedToArray(_ref4, 3); + + var atomName = _ref42[0]; + var atomValue = _ref42[1]; + var atomPayload = _ref42[2]; + + return [atomName, atomValue, atomPayload]; + } + }, { + key: 'parseSections', + value: function parseSections(sections, post) { + var _this4 = this; + + sections.forEach(function (section) { + return _this4.parseSection(section, post); + }); + } + }, { + key: 'parseSection', + value: function parseSection(section, post) { + var _section = _slicedToArray(section, 1); - return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + var type = _section[0]; + + switch (type) { + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_SECTION_TYPE: + this.parseMarkupSection(section, post); + break; + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_IMAGE_SECTION_TYPE: + this.parseImageSection(section, post); + break; + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_CARD_SECTION_TYPE: + this.parseCardSection(section, post); + break; + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_LIST_SECTION_TYPE: + this.parseListSection(section, post); + break; + default: + (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false); + } + } + }, { + key: 'getAtomTypeFromIndex', + value: function getAtomTypeFromIndex(index) { + var atomType = this.atomTypes[index]; + (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType); + return atomType; + } + }, { + key: 'getCardTypeFromIndex', + value: function getCardTypeFromIndex(index) { + var cardType = this.cardTypes[index]; + (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType); + return cardType; + } + }, { + key: 'parseCardSection', + value: function parseCardSection(_ref5, post) { + var _ref52 = _slicedToArray(_ref5, 2); + + var cardIndex = _ref52[1]; + + var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); + + var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2); + + var name = _getCardTypeFromIndex2[0]; + var payload = _getCardTypeFromIndex2[1]; + + var section = this.builder.createCardSection(name, payload); + post.sections.append(section); + } + }, { + key: 'parseImageSection', + value: function parseImageSection(_ref6, post) { + var _ref62 = _slicedToArray(_ref6, 2); + + var src = _ref62[1]; + + var section = this.builder.createImageSection(src); + post.sections.append(section); + } + }, { + key: 'parseMarkupSection', + value: function parseMarkupSection(_ref7, post) { + var _ref72 = _slicedToArray(_ref7, 4); + + var tagName = _ref72[1]; + var markers = _ref72[2]; + var attributesArray = _ref72[3]; + + var section = this.builder.createMarkupSection(tagName); + post.sections.append(section); + if (attributesArray) { + (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref8) { + var _ref82 = _slicedToArray(_ref8, 2); + + var key = _ref82[0]; + var value = _ref82[1]; + + section.setAttribute(key, value); + }); + } + this.parseMarkers(markers, section); + // Strip blank markers after they have been created. This ensures any + // markup they include has been correctly populated. + (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) { + return m.isBlank; + }).forEach(function (m) { + section.markers.remove(m); + }); + } + }, { + key: 'parseListSection', + value: function parseListSection(_ref9, post) { + var _ref92 = _slicedToArray(_ref9, 4); + + var tagName = _ref92[1]; + var items = _ref92[2]; + var attributesArray = _ref92[3]; + + var section = this.builder.createListSection(tagName); + post.sections.append(section); + if (attributesArray) { + (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref10) { + var _ref102 = _slicedToArray(_ref10, 2); + + var key = _ref102[0]; + var value = _ref102[1]; + + section.setAttribute(key, value); + }); + } + this.parseListItems(items, section); + } + }, { + key: 'parseListItems', + value: function parseListItems(items, section) { + var _this5 = this; + + items.forEach(function (i) { + return _this5.parseListItem(i, section); + }); + } + }, { + key: 'parseListItem', + value: function parseListItem(markers, section) { + var item = this.builder.createListItem(); + this.parseMarkers(markers, item); + section.items.append(item); + } + }, { + key: 'parseMarkers', + value: function parseMarkers(markers, parent) { + var _this6 = this; + + markers.forEach(function (m) { + return _this6.parseMarker(m, parent); + }); + } + }, { + key: 'parseMarker', + value: function parseMarker(_ref11, parent) { + var _this7 = this; + + var _ref112 = _slicedToArray(_ref11, 4); + + var type = _ref112[0]; + var markerTypeIndexes = _ref112[1]; + var closeCount = _ref112[2]; + var value = _ref112[3]; + + markerTypeIndexes.forEach(function (index) { + _this7.markups.push(_this7.markerTypes[index]); + }); + + var marker = this.buildMarkerType(type, value); + parent.markers.append(marker); + + this.markups = this.markups.slice(0, this.markups.length - closeCount); + } + }, { + key: 'buildMarkerType', + value: function buildMarkerType(type, value) { + switch (type) { + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_MARKER_TYPE: + return this.builder.createMarker(value, this.markups.slice()); + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_ATOM_MARKER_TYPE: + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; + + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false); } @@ -9280,7 +10002,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere _createClass(MobiledocParser, [{ key: 'parse', value: function parse(_ref) { - var version = _ref.version; var sections = _ref.sections; var markerTypes = _ref.markups; var cardTypes = _ref.cards; @@ -9411,7 +10132,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseCardSection(_ref5, post) { var _ref52 = _slicedToArray(_ref5, 2); - var type = _ref52[0]; var cardIndex = _ref52[1]; var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex); @@ -9429,7 +10149,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseImageSection(_ref6, post) { var _ref62 = _slicedToArray(_ref6, 2); - var type = _ref62[0]; var src = _ref62[1]; var section = this.builder.createImageSection(src); @@ -9440,7 +10159,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseMarkupSection(_ref7, post) { var _ref72 = _slicedToArray(_ref7, 3); - var type = _ref72[0]; var tagName = _ref72[1]; var markers = _ref72[2]; @@ -9460,7 +10178,6 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere value: function parseListSection(_ref8, post) { var _ref82 = _slicedToArray(_ref8, 3); - var type = _ref82[0]; var tagName = _ref82[1]; var items = _ref82[2]; @@ -9521,13 +10238,17 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE: return this.builder.createMarker(value, this.markups.slice()); case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE: - var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value), - _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3), - atomName = _getAtomTypeFromIndex2[0], - atomValue = _getAtomTypeFromIndex2[1], - atomPayload = _getAtomTypeFromIndex2[2]; + { + var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value); + + var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3); + + var atomName = _getAtomTypeFromIndex2[0]; + var atomValue = _getAtomTypeFromIndex2[1]; + var atomPayload = _getAtomTypeFromIndex2[2]; - return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice()); + } default: (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false); } @@ -9539,7 +10260,7 @@ define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/rendere exports['default'] = MobiledocParser; }); -define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/parsers/mobiledoc/0-3-2', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitParsersMobiledoc032, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) { 'use strict'; function parseVersion(mobiledoc) { @@ -9556,6 +10277,8 @@ define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mob return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc); case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION: return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc); + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION: + return new _mobiledocKitParsersMobiledoc032['default'](builder).parse(mobiledoc); default: (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false); } @@ -9575,8 +10298,7 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup var NEWLINES = /\n/g; function sanitize(text) { - text = text.replace(NEWLINES, ''); - return text; + return text.replace(NEWLINES, ' '); } /** @@ -9608,11 +10330,17 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup this._updateStateFromElement(element); - var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes; + var finished = false; + + // top-level text nodes will be run through parseNode later so avoid running + // the node through parserPlugins twice + if (!(0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) { + finished = this.runPlugins(element); + } + + if (!finished) { + var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes; - if (this.state.section.isListSection) { - this.parseListItems(childNodes); - } else { (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) { _this.parseNode(el); }); @@ -9622,39 +10350,30 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup return this.sections; } - }, { - key: 'parseListItems', - value: function parseListItems(childNodes) { - var _this2 = this; - - var state = this.state; - - (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) { - var parsed = new _this2.constructor(_this2.builder).parse(el); - var li = parsed[0]; - if (li && li.isListItem) { - state.section.items.append(li); - } - }); - } }, { key: 'runPlugins', value: function runPlugins(node) { - var _this3 = this; + var _this2 = this; var isNodeFinished = false; var env = { addSection: function addSection(section) { - _this3._closeCurrentSection(); - _this3.sections.push(section); + // avoid creating empty paragraphs due to wrapper elements around + // parser-plugin-handled elements + if (_this2.state.section.isMarkerable && !_this2.state.text && !_this2.state.section.text) { + _this2.state.section = null; + } else { + _this2._closeCurrentSection(); + } + _this2.sections.push(section); }, addMarkerable: function addMarkerable(marker) { - var state = _this3.state; + var state = _this2.state; var section = state.section; (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable); if (state.text) { - _this3._createMarker(); + _this2._createMarker(); } section.markers.append(marker); }, @@ -9671,9 +10390,13 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup } return false; } + + /* eslint-disable complexity */ }, { key: 'parseNode', value: function parseNode(node) { + var _this3 = this; + if (!this.state.section) { this._updateStateFromElement(node); } @@ -9683,6 +10406,72 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup return; } + // handle closing the current section and starting a new one if we hit a + // new-section-creating element. + if (this.state.section && !(0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.tagName) { + var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.tagName); + var isListSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName); + var isListItem = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName); + var isMarkupSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName); + var isNestedListSection = isListSection && this.state.section.isListItem; + var lastSection = this.sections[this.sections.length - 1]; + + // we can hit a list item after parsing a nested list, when that happens + // and the lists are of different types we need to make sure we switch + // the list type back + if (isListItem && lastSection && lastSection.isListSection) { + var parentElement = node.parentElement; + var parentElementTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(parentElement.tagName); + if (parentElementTagName !== lastSection.tagName) { + this._closeCurrentSection(); + this._updateStateFromElement(parentElement); + } + } + + // if we've broken out of a list due to nested section-level elements we + // can hit the next list item without having a list section in the current + // state. In this instance we find the parent list node and use it to + // re-initialize the state with a new list section + if (isListItem && !(this.state.section.isListItem || this.state.section.isListSection) && !lastSection.isListSection) { + this._closeCurrentSection(); + this._updateStateFromElement(node.parentElement); + } + + // if we have consecutive list sections of different types (ul, ol) then + // ensure we close the current section and start a new one + var isNewListSection = lastSection && lastSection.isListSection && this.state.section.isListItem && isListSection && tagName !== lastSection.tagName; + + if (isNewListSection || isListSection && !isNestedListSection || isMarkupSection || isListItem) { + // don't break out of the list for list items that contain a single

    . + // deals with typical case of

  • Text

  • Text

  • + if (this.state.section.isListItem && tagName === 'p' && !node.nextSibling && (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.parentElement.tagName))) { + this.parseElementNode(node); + return; + } + + // avoid creating empty paragraphs due to wrapper elements around + // section-creating elements + if (this.state.section.isMarkerable && !this.state.text && this.state.section.markers.length === 0) { + this.state.section = null; + } else { + this._closeCurrentSection(); + } + + this._updateStateFromElement(node); + } + + if (this.state.section.isListSection) { + // ensure the list section is closed and added to the sections list. + // _closeCurrentSection handles pushing list items onto the list section + this._closeCurrentSection(); + + (0, _mobiledocKitUtilsArrayUtils.forEach)(node.childNodes, function (node) { + _this3.parseNode(node); + }); + return; + } + } + switch (node.nodeType) { case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT: this.parseTextNode(node); @@ -9701,7 +10490,7 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup var state = this.state; var markups = this._markupsFromElement(element); - if (markups.length && state.text.length) { + if (markups.length && state.text.length && state.section.isMarkerable) { this._createMarker(); } (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups)); @@ -9710,7 +10499,7 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup _this4.parseNode(node); }); - if (markups.length && state.text.length) { + if (markups.length && state.text.length && state.section.isMarkerable) { // create the marker started for this node this._createMarker(); } @@ -9740,17 +10529,41 @@ define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup var sections = this.sections; var state = this.state; + var lastSection = sections[sections.length - 1]; + if (!state.section) { return; } // close a trailing text node if it exists - if (state.text.length) { + if (state.text.length && state.section.isMarkerable) { this._createMarker(); } - sections.push(state.section); + // push listItems onto the listSection or add a new section + if (state.section.isListItem && lastSection && lastSection.isListSection) { + (0, _mobiledocKitParsersDom.trimSectionText)(state.section); + lastSection.items.append(state.section); + } else { + // avoid creating empty markup sections, especially useful for indented source + if (state.section.isMarkerable && !state.section.text.trim() && !(0, _mobiledocKitUtilsArrayUtils.any)(state.section.markers, function (marker) { + return marker.isAtom; + })) { + state.section = null; + state.text = ''; + return; + } + + // remove empty list sections before creating a new section + if (lastSection && lastSection.isListSection && lastSection.items.length === 0) { + sections.pop(); + } + + sections.push(state.section); + } + state.section = null; + state.text = ''; } }, { key: '_markupsFromElement', @@ -9954,10 +10767,12 @@ define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', ' switch (type) { case _mobiledocKitModelsTypes.LIST_SECTION_TYPE: - var item = this.builder.createListItem(markers); - var list = this.builder.createListSection(tagName, [item]); - section = list; - break; + { + var item = this.builder.createListItem(markers); + var list = this.builder.createListSection(tagName, [item]); + section = list; + break; + } case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE: section = this.builder.createMarkupSection(tagName, markers); break; @@ -10067,6 +10882,12 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c return element; } + function setSectionAttributesOnElement(section, element) { + section.eachAttribute(function (key, value) { + element.setAttribute(key, value); + }); + } + function renderMarkupSection(section) { var element = undefined; if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) { @@ -10076,11 +10897,17 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName); } + setSectionAttributesOnElement(section, element); + return element; } function renderListSection(section) { - return document.createElement(section.tagName); + var element = document.createElement(section.tagName); + + setSectionAttributesOnElement(section, element); + + return element; } function renderListItem() { @@ -10610,7 +11437,6 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c method = postNode.type; (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]); - // jshint -W083 this.visitor[method](renderNode, postNode, function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; @@ -10618,7 +11444,6 @@ define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/c return _this2.visit.apply(_this2, [renderTree].concat(args)); }); - // jshint +W083 renderNode.markClean(); renderNode = this.nodes.shift(); } @@ -10889,6 +11714,150 @@ define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/uti } }; }); +define('mobiledoc-kit/renderers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { + 'use strict'; + + var _visitor; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + var MOBILEDOC_VERSION = '0.3.2'; + exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; + var MOBILEDOC_MARKUP_SECTION_TYPE = 1; + exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE; + var MOBILEDOC_IMAGE_SECTION_TYPE = 2; + exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE; + var MOBILEDOC_LIST_SECTION_TYPE = 3; + exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE; + var MOBILEDOC_CARD_SECTION_TYPE = 10; + + exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE; + var MOBILEDOC_MARKUP_MARKER_TYPE = 0; + exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE; + var MOBILEDOC_ATOM_MARKER_TYPE = 1; + + exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE; + var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) { + opcodes.push(['openPost']); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openMarkupSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openListSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) { + opcodes.push(['openListItem']); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) { + opcodes.push(['openImageSection', node.src]); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) { + opcodes.push(['openCardSection', node.name, node.payload]); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) { + opcodes.push(['openMarker', node.closedMarkups.length, node.value]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) { + opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]); + }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) { + opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]); + (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes); + }), _visitor); + + var postOpcodeCompiler = { + openMarker: function openMarker(closeCount, value) { + this.markupMarkerIds = []; + this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']); + }, + openMarkupSection: function openMarkupSection(tagName, attributes) { + this.markers = []; + this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]); + }, + openListSection: function openListSection(tagName, attributes) { + this.items = []; + this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]); + }, + openListItem: function openListItem() { + this.markers = []; + this.items.push(this.markers); + }, + openImageSection: function openImageSection(url) { + this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]); + }, + openCardSection: function openCardSection(name, payload) { + var index = this._addCardTypeIndex(name, payload); + this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]); + }, + openAtom: function openAtom(closeCount, name, value, payload) { + var index = this._addAtomTypeIndex(name, value, payload); + this.markupMarkerIds = []; + this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]); + }, + openPost: function openPost() { + this.atomTypes = []; + this.cardTypes = []; + this.markerTypes = []; + this.sections = []; + this.result = { + version: MOBILEDOC_VERSION, + atoms: this.atomTypes, + cards: this.cardTypes, + markups: this.markerTypes, + sections: this.sections + }; + }, + openMarkup: function openMarkup(tagName, attributes) { + var index = this._findOrAddMarkerTypeIndex(tagName, attributes); + this.markupMarkerIds.push(index); + }, + _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) { + var cardType = [cardName, payload]; + this.cardTypes.push(cardType); + return this.cardTypes.length - 1; + }, + _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) { + var atomType = [atomName, atomValue, payload]; + this.atomTypes.push(atomType); + return this.atomTypes.length - 1; + }, + _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) { + if (!this._markerTypeCache) { + this._markerTypeCache = {}; + } + var key = tagName + '-' + attributesArray.join('-'); + + var index = this._markerTypeCache[key]; + if (index === undefined) { + var markerType = [tagName]; + if (attributesArray.length) { + markerType.push(attributesArray); + } + this.markerTypes.push(markerType); + + index = this.markerTypes.length - 1; + this._markerTypeCache[key] = index; + } + + return index; + } + }; + + /** + * Render from post -> mobiledoc + */ + exports['default'] = { + /** + * @param {Post} + * @return {Mobiledoc} + */ + render: function render(post) { + var opcodes = []; + (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes); + var compiler = Object.create(postOpcodeCompiler); + (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes); + return compiler.result; + } + }; +}); define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { 'use strict'; @@ -11033,10 +12002,10 @@ define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils } }; }); -define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) { 'use strict'; - var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION; + var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION; exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; exports['default'] = { @@ -11046,10 +12015,12 @@ define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers return _mobiledocKitRenderersMobiledoc02['default'].render(post); case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION: return _mobiledocKitRenderersMobiledoc03['default'].render(post); - case undefined: - case null: case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION: return _mobiledocKitRenderersMobiledoc031['default'].render(post); + case undefined: + case null: + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION: + return _mobiledocKitRenderersMobiledoc032['default'].render(post); default: (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false); } @@ -11599,7 +12570,9 @@ define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/d var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD; var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD; - var WORD_CHAR_REGEX = /\w|_|:/; + // generated via http://xregexp.com/ to cover chars that \w misses + // (new XRegExp('\\p{Alphabetic}|[0-9]|_|:')).toString() + var WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]|[0-9]|_|:/; function findParentSectionFromNode(renderTree, node) { var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) { @@ -12057,6 +13030,12 @@ define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/d sectionOffset += postNode.length; } position = new Position(section, sectionOffset); + } else if (offset >= elementNode.childNodes.length) { + + // This is to deal with how Firefox handles triple-click selections. + // See https://stackoverflow.com/a/21234837/1269194 for an + // explanation. + position = section.tailPosition(); } else { // The offset is 0 if the cursor is on a non-atom-wrapper element node // (e.g., a
    tag in a blank markup section) @@ -12248,8 +13227,10 @@ define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/curs case _mobiledocKitUtilsKey.DIRECTION.BACKWARD: return new Range(head.move(units), tail, currentDirection); default: - var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD; - return new Range(head, tail, newDirection).extend(units); + { + var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD; + return new Range(head, tail, newDirection).extend(units); + } } } @@ -12301,12 +13282,20 @@ define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/curs return !detectMarker(i); }; - var headMarker = head.section.markers.detect(firstNotMatchingDetect, head.marker, true); - headMarker = headMarker && headMarker.next || head.marker; + var headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true); + if (!headMarker && detectMarker(headSection.markers.head)) { + headMarker = headSection.markers.head; + } else { + headMarker = headMarker.next || head.marker; + } var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker)); var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker); - tailMarker = tailMarker && tailMarker.prev || tail.marker; + if (!tailMarker && detectMarker(headSection.markers.tail)) { + tailMarker = headSection.markers.tail; + } else { + tailMarker = tailMarker.prev || tail.marker; + } var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length); return headPosition.toRange(tailPosition, direction); @@ -12418,7 +13407,8 @@ define("mobiledoc-kit/utils/deprecate", ["exports"], function (exports) { var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; if (!conditional) { - console.log("[mobiledoc-kit] [DEPRECATED]: " + message); // jshint ignore:line + // eslint-disable-next-line no-console + console.log("[mobiledoc-kit] [DEPRECATED]: " + message); } } }); @@ -12667,6 +13657,24 @@ define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/str } } + function whenElementIsNotInDOM(element, callback) { + var isCanceled = false; + var observerFn = function observerFn() { + if (isCanceled) { + return; + } + if (!element.parentNode) { + callback(); + } else { + window.requestAnimationFrame(observerFn); + } + }; + observerFn(); + return { cancel: function cancel() { + return isCanceled = true; + } }; + } + exports.setData = setData; exports.getEventTargetMatchingTag = getEventTargetMatchingTag; exports.getElementRelativeOffset = getElementRelativeOffset; @@ -12674,6 +13682,7 @@ define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/str exports.positionElementToRect = positionElementToRect; exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect; exports.positionElementCenteredBelow = positionElementCenteredBelow; + exports.whenElementIsNotInDOM = whenElementIsNotInDOM; }); define('mobiledoc-kit/utils/environment', ['exports'], function (exports) { 'use strict'; @@ -12736,12 +13745,13 @@ define("mobiledoc-kit/utils/fixed-queue", ["exports"], function (exports) { exports["default"] = FixedQueue; }); -define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) { +define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/keys', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKeys, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) { 'use strict'; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); exports.modifierMask = modifierMask; + exports.specialCharacterToCode = specialCharacterToCode; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } @@ -12795,7 +13805,10 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm DEL: _mobiledocKitUtilsKeycodes['default'].DELETE }; - exports.SPECIAL_KEYS = SPECIAL_KEYS; + function specialCharacterToCode(specialCharacter) { + return SPECIAL_KEYS[specialCharacter]; + } + // heuristic for determining if `event` is a key event function isKeyEvent(event) { return (/^key/.test(event.type) @@ -12811,6 +13824,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm function Key(event) { _classCallCheck(this, Key); + this.key = event.key; this.keyCode = event.keyCode; this.charCode = event.charCode; this.event = event; @@ -12825,20 +13839,38 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm } return String.fromCharCode(this.charCode); } + + // See https://caniuse.com/#feat=keyboardevent-key for browser support. + }, { + key: 'isKeySupported', + value: function isKeySupported() { + return this.key; + } + }, { + key: 'isKey', + value: function isKey(identifier) { + if (this.isKeySupported()) { + (0, _mobiledocKitUtilsAssert['default'])('Must define Keys.' + identifier + '.', _mobiledocKitUtilsKeys['default'][identifier]); + return this.key === _mobiledocKitUtilsKeys['default'][identifier]; + } else { + (0, _mobiledocKitUtilsAssert['default'])('Must define Keycodes.' + identifier + '.', _mobiledocKitUtilsKeycodes['default'][identifier]); + return this.keyCode === _mobiledocKitUtilsKeycodes['default'][identifier]; + } + } }, { key: 'isEscape', value: function isEscape() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ESC; + return this.isKey('ESC'); } }, { key: 'isDelete', value: function isDelete() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].BACKSPACE || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE; + return this.isKey('BACKSPACE') || this.isForwardDelete(); } }, { key: 'isForwardDelete', value: function isForwardDelete() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE; + return this.isKey('DELETE'); } }, { key: 'isArrow', @@ -12848,7 +13880,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isHorizontalArrow', value: function isHorizontalArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT || this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT; + return this.isLeftArrow() || this.isRightArrow(); } }, { key: 'isHorizontalArrowWithoutModifiersOtherThanShift', @@ -12858,56 +13890,75 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isVerticalArrow', value: function isVerticalArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].UP || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DOWN; + return this.isKey('UP') || this.isKey('DOWN'); } }, { key: 'isLeftArrow', value: function isLeftArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT; + return this.isKey('LEFT'); } }, { key: 'isRightArrow', value: function isRightArrow() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT; + return this.isKey('RIGHT'); } }, { key: 'isHome', value: function isHome() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].HOME; + return this.isKey('HOME'); } }, { key: 'isEnd', value: function isEnd() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].END; + return this.isKey('END'); + } + }, { + key: 'isPageUp', + value: function isPageUp() { + return this.isKey('PAGEUP'); + } + }, { + key: 'isPageDown', + value: function isPageDown() { + return this.isKey('PAGEDOWN'); + } + }, { + key: 'isInsert', + value: function isInsert() { + return this.isKey('INS'); + } + }, { + key: 'isClear', + value: function isClear() { + return this.isKey('CLEAR'); + } + }, { + key: 'isPause', + value: function isPause() { + return this.isKey('PAUSE'); } }, { key: 'isSpace', value: function isSpace() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SPACE; + return this.isKey('SPACE'); } + + // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but + // it will also fire a keydown event for the tab+modifier (ctrl). This causes + // Mobiledoc to erroneously insert a tab character before FF switches to the + // new browser tab. Chrome doesn't fire this event so the issue doesn't + // arise there. Fix this by returning false when the TAB key event includes a + // modifier. + // See: https://github.com/bustle/mobiledoc-kit/issues/565 }, { key: 'isTab', value: function isTab() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].TAB; + return !this.hasAnyModifier() && this.isKey('TAB'); } }, { key: 'isEnter', value: function isEnter() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ENTER; - } - - /** - * If the shift key is depressed. - * For example, while holding down meta+shift, pressing the "v" - * key would result in an event whose `Key` had `isShift()` with a truthy value, - * because the shift key is down when pressing the "v". - * @see {isShiftKey} which checks if the key is actually the shift key itself. - * @return {bool} - */ - }, { - key: 'isShift', - value: function isShift() { - return this.shiftKey; + return this.isKey('ENTER'); } /* @@ -12919,7 +13970,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isShiftKey', value: function isShiftKey() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SHIFT; + return this.isKey('SHIFT'); } /* @@ -12930,7 +13981,7 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isAltKey', value: function isAltKey() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ALT; + return this.isKey('ALT'); } /* @@ -12941,7 +13992,28 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm }, { key: 'isCtrlKey', value: function isCtrlKey() { - return this.keyCode === _mobiledocKitUtilsKeycodes['default'].CTRL; + return this.isKey('CTRL'); + } + }, { + key: 'isIME', + value: function isIME() { + // FIXME the IME action seems to get lost when we issue an + // `editor.deleteSelection` before it (in Chrome) + return this.keyCode === _mobiledocKitUtilsKeycodes['default'].IME; + } + }, { + key: 'isShift', + + /** + * If the shift key is depressed. + * For example, while holding down meta+shift, pressing the "v" + * key would result in an event whose `Key` had `isShift()` with a truthy value, + * because the shift key is down when pressing the "v". + * @see {isShiftKey} which checks if the key is actually the shift key itself. + * @return {bool} + */ + value: function isShift() { + return this.shiftKey; } }, { key: 'hasModifier', @@ -12954,33 +14026,60 @@ define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'm return !!this.modifierMask; } }, { - key: 'isPrintable', + key: 'isPrintableKey', + value: function isPrintableKey() { + return !(this.isArrow() || this.isHome() || this.isEnd() || this.isPageUp() || this.isPageDown() || this.isInsert() || this.isClear() || this.isPause() || this.isEscape()); + } + }, { + key: 'isNumberKey', + value: function isNumberKey() { + if (this.isKeySupported()) { + return this.key >= '0' && this.key <= '9'; + } else { + var code = this.keyCode; + return code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9; // numpad keys + } + } + }, { + key: 'isLetterKey', + value: function isLetterKey() { + if (this.isKeySupported()) { + var key = this.key; + return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z'; + } else { + var code = this.keyCode; + return code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z; + } + } + }, { + key: 'isPunctuation', + value: function isPunctuation() { + if (this.isKeySupported()) { + var key = this.key; + return key >= ';' && key <= '`' || key >= '[' && key <= '"'; + } else { + var code = this.keyCode; + return code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['"']; + } + } /** * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position * and http://stackoverflow.com/a/12467610/137784 */ + }, { + key: 'isPrintable', value: function isPrintable() { if (this.ctrlKey || this.metaKey) { return false; } - var code = this.keyCode; - - // Firefox calls keypress events for arrow keys, but they should not be - // considered printable - if (this.isArrow()) { + // Firefox calls keypress events for some keys that should not be printable + if (!this.isPrintableKey()) { return false; } - return code !== 0 || this.toString().length > 0 || code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || // number keys - this.isSpace() || this.isTab() || this.isEnter() || code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || // letter keys - code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9 || // numpad keys - code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || // punctuation - code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['"'] || - // FIXME the IME action seems to get lost when we issue an `editor.deleteSelection` - // before it (in Chrome) - code === _mobiledocKitUtilsKeycodes['default'].IME; + return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME(); } }, { key: 'direction', @@ -13056,6 +14155,8 @@ define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) { IME: 229, TAB: 9, + CLEAR: 12, + PAUSE: 19, PAGEUP: 33, PAGEDOWN: 34, END: 35, @@ -13070,6 +14171,33 @@ define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) { CTRL: 17 }; }); +define('mobiledoc-kit/utils/keys', ['exports'], function (exports) { + 'use strict'; + + exports['default'] = { + BACKSPACE: 'Backspace', + SPACE: ' ', + ENTER: 'Enter', + SHIFT: 'Shift', + ESC: 'Escape', + DELETE: 'Delete', + INS: 'Insert', + HOME: 'Home', + END: 'End', + PAGEUP: 'PageUp', + PAGEDOWN: 'PageDown', + CLEAR: 'Clear', + PAUSE: 'Pause', + TAB: 'Tab', + ALT: 'Alt', + CTRL: 'Control', + + LEFT: 'ArrowLeft', + RIGHT: 'ArrowRight', + UP: 'ArrowUp', + DOWN: 'ArrowDown' + }; +}); define("mobiledoc-kit/utils/linked-item", ["exports"], function (exports) { "use strict"; @@ -13174,25 +14302,29 @@ define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/asser break; case 'middle': - var prevItem = nextItem.prev; - item.next = nextItem; - item.prev = prevItem; - nextItem.prev = item; - prevItem.next = item; + { + var prevItem = nextItem.prev; + item.next = nextItem; + item.prev = prevItem; + nextItem.prev = item; + prevItem.next = item; - break; + break; + } case 'end': - var tail = this.tail; - item.prev = tail; + { + var tail = this.tail; + item.prev = tail; - if (tail) { - tail.next = item; - } else { - this.head = item; - } - this.tail = item; + if (tail) { + tail.next = item; + } else { + this.head = item; + } + this.tail = item; - break; + break; + } } } }, { @@ -13624,6 +14756,23 @@ define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) { exports['default'] = MobiledocError; }); +define("mobiledoc-kit/utils/object-utils", ["exports"], function (exports) { + "use strict"; + + exports.entries = entries; + + function entries(obj) { + var ownProps = Object.keys(obj); + var i = ownProps.length; + var resArray = new Array(i); + + while (i--) { + resArray[i] = [ownProps[i], obj[ownProps[i]]]; + } + + return resArray; + } +}); define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) { /* global JSON */ 'use strict'; @@ -13844,6 +14993,7 @@ define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/k * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js * @return {Object} {node, offset} */ + /* eslint-disable complexity */ function findOffsetInNode(_x, _x2) { var _again = true; @@ -13901,6 +15051,7 @@ define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/k return { node: node, offset: offset }; } } + /* eslint-enable complexity */ function constrainNodeTo(node, parentNode, existingOffset) { var compare = parentNode.compareDocumentPosition(node); @@ -14154,7 +15305,7 @@ define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/r define('mobiledoc-kit/version', ['exports'], function (exports) { 'use strict'; - exports['default'] = '0.10.16'; + exports['default'] = '0.12.2'; }); define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) { 'use strict'; @@ -14194,6 +15345,9 @@ define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'm this.addEventListener(rootElement, 'mouseout', function (e) { clearTimeout(timeout); + if (_this.elementObserver) { + _this.elementObserver.cancel(); + } var toElement = e.toElement || e.relatedTarget; if (toElement && toElement.className !== _this.element.className) { _this.hide(); @@ -14212,8 +15366,13 @@ define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'm }, { key: 'showLink', value: function showLink(link, element) { + var _this2 = this; + var message = '' + link + ''; this.showMessage(message, element); + this.elementObserver = (0, _mobiledocKitUtilsElementUtils.whenElementIsNotInDOM)(element, function () { + return _this2.hide(); + }); } }]); @@ -14403,6 +15562,7 @@ define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-r case null: case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3: case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1: + case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_2: return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render(); default: throw new Error('Unexpected Mobiledoc version "' + version + '"'); @@ -14670,11 +15830,11 @@ define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-rend exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3; var MOBILEDOC_VERSION_0_3_1 = '0.3.1'; exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1; - var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_1; + var MOBILEDOC_VERSION_0_3_2 = '0.3.2'; - exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; + exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2; function validateVersion(version) { - if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1) { + if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1 && version !== MOBILEDOC_VERSION_0_3_2) { throw new Error('Unexpected Mobiledoc version "' + version + '"'); } } diff --git a/website/global/mobiledoc-kit.map b/website/global/mobiledoc-kit.map index 1ad087249..b93e78407 100644 --- a/website/global/mobiledoc-kit.map +++ b/website/global/mobiledoc-kit.map @@ -1 +1 @@ -{"version":3,"sources":["loader.js/loader.js","mobiledoc-dom-renderer/cards/image.js","mobiledoc-dom-renderer/index.js","mobiledoc-dom-renderer/renderer-factory.js","mobiledoc-dom-renderer/renderers/0-2.js","mobiledoc-dom-renderer/renderers/0-3.js","mobiledoc-dom-renderer/utils/array-utils.js","mobiledoc-dom-renderer/utils/dom.js","mobiledoc-dom-renderer/utils/marker-types.js","mobiledoc-dom-renderer/utils/render-type.js","mobiledoc-dom-renderer/utils/render-utils.js","mobiledoc-dom-renderer/utils/sanitization-utils.js","mobiledoc-dom-renderer/utils/section-types.js","mobiledoc-dom-renderer/utils/tag-names.js","mobiledoc-kit/cards/image.js","mobiledoc-kit/editor/edit-history.js","mobiledoc-kit/editor/edit-state.js","mobiledoc-kit/editor/editor.js","mobiledoc-kit/editor/event-manager.js","mobiledoc-kit/editor/key-commands.js","mobiledoc-kit/editor/mutation-handler.js","mobiledoc-kit/editor/post.js","mobiledoc-kit/editor/post/post-inserter.js","mobiledoc-kit/editor/selection-change-observer.js","mobiledoc-kit/editor/selection-manager.js","mobiledoc-kit/editor/text-input-handler.js","mobiledoc-kit/editor/text-input-handlers.js","mobiledoc-kit/editor/ui.js","mobiledoc-kit/index.js","mobiledoc-kit/models/_markerable.js","mobiledoc-kit/models/_section.js","mobiledoc-kit/models/atom-node.js","mobiledoc-kit/models/atom.js","mobiledoc-kit/models/card-node.js","mobiledoc-kit/models/card.js","mobiledoc-kit/models/image.js","mobiledoc-kit/models/lifecycle-callbacks.js","mobiledoc-kit/models/list-item.js","mobiledoc-kit/models/list-section.js","mobiledoc-kit/models/marker.js","mobiledoc-kit/models/markup-section.js","mobiledoc-kit/models/markup.js","mobiledoc-kit/models/post-node-builder.js","mobiledoc-kit/models/post.js","mobiledoc-kit/models/render-node.js","mobiledoc-kit/models/render-tree.js","mobiledoc-kit/models/types.js","mobiledoc-kit/parsers/dom.js","mobiledoc-kit/parsers/html.js","mobiledoc-kit/parsers/mobiledoc/0-2.js","mobiledoc-kit/parsers/mobiledoc/0-3-1.js","mobiledoc-kit/parsers/mobiledoc/0-3.js","mobiledoc-kit/parsers/mobiledoc/index.js","mobiledoc-kit/parsers/section.js","mobiledoc-kit/parsers/text.js","mobiledoc-kit/renderers/editor-dom.js","mobiledoc-kit/renderers/mobiledoc/0-2.js","mobiledoc-kit/renderers/mobiledoc/0-3-1.js","mobiledoc-kit/renderers/mobiledoc/0-3.js","mobiledoc-kit/renderers/mobiledoc/index.js","mobiledoc-kit/utils/array-utils.js","mobiledoc-kit/utils/assert.js","mobiledoc-kit/utils/browser.js","mobiledoc-kit/utils/characters.js","mobiledoc-kit/utils/compiler.js","mobiledoc-kit/utils/copy.js","mobiledoc-kit/utils/cursor.js","mobiledoc-kit/utils/cursor/position.js","mobiledoc-kit/utils/cursor/range.js","mobiledoc-kit/utils/deprecate.js","mobiledoc-kit/utils/dom-utils.js","mobiledoc-kit/utils/element-map.js","mobiledoc-kit/utils/element-utils.js","mobiledoc-kit/utils/environment.js","mobiledoc-kit/utils/fixed-queue.js","mobiledoc-kit/utils/key.js","mobiledoc-kit/utils/keycodes.js","mobiledoc-kit/utils/linked-item.js","mobiledoc-kit/utils/linked-list.js","mobiledoc-kit/utils/log-manager.js","mobiledoc-kit/utils/markuperable.js","mobiledoc-kit/utils/merge.js","mobiledoc-kit/utils/mixin.js","mobiledoc-kit/utils/mobiledoc-error.js","mobiledoc-kit/utils/parse-utils.js","mobiledoc-kit/utils/placeholder-image-src.js","mobiledoc-kit/utils/selection-utils.js","mobiledoc-kit/utils/set.js","mobiledoc-kit/utils/string-utils.js","mobiledoc-kit/utils/to-range.js","mobiledoc-kit/version.js","mobiledoc-kit/views/tooltip.js","mobiledoc-kit/views/view.js","mobiledoc-text-renderer/cards/image.js","mobiledoc-text-renderer/index.js","mobiledoc-text-renderer/renderer-factory.js","mobiledoc-text-renderer/renderers/0-2.js","mobiledoc-text-renderer/renderers/0-3.js","mobiledoc-text-renderer/utils/marker-types.js","mobiledoc-text-renderer/utils/render-type.js","mobiledoc-text-renderer/utils/section-types.js"],"sourcesContent":["var loader, define, requireModule, require, requirejs;\n\n(function (global) {\n 'use strict';\n\n var heimdall = global.heimdall;\n\n function dict() {\n var obj = Object.create(null);\n obj['__'] = undefined;\n delete obj['__'];\n return obj;\n }\n\n // Save off the original values of these globals, so we can restore them if someone asks us to\n var oldGlobals = {\n loader: loader,\n define: define,\n requireModule: requireModule,\n require: require,\n requirejs: requirejs\n };\n\n requirejs = require = requireModule = function (name) {\n var pending = [];\n var mod = findModule(name, '(require)', pending);\n\n for (var i = pending.length - 1; i >= 0; i--) {\n pending[i].exports();\n }\n\n return mod.module.exports;\n };\n\n loader = {\n noConflict: function (aliases) {\n var oldName, newName;\n\n for (oldName in aliases) {\n if (aliases.hasOwnProperty(oldName)) {\n if (oldGlobals.hasOwnProperty(oldName)) {\n newName = aliases[oldName];\n\n global[newName] = global[oldName];\n global[oldName] = oldGlobals[oldName];\n }\n }\n }\n }\n };\n\n var _isArray;\n if (!Array.isArray) {\n _isArray = function (x) {\n return Object.prototype.toString.call(x) === '[object Array]';\n };\n } else {\n _isArray = Array.isArray;\n }\n\n var registry = dict();\n var seen = dict();\n\n var uuid = 0;\n\n function unsupportedModule(length) {\n throw new Error('an unsupported module was defined, expected `define(name, deps, module)` instead got: `' + length + '` arguments to define`');\n }\n\n var defaultDeps = ['require', 'exports', 'module'];\n\n function Module(name, deps, callback, alias) {\n this.id = uuid++;\n this.name = name;\n this.deps = !deps.length && callback.length ? defaultDeps : deps;\n this.module = { exports: {} };\n this.callback = callback;\n this.hasExportsAsDep = false;\n this.isAlias = alias;\n this.reified = new Array(deps.length);\n\n /*\n Each module normally passes through these states, in order:\n new : initial state\n pending : this module is scheduled to be executed\n reifying : this module's dependencies are being executed\n reified : this module's dependencies finished executing successfully\n errored : this module's dependencies failed to execute\n finalized : this module executed successfully\n */\n this.state = 'new';\n }\n\n Module.prototype.makeDefaultExport = function () {\n var exports = this.module.exports;\n if (exports !== null && (typeof exports === 'object' || typeof exports === 'function') && exports['default'] === undefined && Object.isExtensible(exports)) {\n exports['default'] = exports;\n }\n };\n\n Module.prototype.exports = function () {\n // if finalized, there is no work to do. If reifying, there is a\n // circular dependency so we must return our (partial) exports.\n if (this.state === 'finalized' || this.state === 'reifying') {\n return this.module.exports;\n }\n\n if (loader.wrapModules) {\n this.callback = loader.wrapModules(this.name, this.callback);\n }\n\n this.reify();\n\n var result = this.callback.apply(this, this.reified);\n this.state = 'finalized';\n\n if (!(this.hasExportsAsDep && result === undefined)) {\n this.module.exports = result;\n }\n this.makeDefaultExport();\n return this.module.exports;\n };\n\n Module.prototype.unsee = function () {\n this.state = 'new';\n this.module = { exports: {} };\n };\n\n Module.prototype.reify = function () {\n if (this.state === 'reified') {\n return;\n }\n this.state = 'reifying';\n try {\n this.reified = this._reify();\n this.state = 'reified';\n } finally {\n if (this.state === 'reifying') {\n this.state = 'errored';\n }\n }\n };\n\n Module.prototype._reify = function () {\n var reified = this.reified.slice();\n for (var i = 0; i < reified.length; i++) {\n var mod = reified[i];\n reified[i] = mod.exports ? mod.exports : mod.module.exports();\n }\n return reified;\n };\n\n Module.prototype.findDeps = function (pending) {\n if (this.state !== 'new') {\n return;\n }\n\n this.state = 'pending';\n\n var deps = this.deps;\n\n for (var i = 0; i < deps.length; i++) {\n var dep = deps[i];\n var entry = this.reified[i] = { exports: undefined, module: undefined };\n if (dep === 'exports') {\n this.hasExportsAsDep = true;\n entry.exports = this.module.exports;\n } else if (dep === 'require') {\n entry.exports = this.makeRequire();\n } else if (dep === 'module') {\n entry.exports = this.module;\n } else {\n entry.module = findModule(resolve(dep, this.name), this.name, pending);\n }\n }\n };\n\n Module.prototype.makeRequire = function () {\n var name = this.name;\n var r = function (dep) {\n return require(resolve(dep, name));\n };\n r['default'] = r;\n r.has = function (dep) {\n return has(resolve(dep, name));\n };\n return r;\n };\n\n define = function (name, deps, callback) {\n var module = registry[name];\n\n // If a module for this name has already been defined and is in any state\n // other than `new` (meaning it has been or is currently being required),\n // then we return early to avoid redefinition.\n if (module && module.state !== 'new') {\n return;\n }\n\n if (arguments.length < 2) {\n unsupportedModule(arguments.length);\n }\n\n if (!_isArray(deps)) {\n callback = deps;\n deps = [];\n }\n\n if (callback instanceof Alias) {\n registry[name] = new Module(callback.name, deps, callback, true);\n } else {\n registry[name] = new Module(name, deps, callback, false);\n }\n };\n\n // we don't support all of AMD\n // define.amd = {};\n\n function Alias(path) {\n this.name = path;\n }\n\n define.alias = function (path) {\n return new Alias(path);\n };\n\n function missingModule(name, referrer) {\n throw new Error('Could not find module `' + name + '` imported from `' + referrer + '`');\n }\n\n function findModule(name, referrer, pending) {\n var mod = registry[name] || registry[name + '/index'];\n\n while (mod && mod.isAlias) {\n mod = registry[mod.name];\n }\n\n if (!mod) {\n missingModule(name, referrer);\n }\n\n if (pending && mod.state !== 'pending' && mod.state !== 'finalized') {\n mod.findDeps(pending);\n pending.push(mod);\n }\n return mod;\n }\n\n function resolve(child, name) {\n if (child.charAt(0) !== '.') {\n return child;\n }\n\n var parts = child.split('/');\n var nameParts = name.split('/');\n var parentBase = nameParts.slice(0, -1);\n\n for (var i = 0, l = parts.length; i < l; i++) {\n var part = parts[i];\n\n if (part === '..') {\n if (parentBase.length === 0) {\n throw new Error('Cannot access parent module of root');\n }\n parentBase.pop();\n } else if (part === '.') {\n continue;\n } else {\n parentBase.push(part);\n }\n }\n\n return parentBase.join('/');\n }\n\n function has(name) {\n return !!(registry[name] || registry[name + '/index']);\n }\n\n requirejs.entries = requirejs._eak_seen = registry;\n requirejs.has = has;\n requirejs.unsee = function (moduleName) {\n findModule(moduleName, '(unsee)', false).unsee();\n };\n\n requirejs.clear = function () {\n requirejs.entries = requirejs._eak_seen = registry = dict();\n seen = dict();\n };\n\n // This code primes the JS engine for good performance by warming the\n // JIT compiler for these functions.\n define('foo', function () {});\n define('foo/bar', [], function () {});\n define('foo/asdf', ['module', 'exports', 'require'], function (module, exports, require) {\n if (require.has('foo/bar')) {\n require('foo/bar');\n }\n });\n define('foo/baz', [], define.alias('foo'));\n define('foo/quz', define.alias('foo'));\n define('foo/bar', ['foo', './quz', './baz', './asdf', './bar', '../foo'], function () {});\n define('foo/main', ['foo/bar'], function () {});\n\n require('foo/main');\n require.unsee('foo/bar');\n\n requirejs.clear();\n\n if (typeof exports === 'object' && typeof module === 'object' && module.exports) {\n module.exports = { require: require, define: define };\n }\n})(this);","define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: function render(_ref) {\n var payload = _ref.payload;\n var dom = _ref.env.dom;\n\n var img = dom.createElement('img');\n img.src = payload.src;\n return img;\n }\n };\n});","define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];\n\n function registerGlobal(window) {\n window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];\n }\n\n exports['default'] = _mobiledocDomRendererRendererFactory['default'];\n});","define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderers/0-2', 'mobiledoc-dom-renderer/renderers/0-3', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderers02, _mobiledocDomRendererRenderers03, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime DOM renderer\n * renders a mobiledoc to DOM\n *\n * input: mobiledoc\n * output: DOM\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be of type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var _ref$cards = _ref.cards;\n var cards = _ref$cards === undefined ? [] : _ref$cards;\n var _ref$atoms = _ref.atoms;\n var atoms = _ref$atoms === undefined ? [] : _ref$atoms;\n var _ref$cardOptions = _ref.cardOptions;\n var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n var _ref$markupElementRenderer = _ref.markupElementRenderer;\n var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer;\n var _ref$sectionElementRenderer = _ref.sectionElementRenderer;\n var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer;\n var dom = _ref.dom;\n var _ref$markupSanitizer = _ref.markupSanitizer;\n var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer;\n\n _classCallCheck(this, RendererFactory);\n\n validateCards(cards);\n validateAtoms(atoms);\n\n if (!dom) {\n if (typeof window === 'undefined') {\n throw new Error('A `dom` option must be provided to the renderer when running without window.document');\n }\n dom = window.document;\n }\n\n this.options = {\n cards: cards,\n atoms: atoms,\n cardOptions: cardOptions,\n unknownCardHandler: unknownCardHandler,\n unknownAtomHandler: unknownAtomHandler,\n markupElementRenderer: markupElementRenderer,\n sectionElementRenderer: sectionElementRenderer,\n dom: dom,\n markupSanitizer: markupSanitizer\n };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocDomRendererRenderers02.MOBILEDOC_VERSION:\n case undefined:\n case null:\n return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render();\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-dom-renderer/renderers/0-2', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, options) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = options.cards;\n var cardOptions = options.cardOptions;\n var unknownCardHandler = options.unknownCardHandler;\n var markupElementRenderer = options.markupElementRenderer;\n var sectionElementRenderer = options.sectionElementRenderer;\n var dom = options.dom;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var markerTypes = _sectionData[0];\n var sections = _sectionData[1];\n\n this.dom = dom;\n this.root = dom.createDocumentFragment();\n this.markerTypes = markerTypes;\n this.sections = sections;\n this.cards = cards;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n this._renderedChildNodes = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = [];\n var node = this.root.firstChild;\n while (node) {\n this._renderedChildNodes.push(node);\n node = node.nextSibling;\n }\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 3);\n\n var openTypes = _marker[0];\n var closeCount = _marker[1];\n var text = _marker[2];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, text));\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var name = _ref42[1];\n var payload = _ref42[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils', 'mobiledoc-dom-renderer/utils/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils, _mobiledocDomRendererUtilsMarkerTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION_0_3_0 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_0;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n switch (version) {\n case MOBILEDOC_VERSION_0_3_0:\n case MOBILEDOC_VERSION_0_3_1:\n return;\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var markupElementRenderer = state.markupElementRenderer;\n var sectionElementRenderer = state.sectionElementRenderer;\n var dom = state.dom;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n var markerTypes = mobiledoc.markups;\n\n validateVersion(version);\n\n this.dom = dom;\n this.root = this.dom.createDocumentFragment();\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.markerTypes = markerTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 4);\n\n var type = _marker[0];\n var openTypes = _marker[1];\n var closeCount = _marker[2];\n var value = _marker[3];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n switch (type) {\n case _mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, value));\n break;\n case _mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n currentElement.appendChild(this._renderAtom(value));\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var index = _ref42[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this5 = this;\n\n var env = {\n name: atom.name,\n isInEditor: false,\n dom: this.dom,\n onTeardown: function onTeardown(callback) {\n return _this5._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || (0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, '');\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref7) {\n var name = _ref7.env.name;\n\n throw new Error('Atom \"' + name + '\" not found but no unknownAtomHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-dom-renderer/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.includes = includes;\n\n function includes(array, detectValue) {\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n if (value === detectValue) {\n return true;\n }\n }\n return false;\n }\n});","define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) {\n 'use strict';\n\n exports.createTextNode = createTextNode;\n exports.normalizeTagName = normalizeTagName;\n function addHTMLSpaces(text) {\n var nbsp = ' ';\n return text.replace(/ /g, ' ' + nbsp);\n }\n\n function createTextNode(dom, text) {\n return dom.createTextNode(addHTMLSpaces(text));\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n});","define(\"mobiledoc-dom-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'dom';\n});","define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) {\n 'use strict';\n\n exports.defaultSectionElementRenderer = defaultSectionElementRenderer;\n exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer;\n\n function defaultSectionElementRenderer(tagName, dom) {\n var element = undefined;\n if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) {\n element = dom.createElement(tagName);\n } else {\n element = dom.createElement('div');\n element.setAttribute('class', tagName);\n }\n\n return element;\n }\n\n function sanitizeAttribute(tagName, attrName, attrValue) {\n if (tagName === 'a' && attrName === 'href') {\n return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attrValue);\n } else {\n return attrValue;\n }\n }\n\n function defaultMarkupElementRenderer(tagName, dom, attrsObj) {\n var element = dom.createElement(tagName);\n Object.keys(attrsObj).forEach(function (attrName) {\n var attrValue = attrsObj[attrName];\n attrValue = sanitizeAttribute(tagName, attrName, attrValue);\n element.setAttribute(attrName, attrValue);\n });\n return element;\n }\n});","define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {\n 'use strict';\n\n exports.sanitizeHref = sanitizeHref;\n exports.reduceAttributes = reduceAttributes;\n\n var PROTOCOL_REGEXP = /^([a-z0-9.+-]+:)/i;\n\n var badProtocols = ['javascript:', // jshint ignore:line\n 'vbscript:' // jshint ignore:line\n ];\n\n function getProtocol(url) {\n var matches = url && url.match(PROTOCOL_REGEXP);\n var protocol = matches && matches[0] || ':';\n return protocol;\n }\n\n function sanitizeHref(url) {\n var protocol = getProtocol(url);\n if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) {\n return 'unsafe:' + url;\n }\n return url;\n }\n\n /**\n * @param attributes array\n * @return obj with normalized attribute names (lowercased)\n */\n\n function reduceAttributes(attributes) {\n var obj = {};\n for (var i = 0; i < attributes.length; i += 2) {\n var key = attributes[i];\n var val = attributes[i + 1];\n obj[key.toLowerCase()] = val;\n }\n return obj;\n }\n});","define(\"mobiledoc-dom-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});","define('mobiledoc-dom-renderer/utils/tag-names', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsDom) {\n 'use strict';\n\n exports.isValidSectionTagName = isValidSectionTagName;\n exports.isMarkupSectionElementName = isMarkupSectionElementName;\n exports.isValidMarkerType = isValidMarkerType;\n\n var MARKUP_SECTION_TAG_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pull-quote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_SECTION_ELEMENT_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var LIST_SECTION_TAG_NAMES = ['ul', 'ol'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_TYPES = ['b', 'i', 'strong', 'em', 'a', 'u', 'sub', 'sup', 's', 'code'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function isValidSectionTagName(tagName, sectionType) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n\n switch (sectionType) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return contains(MARKUP_SECTION_TAG_NAMES, tagName);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return contains(LIST_SECTION_TAG_NAMES, tagName);\n default:\n throw new Error('Cannot validate tagName for unknown section type \"' + sectionType + '\"');\n }\n }\n\n function isMarkupSectionElementName(tagName) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n return contains(MARKUP_SECTION_ELEMENT_NAMES, tagName);\n }\n\n function isValidMarkerType(type) {\n type = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(type);\n return contains(MARKUP_TYPES, type);\n }\n});","define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder-image-src'], function (exports, _mobiledocKitUtilsPlaceholderImageSrc) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: 'dom',\n\n render: function render(_ref) {\n var env = _ref.env;\n var options = _ref.options;\n var payload = _ref.payload;\n\n var img = document.createElement('img');\n img.src = payload.src || _mobiledocKitUtilsPlaceholderImageSrc['default'];\n return img;\n }\n };\n});","define('mobiledoc-kit/editor/edit-history', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/utils/fixed-queue'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitUtilsFixedQueue) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function findLeafSectionAtIndex(post, index) {\n var section = undefined;\n post.walkAllLeafSections(function (_section, _index) {\n if (index === _index) {\n section = _section;\n }\n });\n return section;\n }\n\n var Snapshot = (function () {\n function Snapshot(takenAt, editor) {\n var editAction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n _classCallCheck(this, Snapshot);\n\n this.mobiledoc = editor.serialize();\n this.editor = editor;\n this.editAction = editAction;\n this.takenAt = takenAt;\n\n this.snapshotRange();\n }\n\n _createClass(Snapshot, [{\n key: 'snapshotRange',\n value: function snapshotRange() {\n var _editor = this.editor;\n var range = _editor.range;\n var cursor = _editor.cursor;\n\n if (cursor.hasCursor() && !range.isBlank) {\n var head = range.head;\n var tail = range.tail;\n\n this.range = {\n head: [head.leafSectionIndex, head.offset],\n tail: [tail.leafSectionIndex, tail.offset]\n };\n }\n }\n }, {\n key: 'getRange',\n value: function getRange(post) {\n if (this.range) {\n var _range = this.range;\n var head = _range.head;\n var tail = _range.tail;\n var _head = head;\n\n var _head2 = _slicedToArray(_head, 2);\n\n var headLeafSectionIndex = _head2[0];\n var headOffset = _head2[1];\n var _tail = tail;\n\n var _tail2 = _slicedToArray(_tail, 2);\n\n var tailLeafSectionIndex = _tail2[0];\n var tailOffset = _tail2[1];\n\n var headSection = findLeafSectionAtIndex(post, headLeafSectionIndex);\n var tailSection = findLeafSectionAtIndex(post, tailLeafSectionIndex);\n\n head = headSection.toPosition(headOffset);\n tail = tailSection.toPosition(tailOffset);\n\n return head.toRange(tail);\n }\n }\n }, {\n key: 'groupsWith',\n value: function groupsWith(groupingTimeout, editAction, takenAt) {\n return editAction !== null && this.editAction === editAction && this.takenAt + groupingTimeout > takenAt;\n }\n }]);\n\n return Snapshot;\n })();\n\n exports.Snapshot = Snapshot;\n\n var EditHistory = (function () {\n function EditHistory(editor, queueLength, groupingTimeout) {\n _classCallCheck(this, EditHistory);\n\n this.editor = editor;\n this._undoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n this._redoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n\n this._pendingSnapshot = null;\n this._groupingTimeout = groupingTimeout;\n }\n\n _createClass(EditHistory, [{\n key: 'snapshot',\n value: function snapshot() {\n // update the current snapshot with the range read from DOM\n if (this._pendingSnapshot) {\n this._pendingSnapshot.snapshotRange();\n }\n }\n }, {\n key: 'storeSnapshot',\n value: function storeSnapshot() {\n var editAction = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];\n\n var now = Date.now();\n // store pending snapshot\n var pendingSnapshot = this._pendingSnapshot;\n if (pendingSnapshot) {\n if (!pendingSnapshot.groupsWith(this._groupingTimeout, editAction, now)) {\n this._undoStack.push(pendingSnapshot);\n }\n this._redoStack.clear();\n }\n\n // take new pending snapshot to store next time `storeSnapshot` is called\n this._pendingSnapshot = new Snapshot(now, this.editor, editAction);\n }\n }, {\n key: 'stepBackward',\n value: function stepBackward(postEditor) {\n // Throw away the pending snapshot\n this._pendingSnapshot = null;\n\n var snapshot = this._undoStack.pop();\n if (snapshot) {\n this._redoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n }\n }, {\n key: 'stepForward',\n value: function stepForward(postEditor) {\n var snapshot = this._redoStack.pop();\n if (snapshot) {\n this._undoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n postEditor.cancelSnapshot();\n }\n }, {\n key: '_restoreFromSnapshot',\n value: function _restoreFromSnapshot(snapshot, postEditor) {\n var mobiledoc = snapshot.mobiledoc;\n var editor = this.editor;\n var builder = editor.builder;\n var post = editor.post;\n\n var restoredPost = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(restoredPost);\n\n // resurrect snapshotted range if it exists\n var newRange = snapshot.getRange(post);\n if (newRange) {\n postEditor.setRange(newRange);\n }\n }\n }]);\n\n return EditHistory;\n })();\n\n exports['default'] = EditHistory;\n});","define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * Used by {@link Editor} to manage its current state (cursor, active markups\n * and active sections).\n * @private\n */\n\n var EditState = (function () {\n function EditState(editor) {\n _classCallCheck(this, EditState);\n\n this.editor = editor;\n\n var defaultState = {\n range: _mobiledocKitUtilsCursorRange['default'].blankRange(),\n activeMarkups: [],\n activeSections: [],\n activeSectionTagNames: []\n };\n\n this.prevState = this.state = defaultState;\n }\n\n _createClass(EditState, [{\n key: 'updateRange',\n value: function updateRange(newRange) {\n this.prevState = this.state;\n this.state = this._readState(newRange);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.editor = null;\n this.prevState = this.state = null;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'rangeDidChange',\n value: function rangeDidChange() {\n var range = this.state.range;\n var prevRange = this.prevState.range;\n\n return !prevRange.isEqual(range);\n }\n\n /**\n * @return {Boolean} Whether the input mode (active markups or active section tag names)\n * has changed.\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange() {\n var state = this.state;\n var prevState = this.prevState;\n\n return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames);\n }\n\n /**\n * @return {Range}\n */\n }, {\n key: 'toggleMarkupState',\n\n /**\n * Update the editor's markup state. This is used when, e.g.,\n * a user types meta+B when the editor has a cursor but no selected text;\n * in this case the editor needs to track that it has an active \"b\" markup\n * and apply it to the next text the user types.\n */\n value: function toggleMarkupState(markup) {\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(this.activeMarkups, markup)) {\n this._removeActiveMarkup(markup);\n } else {\n this._addActiveMarkup(markup);\n }\n }\n }, {\n key: '_readState',\n value: function _readState(range) {\n var state = {\n range: range,\n activeMarkups: this._readActiveMarkups(range),\n activeSections: this._readActiveSections(range)\n };\n // Section objects are 'live', so to check that they changed, we\n // need to map their tagNames now (and compare to mapped tagNames later).\n // In addition, to catch changes from ul -> ol, we keep track of the\n // un-nested tag names (otherwise we'd only see li -> li change)\n state.activeSectionTagNames = state.activeSections.map(function (s) {\n return s.isNested ? s.parent.tagName : s.tagName;\n });\n return state;\n }\n }, {\n key: '_readActiveSections',\n value: function _readActiveSections(range) {\n var head = range.head;\n var tail = range.tail;\n var post = this.editor.post;\n\n if (range.isBlank) {\n return [];\n } else {\n return post.sections.readRange(head.section, tail.section);\n }\n }\n }, {\n key: '_readActiveMarkups',\n value: function _readActiveMarkups(range) {\n var post = this.editor.post;\n\n return post.markupsInRange(range);\n }\n }, {\n key: '_removeActiveMarkup',\n value: function _removeActiveMarkup(markup) {\n var index = this.state.activeMarkups.indexOf(markup);\n this.state.activeMarkups.splice(index, 1);\n }\n }, {\n key: '_addActiveMarkup',\n value: function _addActiveMarkup(markup) {\n this.state.activeMarkups.push(markup);\n }\n }, {\n key: 'range',\n get: function get() {\n return this.state.range;\n }\n\n /**\n * @return {Section[]}\n */\n }, {\n key: 'activeSections',\n get: function get() {\n return this.state.activeSections;\n }\n\n /**\n * @return {Markup[]}\n */\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this.state.activeMarkups;\n }\n }]);\n\n return EditState;\n })();\n\n exports['default'] = EditState;\n});","define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/element-utils', 'mobiledoc-kit/utils/cursor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/environment', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/text-input-handlers', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/editor/mutation-handler', 'mobiledoc-kit/editor/edit-history', 'mobiledoc-kit/editor/event-manager', 'mobiledoc-kit/editor/edit-state', 'mobiledoc-dom-renderer', 'mobiledoc-text-renderer', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/log-manager', 'mobiledoc-kit/utils/to-range', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitViewsTooltip, _mobiledocKitEditorPost, _mobiledocKitCardsImage, _mobiledocKitUtilsKey, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersDom, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree, _mobiledocKitRenderersMobiledoc, _mobiledocKitUtilsMerge, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsElementUtils, _mobiledocKitUtilsCursor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsEnvironment, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorTextInputHandlers, _mobiledocKitEditorKeyCommands, _mobiledocKitModelsCard, _mobiledocKitUtilsAssert, _mobiledocKitEditorMutationHandler, _mobiledocKitEditorEditHistory, _mobiledocKitEditorEventManager, _mobiledocKitEditorEditState, _mobiledocDomRenderer, _mobiledocTextRenderer, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsLogManager, _mobiledocKitUtilsToRange, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // This export may later be deprecated, but re-export it from the renderer here\n // for consumers that may depend on it.\n Object.defineProperty(exports, 'EDITOR_ELEMENT_CLASS_NAME', {\n enumerable: true,\n get: function get() {\n return _mobiledocKitRenderersEditorDom.EDITOR_ELEMENT_CLASS_NAME;\n }\n });\n\n var defaults = {\n placeholder: 'Write here...',\n spellcheck: true,\n autofocus: true,\n undoDepth: 5,\n undoBlockTimeout: 5000, // ms for an undo event\n cards: [],\n atoms: [],\n cardOptions: {},\n unknownCardHandler: function unknownCardHandler(_ref) {\n var env = _ref.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown card encountered: ' + env.name);\n },\n unknownAtomHandler: function unknownAtomHandler(_ref2) {\n var env = _ref2.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown atom encountered: ' + env.name);\n },\n mobiledoc: null,\n html: null\n };\n\n var CALLBACK_QUEUES = {\n DID_UPDATE: 'didUpdate',\n WILL_RENDER: 'willRender',\n DID_RENDER: 'didRender',\n WILL_DELETE: 'willDelete',\n DID_DELETE: 'didDelete',\n WILL_HANDLE_NEWLINE: 'willHandleNewline',\n CURSOR_DID_CHANGE: 'cursorDidChange',\n DID_REPARSE: 'didReparse',\n POST_DID_CHANGE: 'postDidChange',\n INPUT_MODE_DID_CHANGE: 'inputModeDidChange'\n };\n\n /**\n * The Editor is a core component of mobiledoc-kit. After instantiating\n * an editor, use {@link Editor#render} to display the editor on the web page.\n *\n * An editor uses a {@link Post} internally to represent the displayed document.\n * The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc\n * is the transportable \"over-the-wire\" format (JSON) that is suited for persisting\n * and sharing between editors and renderers (for display, e.g.), whereas the Post\n * model is better suited for programmatic editing.\n *\n * The editor will call registered callbacks for certain state changes. These are:\n * * {@link Editor#cursorDidChange} -- The cursor position or selection changed.\n * * {@link Editor#postDidChange} -- The contents of the post changed due to user input or\n * programmatic editing. This hook can be used with {@link Editor#serialize}\n * to auto-save a post as it is being edited.\n * * {@link Editor#inputModeDidChange} -- The active section(s) or markup(s) at the current cursor\n * position or selection have changed. This hook can be used with\n * {@link Editor#activeMarkups} and {@link Editor#activeSections} to implement\n * a custom toolbar.\n * * {@link Editor#onTextInput} -- Register callbacks when the user enters text\n * that matches a given string or regex.\n */\n\n var Editor = (function () {\n /**\n * @param {Object} [options]\n * @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.\n * Supersedes `options.html`.\n * @param {String|DOM} [options.html] The html (as a string or DOM fragment)\n * to parse and load into the editor.\n * Will be ignored if `options.mobiledoc` is also passed.\n * @param {Array} [options.parserPlugins=[]]\n * @param {Array} [options.cards=[]] The cards that the editor may render.\n * @param {Array} [options.atoms=[]] The atoms that the editor may render.\n * @param {Function} [options.unknownCardHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown card.\n * @param {Function} [options.unknownAtomHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown atom.\n * @param {String} [options.placeholder] Default text to show before user starts typing.\n * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck\n * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered.\n * @param {number} [options.undoDepth=5] How many undo levels will be available.\n * Set to 0 to disable undo/redo functionality.\n * @return {Editor}\n * @public\n */\n\n function Editor() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, Editor);\n\n (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType);\n this._views = [];\n this.isEditable = null;\n this._parserPlugins = options.parserPlugins || [];\n\n // FIXME: This should merge onto this.options\n (0, _mobiledocKitUtilsMerge.mergeWithOptions)(this, defaults, options);\n this.cards.push(_mobiledocKitCardsImage['default']);\n\n _mobiledocKitEditorKeyCommands.DEFAULT_KEY_COMMANDS.forEach(function (kc) {\n return _this.registerKeyCommand(kc);\n });\n\n this._logManager = new _mobiledocKitUtilsLogManager['default']();\n this._parser = new _mobiledocKitParsersDom['default'](this.builder);\n var cards = this.cards;\n var atoms = this.atoms;\n var unknownCardHandler = this.unknownCardHandler;\n var unknownAtomHandler = this.unknownAtomHandler;\n var cardOptions = this.cardOptions;\n\n this._renderer = new _mobiledocKitRenderersEditorDom['default'](this, cards, atoms, unknownCardHandler, unknownAtomHandler, cardOptions);\n\n this.post = this.loadPost();\n this._renderTree = new _mobiledocKitModelsRenderTree['default'](this.post);\n\n this._editHistory = new _mobiledocKitEditorEditHistory['default'](this, this.undoDepth, this.undoBlockTimeout);\n this._eventManager = new _mobiledocKitEditorEventManager['default'](this);\n this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this);\n this._editState = new _mobiledocKitEditorEditState['default'](this);\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) {\n return _this.onTextInput(handler);\n });\n\n this.hasRendered = false;\n }\n\n /**\n * Turns on verbose logging for the editor.\n * @param {Array} [logTypes=[]] If present, only the given log types will be logged.\n * @public\n */\n\n _createClass(Editor, [{\n key: 'enableLogging',\n value: function enableLogging() {\n var logTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n if (logTypes.length === 0) {\n this._logManager.enableAll();\n } else {\n this._logManager.enableTypes(logTypes);\n }\n }\n\n /**\n * Disable all logging\n * @public\n */\n }, {\n key: 'disableLogging',\n value: function disableLogging() {\n this._logManager.disable();\n }\n\n /**\n * @private\n */\n }, {\n key: 'loggerFor',\n value: function loggerFor(type) {\n return this._logManager['for'](type);\n }\n\n /**\n * The editor's instance of a post node builder.\n * @type {PostNodeBuilder}\n */\n }, {\n key: 'loadPost',\n value: function loadPost() {\n var mobiledoc = this.mobiledoc;\n var html = this.html;\n\n if (mobiledoc) {\n return _mobiledocKitParsersMobiledoc['default'].parse(this.builder, mobiledoc);\n } else if (html) {\n if (typeof html === 'string') {\n var options = { plugins: this._parserPlugins };\n return new _mobiledocKitParsersHtml['default'](this.builder, options).parse(this.html);\n } else {\n var dom = html;\n return this._parser.parse(dom);\n }\n } else {\n return this.builder.createPost();\n }\n }\n }, {\n key: 'rerender',\n value: function rerender() {\n var _this2 = this;\n\n var postRenderNode = this.post.renderNode;\n\n // if we haven't rendered this post's renderNode before, mark it dirty\n if (!postRenderNode.element) {\n (0, _mobiledocKitUtilsAssert['default'])('Must call `render` before `rerender` can be called', this.hasRendered);\n postRenderNode.element = this.element;\n postRenderNode.markDirty();\n }\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_RENDER);\n this._mutationHandler.suspendObservation(function () {\n _this2._renderer.render(_this2._renderTree);\n });\n this.runCallbacks(CALLBACK_QUEUES.DID_RENDER);\n }\n\n /**\n * @param {Element} element The DOM element to render into.\n * Its contents will be replaced by the editor's rendered post.\n * @public\n */\n }, {\n key: 'render',\n value: function render(element) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot render an editor twice. Use `rerender` to update the ' + 'rendering of an existing editor instance.', !this.hasRendered);\n\n element.spellcheck = this.spellcheck;\n\n (0, _mobiledocKitUtilsDomUtils.clearChildNodes)(element);\n\n this.element = element;\n\n if (this.isEditable === null) {\n this.enableEditing();\n }\n\n this._addTooltip();\n\n // A call to `run` will trigger the didUpdatePostCallbacks hooks with a\n // postEditor.\n this.run(function () {});\n\n // Only set `hasRendered` to true after calling `run` to ensure that\n // no cursorDidChange or other callbacks get fired before the editor is\n // done rendering\n this.hasRendered = true;\n this.rerender();\n\n this._mutationHandler.init();\n this._eventManager.init();\n\n if (this.autofocus) {\n this.selectRange(this.post.headPosition());\n }\n }\n }, {\n key: '_addTooltip',\n value: function _addTooltip() {\n this.addView(new _mobiledocKitViewsTooltip['default']({\n rootElement: this.element,\n showForTag: 'a'\n }));\n }\n }, {\n key: 'registerKeyCommand',\n\n /**\n * @param {Object} keyCommand The key command to register. It must specify a\n * modifier key (meta, ctrl, etc), a string representing the ascii key, and\n * a `run` method that will be passed the editor instance when the key command\n * is invoked\n * @public\n */\n value: function registerKeyCommand(rawKeyCommand) {\n var keyCommand = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)(rawKeyCommand);\n (0, _mobiledocKitUtilsAssert['default'])('Key Command is not valid', (0, _mobiledocKitEditorKeyCommands.validateKeyCommand)(keyCommand));\n this.keyCommands.unshift(keyCommand);\n }\n\n /**\n * @param {String} name If the keyCommand event has a name attribute it can be removed.\n * @public\n */\n }, {\n key: 'unregisterKeyCommands',\n value: function unregisterKeyCommands(name) {\n for (var i = this.keyCommands.length - 1; i > -1; i--) {\n var keyCommand = this.keyCommands[i];\n\n if (keyCommand.name === name) {\n this.keyCommands.splice(i, 1);\n }\n }\n }\n\n /**\n * Convenience for {@link PostEditor#deleteAtPosition}. Deletes and puts the\n * cursor in the new position.\n * @public\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position, direction, _ref3) {\n var unit = _ref3.unit;\n\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteAtPosition(position, direction, { unit: unit });\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * Convenience for {@link PostEditor#deleteRange}. Deletes and puts the\n * cursor in the new position.\n * @param {Range} range\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * @private\n */\n }, {\n key: 'performDelete',\n value: function performDelete() {\n var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? { direction: _mobiledocKitUtilsKey.DIRECTION.BACKWARD, unit: 'char' } : arguments[0];\n\n var direction = _ref4.direction;\n var unit = _ref4.unit;\n var range = this.range;\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_DELETE, [range, direction, unit]);\n if (range.isCollapsed) {\n this.deleteAtPosition(range.head, direction, { unit: unit });\n } else {\n this.deleteRange(range);\n }\n this.runCallbacks(CALLBACK_QUEUES.DID_DELETE, [range, direction, unit]);\n }\n }, {\n key: 'handleNewline',\n value: function handleNewline(event) {\n var _this3 = this;\n\n if (!this.hasCursor()) {\n return;\n }\n\n event.preventDefault();\n\n var range = this.range;\n\n this.run(function (postEditor) {\n var cursorSection = undefined;\n if (!range.isCollapsed) {\n var nextPosition = postEditor.deleteRange(range);\n cursorSection = nextPosition.section;\n if (cursorSection && cursorSection.isBlank) {\n postEditor.setRange(cursorSection.headPosition());\n return;\n }\n }\n\n // Above logic might delete redundant range, so callback must run after it.\n var defaultPrevented = false;\n var event = { preventDefault: function preventDefault() {\n defaultPrevented = true;\n } };\n _this3.runCallbacks(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, [event]);\n if (defaultPrevented) {\n return;\n }\n\n cursorSection = postEditor.splitSection(range.head)[1];\n postEditor.setRange(cursorSection.headPosition());\n });\n }\n\n /**\n * Notify the editor that the post did change, and run associated\n * callbacks.\n * @private\n */\n }, {\n key: '_postDidChange',\n value: function _postDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.POST_DID_CHANGE);\n }\n\n /**\n * Selects the given range or position. If given a collapsed range or a position, this positions the cursor\n * at the range's position. Otherwise a selection is created in the editor\n * surface encompassing the range.\n * @param {Range|Position} range\n */\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n this.cursor.selectRange(range);\n this.range = range;\n }\n }, {\n key: '_readRangeFromDOM',\n value: function _readRangeFromDOM() {\n this.range = this.cursor.offsets;\n }\n }, {\n key: 'setPlaceholder',\n value: function setPlaceholder(placeholder) {\n (0, _mobiledocKitUtilsElementUtils.setData)(this.element, 'placeholder', placeholder);\n }\n }, {\n key: '_reparsePost',\n value: function _reparsePost() {\n var post = this._parser.parse(this.element);\n this.run(function (postEditor) {\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(post);\n postEditor.setRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n });\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n }, {\n key: '_reparseSections',\n value: function _reparseSections() {\n var _this4 = this;\n\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var currentRange = undefined;\n sections.forEach(function (section) {\n _this4._parser.reparseSection(section, _this4._renderTree);\n });\n this._removeDetachedSections();\n\n if (this._renderTree.isDirty) {\n currentRange = this.range;\n }\n\n // force the current snapshot's range to remain the same rather than\n // rereading it from DOM after the new character is applied and the browser\n // updates the cursor position\n var range = this._editHistory._pendingSnapshot.range;\n this.run(function () {\n _this4._editHistory._pendingSnapshot.range = range;\n });\n this.rerender();\n if (currentRange) {\n this.selectRange(currentRange);\n }\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n\n // FIXME this should be able to be removed now -- if any sections are detached,\n // it's due to a bug in the code.\n }, {\n key: '_removeDetachedSections',\n value: function _removeDetachedSections() {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.post.sections, function (s) {\n return !s.renderNode.isAttached();\n }), function (s) {\n return s.renderNode.scheduleForRemoval();\n });\n }\n\n /**\n * The sections from the cursor's selection start to the selection end\n * @type {Section[]}\n */\n }, {\n key: 'detectMarkupInRange',\n value: function detectMarkupInRange(range, markupTagName) {\n var markups = this.post.markupsInRange(range);\n return (0, _mobiledocKitUtilsArrayUtils.detect)(markups, function (markup) {\n return markup.hasTag(markupTagName);\n });\n }\n\n /**\n * @type {Markup[]}\n * @public\n */\n }, {\n key: 'hasActiveMarkup',\n\n /**\n * @param {Markup|String} markup A markup instance, or a string (e.g. \"b\")\n * @return {boolean}\n */\n value: function hasActiveMarkup(markup) {\n var matchesFn = undefined;\n if (typeof markup === 'string') {\n (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(markup);\n matchesFn = function (m) {\n return m.tagName === tagName;\n };\n })();\n } else {\n matchesFn = function (m) {\n return m === markup;\n };\n }\n\n return !!(0, _mobiledocKitUtilsArrayUtils.detect)(this.activeMarkups, matchesFn);\n }\n\n /**\n * @param {String} version The mobiledoc version to serialize to.\n * @return {Mobiledoc} Serialized mobiledoc\n * @public\n */\n }, {\n key: 'serialize',\n value: function serialize() {\n var version = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION : arguments[0];\n\n return this.serializePost(this.post, 'mobiledoc', { version: version });\n }\n\n /**\n * Serialize the editor's post to the requested format.\n * Note that only mobiledoc format is lossless. If cards or atoms are present\n * in the post, the html and text formats will omit them in output because\n * the editor does not have access to the html and text versions of the\n * cards/atoms.\n * @param {string} format The format to serialize ('mobiledoc', 'text', 'html')\n * @return {Object|String} The editor's post, serialized to {format}\n * @public\n */\n }, {\n key: 'serializeTo',\n value: function serializeTo(format) {\n var post = this.post;\n return this.serializePost(post, format);\n }\n\n /**\n * @param {Post}\n * @param {String} format Same as {serializeTo}\n * @param {Object} [options]\n * @param {String} [options.version=MOBILEDOC_VERSION] version to serialize to\n * @return {Object|String}\n * @private\n */\n }, {\n key: 'serializePost',\n value: function serializePost(post, format) {\n var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var validFormats = ['mobiledoc', 'html', 'text'];\n (0, _mobiledocKitUtilsAssert['default'])('Unrecognized serialization format ' + format, (0, _mobiledocKitUtilsArrayUtils.contains)(validFormats, format));\n\n if (format === 'mobiledoc') {\n var version = options.version || _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n return _mobiledocKitRenderersMobiledoc['default'].render(post, version);\n } else {\n var rendered = undefined;\n var mobiledoc = this.serializePost(post, 'mobiledoc');\n var unknownCardHandler = function unknownCardHandler() {};\n var unknownAtomHandler = function unknownAtomHandler() {};\n var rendererOptions = { unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n\n switch (format) {\n case 'html':\n var result = undefined;\n if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) {\n rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc);\n result = '
    ' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
    ';\n } else {\n // Fallback to text serialization\n result = this.serializePost(post, 'text', options);\n }\n return result;\n case 'text':\n rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc);\n return rendered.result;\n }\n }\n }\n }, {\n key: 'addView',\n value: function addView(view) {\n this._views.push(view);\n }\n }, {\n key: 'removeAllViews',\n value: function removeAllViews() {\n this._views.forEach(function (v) {\n return v.destroy();\n });\n this._views = [];\n }\n\n /**\n * Whether the editor has a cursor (or a selected range).\n * It is possible for the editor to be focused but not have a selection.\n * In this case, key events will fire but the editor will not be able to\n * determine a cursor position, so they will be ignored.\n * @return {boolean}\n * @public\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.cursor.hasCursor();\n }\n\n /**\n * Tears down the editor's attached event listeners and views.\n * @public\n */\n }, {\n key: 'destroy',\n value: function destroy() {\n this.isDestroyed = true;\n if (this._hasSelection()) {\n this.cursor.clearSelection();\n }\n if (this._hasFocus()) {\n this.element.blur(); // FIXME This doesn't blur the element on IE11\n }\n this._mutationHandler.destroy();\n this._eventManager.destroy();\n this.removeAllViews();\n this._renderer.destroy();\n this._editState.destroy();\n }\n\n /**\n * Keep the user from directly editing the post using the keyboard and mouse.\n * Modification via the programmatic API is still permitted.\n * @see Editor#enableEditing\n * @public\n */\n }, {\n key: 'disableEditing',\n value: function disableEditing() {\n if (this.isEditable === false) {\n return;\n }\n\n this.isEditable = false;\n if (this.hasRendered) {\n this.element.setAttribute('contentEditable', false);\n this.setPlaceholder('');\n this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n }\n }\n\n /**\n * Allow the user to directly interact with editing a post via keyboard and mouse input.\n * Editor instances are editable by default. Use this method to re-enable\n * editing after disabling it.\n * @see Editor#disableEditing\n * @public\n */\n }, {\n key: 'enableEditing',\n value: function enableEditing() {\n this.isEditable = true;\n if (this.element) {\n this.element.setAttribute('contentEditable', true);\n this.setPlaceholder(this.placeholder);\n }\n }\n\n /**\n * Change a cardSection into edit mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in edit mode when it gets rendered.\n * @param {CardSection} cardSection\n * @public\n */\n }, {\n key: 'editCard',\n value: function editCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.EDIT);\n }\n\n /**\n * Change a cardSection into display mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in display mode when it gets rendered.\n * @param {CardSection} cardSection\n * @return undefined\n * @public\n */\n }, {\n key: 'displayCard',\n value: function displayCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.DISPLAY);\n }\n\n /**\n * Run a new post editing session. Yields a block with a new {@link PostEditor}\n * instance. This instance can be used to interact with the post abstract.\n * Rendering will be deferred until after the callback is completed.\n *\n * Usage:\n * ```\n * let markerRange = this.range;\n * editor.run((postEditor) => {\n * postEditor.deleteRange(markerRange);\n * // editing surface not updated yet\n * postEditor.schedule(() => {\n * console.log('logs during rerender flush');\n * });\n * // logging not yet flushed\n * });\n * // editing surface now updated.\n * // logging now flushed\n * ```\n *\n * @param {Function} callback Called with an instance of\n * {@link PostEditor} as its argument.\n * @return {Mixed} The return value of `callback`.\n * @public\n */\n }, {\n key: 'run',\n value: function run(callback) {\n var postEditor = new _mobiledocKitEditorPost['default'](this);\n postEditor.begin();\n this._editHistory.snapshot();\n var result = callback(postEditor);\n this.runCallbacks(CALLBACK_QUEUES.DID_UPDATE, [postEditor]);\n postEditor.complete();\n this._readRangeFromDOM();\n\n if (postEditor._shouldCancelSnapshot) {\n this._editHistory._pendingSnapshot = null;\n }\n this._editHistory.storeSnapshot(postEditor.editActionTaken);\n\n return result;\n }\n\n /**\n * @param {Function} callback Called with `postEditor` as its argument.\n * @public\n */\n }, {\n key: 'didUpdatePost',\n value: function didUpdatePost(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_UPDATE, callback);\n }\n\n /**\n * @param {Function} callback Called when the post has changed, either via\n * user input or programmatically. Use with {@link Editor#serialize} to\n * retrieve the post in portable mobiledoc format.\n */\n }, {\n key: 'postDidChange',\n value: function postDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.POST_DID_CHANGE, callback);\n }\n\n /**\n * Register a handler that will be invoked by the editor after the user enters\n * matching text.\n * @param {Object} inputHandler\n * @param {String} inputHandler.name Required. Used by identifying handlers.\n * @param {String} [inputHandler.text] Required if `match` is not provided\n * @param {RegExp} [inputHandler.match] Required if `text` is not provided\n * @param {Function} inputHandler.run This callback is invoked with the {@link Editor}\n * instance and an array of matches. If `text` was provided,\n * the matches array will equal [`text`], and if a `match`\n * regex was provided the matches array will be the result of\n * `match.exec` on the matching text. The callback is called\n * after the matching text has been inserted.\n * @public\n */\n }, {\n key: 'onTextInput',\n value: function onTextInput(inputHandler) {\n this._eventManager.registerInputHandler(inputHandler);\n }\n\n /**\n * Unregister all text input handlers\n *\n * @public\n */\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._eventManager.unregisterAllTextInputHandlers();\n }\n\n /**\n * Unregister text input handler by name\n * @param {String} name The name of handler to be removed\n *\n * @public\n */\n }, {\n key: 'unregisterTextInputHandler',\n value: function unregisterTextInputHandler(name) {\n this._eventManager.unregisterInputHandler(name);\n }\n\n /**\n * @param {Function} callback Called when the editor's state (active markups or\n * active sections) has changed, either via user input or programmatically\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'willRender',\n value: function willRender(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'didRender',\n value: function didRender(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before deleting.\n * @public\n */\n }, {\n key: 'willDelete',\n value: function willDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after deleting.\n * @public\n */\n }, {\n key: 'didDelete',\n value: function didDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before handling new line.\n * @public\n */\n }, {\n key: 'willHandleNewline',\n value: function willHandleNewline(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called every time the cursor\n * position (or selection) changes.\n * @public\n */\n }, {\n key: 'cursorDidChange',\n value: function cursorDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.CURSOR_DID_CHANGE, callback);\n }\n }, {\n key: '_rangeDidChange',\n value: function _rangeDidChange() {\n if (this.hasRendered) {\n this.runCallbacks(CALLBACK_QUEUES.CURSOR_DID_CHANGE);\n }\n }\n }, {\n key: '_inputModeDidChange',\n value: function _inputModeDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE);\n }\n }, {\n key: '_insertEmptyMarkupSectionAtCursor',\n value: function _insertEmptyMarkupSectionAtCursor() {\n var _this5 = this;\n\n this.run(function (postEditor) {\n var section = postEditor.builder.createMarkupSection('p');\n postEditor.insertSectionBefore(_this5.post.sections, section);\n postEditor.setRange(section.toRange());\n });\n }\n\n /**\n * Toggles the given markup at the editor's current {@link Range}.\n * If the range is collapsed this changes the editor's state so that the\n * next characters typed will be affected. If there is text selected\n * (aka a non-collapsed range), the selections' markup will be toggled.\n * If the editor is not focused and has no active range, nothing happens.\n * @param {String} markup E.g. \"b\", \"em\", \"a\"\n * @public\n * @see PostEditor#toggleMarkup\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markup) {\n markup = this.builder.createMarkup(markup);\n var range = this.range;\n\n if (range.isCollapsed) {\n this._editState.toggleMarkupState(markup);\n this._inputModeDidChange();\n\n // when clicking a button to toggle markup, the button can end up being focused,\n // so ensure the editor is focused\n this._ensureFocus();\n } else {\n this.run(function (postEditor) {\n return postEditor.toggleMarkup(markup, range);\n });\n }\n }\n\n // If the editor has a selection but is not focused, focus it\n }, {\n key: '_ensureFocus',\n value: function _ensureFocus() {\n if (this._hasSelection() && !this._hasFocus()) {\n this.focus();\n }\n }\n }, {\n key: 'focus',\n value: function focus() {\n this.element.focus();\n }\n\n /**\n * Whether there is a selection inside the editor's element.\n * It's possible to have a selection but not have focus.\n * @see #_hasFocus\n * @return {Boolean}\n */\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var cursor = this.cursor;\n\n return this.hasRendered && (cursor._hasCollapsedSelection() || cursor._hasSelection());\n }\n\n /**\n * Whether the editor's element is focused\n * It's possible to be focused but have no selection\n * @see #_hasSelection\n * @return {Boolean}\n */\n }, {\n key: '_hasFocus',\n value: function _hasFocus() {\n return document.activeElement === this.element;\n }\n\n /**\n * Toggles the tagName for the current active section(s). This will skip\n * non-markerable sections. E.g. if the editor's range includes a \"P\" MarkupSection\n * and a CardSection, only the MarkupSection will be toggled.\n * @param {String} tagName The new tagname to change to.\n * @public\n * @see PostEditor#toggleSection\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(tagName) {\n var _this6 = this;\n\n this.run(function (postEditor) {\n return postEditor.toggleSection(tagName, _this6.range);\n });\n }\n\n /**\n * Finds and runs the first matching key command for the event\n *\n * If multiple commands are bound to a key combination, the\n * first matching one is run.\n *\n * If a command returns `false` then the next matching command\n * is run instead.\n *\n * @param {Event} event The keyboard event triggered by the user\n * @return {Boolean} true when a command was successfully run\n * @private\n */\n }, {\n key: 'handleKeyCommand',\n value: function handleKeyCommand(event) {\n var keyCommands = (0, _mobiledocKitEditorKeyCommands.findKeyCommands)(this.keyCommands, event);\n for (var i = 0; i < keyCommands.length; i++) {\n var keyCommand = keyCommands[i];\n if (keyCommand.run(this) !== false) {\n event.preventDefault();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Inserts the text at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n *\n * @param {String} text\n * @public\n */\n }, {\n key: 'insertText',\n value: function insertText(text) {\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n var activeMarkups = this.activeMarkups;\n var range = this.range;\n var position = this.range.head;\n\n this.run(function (postEditor) {\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertTextWithMarkup(position, text, activeMarkups);\n });\n }\n\n /**\n * Inserts an atom at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n * @param {String} atomName\n * @param {String} [atomText='']\n * @param {Object} [atomPayload={}]\n * @return {Atom} The inserted atom.\n * @public\n */\n }, {\n key: 'insertAtom',\n value: function insertAtom(atomName) {\n var atomText = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var atomPayload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var atom = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.head;\n\n atom = postEditor.builder.createAtom(atomName, atomText, atomPayload);\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertMarkers(position, [atom]);\n });\n return atom;\n }\n\n /**\n * Inserts a card at the section after the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion. If the cursor is in\n * a blank section, it will be replaced with a card section.\n * The editor's cursor will be placed at the end of the inserted card.\n * @param {String} cardName\n * @param {Object} [cardPayload={}]\n * @param {Boolean} [inEditMode=false] Whether the card should be inserted in edit mode.\n * @return {Card} The inserted Card section.\n * @public\n */\n }, {\n key: 'insertCard',\n value: function insertCard(cardName) {\n var _this7 = this;\n\n var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var card = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.tail;\n card = postEditor.builder.createCardSection(cardName, cardPayload);\n if (inEditMode) {\n _this7.editCard(card);\n }\n\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n var section = position.section;\n if (section.isNested) {\n section = section.parent;\n }\n\n if (section.isBlank) {\n postEditor.replaceSection(section, card);\n } else {\n var collection = _this7.post.sections;\n postEditor.insertSectionBefore(collection, card, section.next);\n }\n\n // It is important to explicitly set the range to the end of the card.\n // Otherwise it is possible to create an inconsistent state in the\n // browser. For instance, if the user clicked a button that\n // called `editor.insertCard`, the editor surface may retain\n // the selection but lose focus, and the next keystroke by the user\n // will cause an unexpected DOM mutation (which can wipe out the\n // card).\n // See: https://github.com/bustle/mobiledoc-kit/issues/286\n postEditor.setRange(card.tailPosition());\n });\n return card;\n }\n\n /**\n * @param {integer} x x-position in viewport\n * @param {integer} y y-position in viewport\n * @return {Position|null}\n */\n }, {\n key: 'positionAtPoint',\n value: function positionAtPoint(x, y) {\n return _mobiledocKitUtilsCursorPosition['default'].atPoint(x, y, this);\n }\n\n /**\n * @private\n */\n }, {\n key: '_setCardMode',\n value: function _setCardMode(cardSection, mode) {\n var renderNode = cardSection.renderNode;\n if (renderNode && renderNode.isRendered) {\n var cardNode = renderNode.cardNode;\n cardNode[mode]();\n } else {\n cardSection.setInitialMode(mode);\n }\n }\n }, {\n key: 'triggerEvent',\n value: function triggerEvent(context, eventName, event) {\n this._eventManager._trigger(context, eventName, event);\n }\n }, {\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n if (this.isDestroyed) {\n // TODO warn that callback attempted after editor was destroyed\n return;\n }\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n }, {\n key: 'builder',\n get: function get() {\n if (!this._builder) {\n this._builder = new _mobiledocKitModelsPostNodeBuilder['default']();\n }\n return this._builder;\n }\n }, {\n key: 'keyCommands',\n get: function get() {\n if (!this._keyCommands) {\n this._keyCommands = [];\n }\n return this._keyCommands;\n }\n }, {\n key: 'cursor',\n get: function get() {\n return new _mobiledocKitUtilsCursor['default'](this);\n }\n\n /**\n * Return the current range for the editor (may be cached).\n * @return {Range}\n */\n }, {\n key: 'range',\n get: function get() {\n return this._editState.range;\n },\n set: function set(newRange) {\n this._editState.updateRange(newRange);\n\n if (this._editState.rangeDidChange()) {\n this._rangeDidChange();\n }\n\n if (this._editState.inputModeDidChange()) {\n this._inputModeDidChange();\n }\n }\n }, {\n key: 'activeSections',\n get: function get() {\n return this._editState.activeSections;\n }\n }, {\n key: 'activeSection',\n get: function get() {\n var activeSections = this.activeSections;\n\n return activeSections[activeSections.length - 1];\n }\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this._editState.activeMarkups;\n }\n }]);\n\n return Editor;\n })();\n\n exports['default'] = Editor;\n});","define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/parse-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/editor/text-input-handler', 'mobiledoc-kit/editor/selection-manager', 'mobiledoc-kit/utils/browser'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitUtilsParseUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitEditorTextInputHandler, _mobiledocKitEditorSelectionManager, _mobiledocKitUtilsBrowser) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var ELEMENT_EVENT_TYPES = ['keydown', 'keyup', 'cut', 'copy', 'paste', 'keypress', 'drop'];\n\n var EventManager = (function () {\n function EventManager(editor) {\n _classCallCheck(this, EventManager);\n\n this.editor = editor;\n this.logger = editor.loggerFor('event-manager');\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor);\n this._listeners = [];\n this.modifierKeys = {\n shift: false,\n alt: false,\n ctrl: false\n };\n\n this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this));\n }\n\n _createClass(EventManager, [{\n key: 'init',\n value: function init() {\n var _this = this;\n\n var element = this.editor.element;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot init EventManager without element', !!element);\n\n ELEMENT_EVENT_TYPES.forEach(function (type) {\n _this._addListener(element, type);\n });\n\n this._selectionManager.start();\n }\n }, {\n key: 'registerInputHandler',\n value: function registerInputHandler(inputHandler) {\n this._textInputHandler.register(inputHandler);\n }\n }, {\n key: 'unregisterInputHandler',\n value: function unregisterInputHandler(name) {\n this._textInputHandler.unregister(name);\n }\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._textInputHandler.destroy();\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](this.editor);\n }\n }, {\n key: '_addListener',\n value: function _addListener(context, type) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Missing listener for ' + type, !!this[type]);\n\n var listener = function listener(event) {\n return _this2._handleEvent(type, event);\n };\n context.addEventListener(type, listener);\n this._listeners.push([context, type, listener]);\n }\n }, {\n key: '_removeListeners',\n value: function _removeListeners() {\n this._listeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var context = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n context.removeEventListener(type, listener);\n });\n this._listeners = [];\n }\n\n // This is primarily useful for programmatically simulating events on the\n // editor from the tests.\n }, {\n key: '_trigger',\n value: function _trigger(context, type, event) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this._listeners, function (_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var _context = _ref32[0];\n var _type = _ref32[1];\n\n return _context === context && _type === type;\n }), function (_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var context = _ref42[0];\n var type = _ref42[1];\n var listener = _ref42[2];\n\n listener.call(context, event);\n });\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._textInputHandler.destroy();\n this._selectionManager.destroy();\n this._removeListeners();\n }\n }, {\n key: '_handleEvent',\n value: function _handleEvent(type, event) {\n var element = event.target;\n\n if (!this.isElementAddressable(element)) {\n // abort handling this event\n return true;\n }\n\n this[type](event);\n }\n }, {\n key: 'isElementAddressable',\n value: function isElementAddressable(element) {\n return this.editor.cursor.isAddressable(element);\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange(selection /*, prevSelection */) {\n var shouldNotify = true;\n var anchorNode = selection.anchorNode;\n\n if (!this.isElementAddressable(anchorNode)) {\n if (!this.editor.range.isBlank) {\n // Selection changed from something addressable to something\n // not-addressable -- e.g., blur event, user clicked outside editor,\n // etc\n shouldNotify = true;\n } else {\n // selection changes wholly outside the editor should not trigger\n // change notifications\n shouldNotify = false;\n }\n }\n\n if (shouldNotify) {\n this.editor._readRangeFromDOM();\n }\n }\n }, {\n key: 'keypress',\n value: function keypress(event) {\n var editor = this.editor;\n var _textInputHandler = this._textInputHandler;\n\n if (!editor.hasCursor()) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n if (!key.isPrintable()) {\n return;\n } else {\n event.preventDefault();\n }\n\n _textInputHandler.handle(key.toString());\n }\n }, {\n key: 'keydown',\n value: function keydown(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n if (!editor.isEditable) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: true });\n\n if (editor.handleKeyCommand(event)) {\n return;\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var range = editor.range;\n\n switch (true) {\n // FIXME This should be restricted to only card/atom boundaries\n case key.isHorizontalArrowWithoutModifiersOtherThanShift():\n var newRange = undefined;\n if (key.isShift()) {\n newRange = range.extend(key.direction * 1);\n } else {\n newRange = range.move(key.direction);\n }\n\n editor.selectRange(newRange);\n event.preventDefault();\n break;\n case key.isDelete():\n var direction = key.direction;\n\n var unit = 'char';\n if (this.modifierKeys.alt && _mobiledocKitUtilsBrowser['default'].isMac()) {\n unit = 'word';\n } else if (this.modifierKeys.ctrl && _mobiledocKitUtilsBrowser['default'].isWin()) {\n unit = 'word';\n }\n editor.performDelete({ direction: direction, unit: unit });\n event.preventDefault();\n break;\n case key.isEnter():\n editor.handleNewline(event);\n break;\n case key.isTab():\n // Handle tab here because it does not fire a `keypress` event\n event.preventDefault();\n this._textInputHandler.handle(key.toString());\n break;\n }\n }\n }, {\n key: 'keyup',\n value: function keyup(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: false });\n }\n }, {\n key: 'cut',\n value: function cut(event) {\n event.preventDefault();\n\n this.copy(event);\n this.editor.performDelete();\n }\n }, {\n key: 'copy',\n value: function copy(event) {\n event.preventDefault();\n\n var editor = this.editor;\n var _editor = this.editor;\n var range = _editor.range;\n var post = _editor.post;\n\n post = post.trimTo(range);\n\n var data = {\n html: editor.serializePost(post, 'html'),\n text: editor.serializePost(post, 'text'),\n mobiledoc: editor.serializePost(post, 'mobiledoc')\n };\n\n (0, _mobiledocKitUtilsParseUtils.setClipboardData)(event, data, window);\n }\n }, {\n key: 'paste',\n value: function paste(event) {\n event.preventDefault();\n\n var editor = this.editor;\n\n var range = editor.range;\n\n if (!range.isCollapsed) {\n editor.performDelete();\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var position = editor.range.head;\n var targetFormat = this.modifierKeys.shift ? 'text' : 'html';\n var pastedPost = (0, _mobiledocKitUtilsParseUtils.parsePostFromPaste)(event, editor, { targetFormat: targetFormat });\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, pastedPost);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: 'drop',\n value: function drop(event) {\n event.preventDefault();\n\n var x = event.clientX;\n var y = event.clientY;\n var editor = this.editor;\n\n var position = editor.positionAtPoint(x, y);\n if (!position) {\n this.logger.log('Could not find drop position');\n return;\n }\n\n var post = (0, _mobiledocKitUtilsParseUtils.parsePostFromDrop)(event, editor, { logger: this.logger });\n if (!post) {\n this.logger.log('Could not determine post from drop event');\n return;\n }\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, post);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: '_updateModifiersFromKey',\n value: function _updateModifiersFromKey(key, _ref5) {\n var isDown = _ref5.isDown;\n\n if (key.isShiftKey()) {\n this.modifierKeys.shift = isDown;\n } else if (key.isAltKey()) {\n this.modifierKeys.alt = isDown;\n } else if (key.isCtrlKey()) {\n this.modifierKeys.ctrl = isDown;\n }\n }\n }]);\n\n return EventManager;\n })();\n\n exports['default'] = EventManager;\n});","define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/browser', 'mobiledoc-kit/editor/ui'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsBrowser, _mobiledocKitEditorUi) {\n 'use strict';\n\n exports.buildKeyCommand = buildKeyCommand;\n exports.validateKeyCommand = validateKeyCommand;\n exports.findKeyCommands = findKeyCommands;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function selectAll(editor) {\n var post = editor.post;\n\n editor.selectRange(post.toRange());\n }\n\n function gotoStartOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.headPosition());\n });\n }\n\n function gotoEndOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.tailPosition());\n });\n }\n\n function deleteToEndOfSection(editor) {\n var range = editor.range;\n\n if (range.isCollapsed) {\n var _range = range;\n var head = _range.head;\n var section = _range.head.section;\n\n range = head.toRange(section.tailPosition());\n }\n editor.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n var DEFAULT_KEY_COMMANDS = [{\n str: 'META+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'CTRL+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'META+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'CTRL+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'META+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+K',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return deleteToEndOfSection(editor);\n } else if (_mobiledocKitUtilsBrowser['default'].isWin()) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n }\n }, {\n str: 'CTRL+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoStartOfLine(editor);\n } else {\n selectAll(editor);\n }\n }\n }, {\n str: 'META+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n selectAll(editor);\n }\n }\n }, {\n str: 'CTRL+E',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoEndOfLine(editor);\n }\n }\n }, {\n str: 'META+K',\n run: function run(editor) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n\n }, {\n str: 'META+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.undoLastChange();\n });\n }\n }, {\n str: 'META+SHIFT+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.redoLastChange();\n });\n }\n }, {\n str: 'CTRL+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.undoLastChange();\n });\n }\n }, {\n str: 'CTRL+SHIFT+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.redoLastChange();\n });\n }\n }];\n\n exports.DEFAULT_KEY_COMMANDS = DEFAULT_KEY_COMMANDS;\n function modifierNamesToMask(modiferNames) {\n var defaultVal = 0;\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(modiferNames, function (sum, name) {\n var modifier = _mobiledocKitUtilsKey.MODIFIERS[name.toUpperCase()];\n (0, _mobiledocKitUtilsAssert['default'])('No modifier named \"' + name + '\" found', !!modifier);\n return sum + modifier;\n }, defaultVal);\n }\n\n function characterToCode(character) {\n var upperCharacter = character.toUpperCase();\n var special = _mobiledocKitUtilsKey.SPECIAL_KEYS[upperCharacter];\n if (special) {\n return special;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Only 1 character can be used in a key command str (got \"' + character + '\")', character.length === 1);\n return upperCharacter.charCodeAt(0);\n }\n }\n\n function buildKeyCommand(keyCommand) {\n var str = keyCommand.str;\n\n if (!str) {\n return keyCommand;\n }\n (0, _mobiledocKitUtilsAssert['default'])('[deprecation] Key commands no longer use the `modifier` property', !keyCommand.modifier);\n\n var _str$split$reverse = str.split('+').reverse();\n\n var _str$split$reverse2 = _toArray(_str$split$reverse);\n\n var character = _str$split$reverse2[0];\n\n var modifierNames = _str$split$reverse2.slice(1);\n\n keyCommand.modifierMask = modifierNamesToMask(modifierNames);\n keyCommand.code = characterToCode(character);\n\n return keyCommand;\n }\n\n function validateKeyCommand(keyCommand) {\n return !!keyCommand.code && !!keyCommand.run;\n }\n\n function findKeyCommands(keyCommands, keyEvent) {\n var key = _mobiledocKitUtilsKey['default'].fromEvent(keyEvent);\n\n return (0, _mobiledocKitUtilsArrayUtils.filter)(keyCommands, function (_ref) {\n var modifierMask = _ref.modifierMask;\n var code = _ref.code;\n\n return key.keyCode === code && key.modifierMask === modifierMask;\n });\n }\n});","define('mobiledoc-kit/editor/mutation-handler', ['exports', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsSet, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MUTATION = {\n NODES_CHANGED: 'childList',\n CHARACTER_DATA: 'characterData'\n };\n\n var MutationHandler = (function () {\n function MutationHandler(editor) {\n var _this = this;\n\n _classCallCheck(this, MutationHandler);\n\n this.editor = editor;\n this.logger = editor.loggerFor('mutation-handler');\n this.renderTree = null;\n this._isObserving = false;\n\n this._observer = new MutationObserver(function (mutations) {\n _this._handleMutations(mutations);\n });\n }\n\n _createClass(MutationHandler, [{\n key: 'init',\n value: function init() {\n this.startObserving();\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stopObserving();\n this._observer = null;\n }\n }, {\n key: 'suspendObservation',\n value: function suspendObservation(callback) {\n this.stopObserving();\n callback();\n this.startObserving();\n }\n }, {\n key: 'stopObserving',\n value: function stopObserving() {\n if (this._isObserving) {\n this._isObserving = false;\n this._observer.disconnect();\n }\n }\n }, {\n key: 'startObserving',\n value: function startObserving() {\n if (!this._isObserving) {\n var editor = this.editor;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot observe un-rendered editor', editor.hasRendered);\n\n this._isObserving = true;\n this.renderTree = editor._renderTree;\n\n this._observer.observe(editor.element, {\n characterData: true,\n childList: true,\n subtree: true\n });\n }\n }\n }, {\n key: 'reparsePost',\n value: function reparsePost() {\n this.editor._reparsePost();\n }\n }, {\n key: 'reparseSections',\n value: function reparseSections(sections) {\n this.editor._reparseSections(sections);\n }\n\n /**\n * for each mutation:\n * * find the target nodes:\n * * if nodes changed, target nodes are:\n * * added nodes\n * * the target from which removed nodes were removed\n * * if character data changed\n * * target node is the mutation event's target (text node)\n * * filter out nodes that are no longer attached (parentNode is null)\n * * for each remaining node:\n * * find its section, add to sections-to-reparse\n * * if no section, reparse all (and break)\n */\n }, {\n key: '_handleMutations',\n value: function _handleMutations(mutations) {\n var reparsePost = false;\n var sections = new _mobiledocKitUtilsSet['default']();\n\n for (var i = 0; i < mutations.length; i++) {\n if (reparsePost) {\n break;\n }\n\n var nodes = this._findTargetNodes(mutations[i]);\n\n for (var j = 0; j < nodes.length; j++) {\n var node = nodes[j];\n var renderNode = this._findRenderNodeFromNode(node);\n if (renderNode) {\n if (renderNode.reparsesMutationOfChildNode(node)) {\n var section = this._findSectionFromRenderNode(renderNode);\n if (section) {\n sections.add(section);\n } else {\n reparsePost = true;\n }\n }\n } else {\n reparsePost = true;\n break;\n }\n }\n }\n\n if (reparsePost) {\n this.logger.log('reparsePost (' + mutations.length + ' mutations)');\n this.reparsePost();\n } else if (sections.length) {\n this.logger.log('reparse ' + sections.length + ' sections (' + mutations.length + ' mutations)');\n this.reparseSections(sections.toArray());\n }\n }\n }, {\n key: '_findTargetNodes',\n value: function _findTargetNodes(mutation) {\n var nodes = [];\n\n switch (mutation.type) {\n case MUTATION.CHARACTER_DATA:\n nodes.push(mutation.target);\n break;\n case MUTATION.NODES_CHANGED:\n (0, _mobiledocKitUtilsArrayUtils.forEach)(mutation.addedNodes, function (n) {\n return nodes.push(n);\n });\n if (mutation.removedNodes.length) {\n nodes.push(mutation.target);\n }\n break;\n }\n\n var element = this.editor.element;\n var attachedNodes = (0, _mobiledocKitUtilsArrayUtils.filter)(nodes, function (node) {\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, node);\n });\n return attachedNodes;\n }\n }, {\n key: '_findSectionRenderNodeFromNode',\n value: function _findSectionRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node, function (rn) {\n return rn.postNode.isSection;\n });\n }\n }, {\n key: '_findRenderNodeFromNode',\n value: function _findRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node);\n }\n }, {\n key: '_findSectionFromRenderNode',\n value: function _findSectionFromRenderNode(renderNode) {\n var sectionRenderNode = this._findSectionRenderNodeFromNode(renderNode.element);\n return sectionRenderNode && sectionRenderNode.postNode;\n }\n }]);\n\n return MutationHandler;\n })();\n\n exports['default'] = MutationHandler;\n});","define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/editor/post/post-inserter', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/to-range'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils, _mobiledocKitEditorPostPostInserter, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsToRange) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n function isListSectionTagName(tagName) {\n return tagName === 'ul' || tagName === 'ol';\n }\n\n var CALLBACK_QUEUES = {\n BEFORE_COMPLETE: 'beforeComplete',\n COMPLETE: 'complete',\n AFTER_COMPLETE: 'afterComplete'\n };\n\n // There are only two events that we're concerned about for Undo, that is inserting text and deleting content.\n // These are the only two states that go on a \"run\" and create a combined undo, everything else has it's own\n // deadicated undo.\n var EDIT_ACTIONS = {\n INSERT_TEXT: 1,\n DELETE: 2\n };\n\n /**\n * The PostEditor is used to modify a post. It should not be instantiated directly.\n * Instead, a new instance of a PostEditor is created by the editor and passed\n * as the argument to the callback in {@link Editor#run}.\n *\n * Usage:\n * ```\n * editor.run((postEditor) => {\n * // postEditor is an instance of PostEditor that can operate on the\n * // editor's post\n * });\n * ```\n */\n\n var PostEditor = (function () {\n /**\n * @private\n */\n\n function PostEditor(editor) {\n var _this = this;\n\n _classCallCheck(this, PostEditor);\n\n this.editor = editor;\n this.builder = this.editor.builder;\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n this._didComplete = false;\n this.editActionTaken = null;\n\n this._renderRange = function () {\n return _this.editor.selectRange(_this._range);\n };\n this._postDidChange = function () {\n return _this.editor._postDidChange();\n };\n this._rerender = function () {\n return _this.editor.rerender();\n };\n }\n\n _createClass(PostEditor, [{\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n }, {\n key: 'begin',\n value: function begin() {\n // cache the editor's range\n this._range = this.editor.range;\n }\n\n /**\n * Schedules to select the given range on the editor after the postEditor\n * has completed its work. This also updates the postEditor's active range\n * (so that multiple calls to range-changing methods on the postEditor will\n * update the correct range).\n *\n * Usage:\n * let range = editor.range;\n * editor.run(postEditor => {\n * let nextPosition = postEditor.deleteRange(range);\n *\n * // Will position the editor's cursor at `nextPosition` after\n * // the postEditor finishes work and the editor rerenders.\n * postEditor.setRange(nextPosition);\n * });\n * @param {Range|Position} range\n * @public\n */\n }, {\n key: 'setRange',\n value: function setRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n // TODO validate that the range is valid\n // (does not contain marked-for-removal head or tail sections?)\n this._range = range;\n this.scheduleAfterRender(this._renderRange, true);\n }\n\n /**\n * Delete a range from the post\n *\n * Usage:\n * ```\n * let { range } = editor;\n * editor.run((postEditor) => {\n * let nextPosition = postEditor.deleteRange(range);\n * postEditor.setRange(nextPosition);\n * });\n * ```\n * @param {Range} range Cursor Range object with head and tail Positions\n * @return {Position} The position where the cursor would go after deletion\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass MobiledocKit Range to `deleteRange`\", range instanceof _mobiledocKitUtilsCursorRange['default']);\n\n this.editActionTaken = EDIT_ACTIONS.DELETE;\n\n var head = range.head;\n var headSection = range.head.section;\n var tail = range.tail;\n var tailSection = range.tail.section;\n var post = this.editor.post;\n\n if (headSection === tailSection) {\n return this.cutSection(headSection, head, tail);\n }\n\n var nextSection = headSection.nextLeafSection();\n\n var nextPos = this.cutSection(headSection, head, headSection.tailPosition());\n // cutSection can replace the section, so re-read headSection here\n headSection = nextPos.section;\n\n // Remove sections in the middle of the range\n while (nextSection !== tailSection) {\n var tmp = nextSection;\n nextSection = nextSection.nextLeafSection();\n this.removeSection(tmp);\n }\n\n var tailPos = this.cutSection(tailSection, tailSection.headPosition(), tail);\n // cutSection can replace the section, so re-read tailSection here\n tailSection = tailPos.section;\n\n if (tailSection.isBlank) {\n this.removeSection(tailSection);\n } else {\n // If head and tail sections are markerable, join them\n // Note: They may not be the same section type. E.g. this may join\n // a tail section that was a list item onto a markup section, or vice versa.\n // (This is the desired behavior.)\n if (headSection.isMarkerable && tailSection.isMarkerable) {\n headSection.join(tailSection);\n this._markDirty(headSection);\n this.removeSection(tailSection);\n } else if (headSection.isBlank) {\n this.removeSection(headSection);\n nextPos = tailPos;\n }\n }\n\n if (post.isBlank) {\n post.sections.append(this.builder.createMarkupSection('p'));\n nextPos = post.headPosition();\n }\n\n return nextPos;\n }\n\n /**\n * Note: This method may replace `section` with a different section.\n *\n * \"Cut\" out the part of the section inside `headOffset` and `tailOffset`.\n * If section is markerable this splits markers that straddle the head or tail (if necessary),\n * and removes markers that are wholly inside the offsets.\n * If section is a card, this may replace it with a blank markup section if the\n * positions contain the entire card.\n *\n * @param {Section} section\n * @param {Position} head\n * @param {Position} tail\n * @return {Position}\n * @private\n */\n }, {\n key: 'cutSection',\n value: function cutSection(section, head, tail) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass head position and tail position to `cutSection`', head instanceof _mobiledocKitUtilsCursorPosition['default'] && tail instanceof _mobiledocKitUtilsCursorPosition['default']);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass positions within same section to `cutSection`', head.section === tail.section);\n\n if (section.isBlank || head.isEqual(tail)) {\n return head;\n }\n if (section.isCardSection) {\n if (head.isHead() && tail.isTail()) {\n var newSection = this.builder.createMarkupSection();\n this.replaceSection(section, newSection);\n return newSection.headPosition();\n } else {\n return tail;\n }\n }\n\n var range = head.toRange(tail);\n this.splitMarkers(range).forEach(function (m) {\n return _this2.removeMarker(m);\n });\n\n return head;\n }\n }, {\n key: '_coalesceMarkers',\n value: function _coalesceMarkers(section) {\n if (section.isMarkerable) {\n this._removeBlankMarkers(section);\n this._joinSimilarMarkers(section);\n }\n }\n }, {\n key: '_removeBlankMarkers',\n value: function _removeBlankMarkers(section) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }), function (m) {\n return _this3.removeMarker(m);\n });\n }\n\n // joins markers that have identical markups\n }, {\n key: '_joinSimilarMarkers',\n value: function _joinSimilarMarkers(section) {\n var marker = section.markers.head;\n var nextMarker = undefined;\n while (marker && marker.next) {\n nextMarker = marker.next;\n\n if (marker.canJoin(nextMarker)) {\n nextMarker.value = marker.value + nextMarker.value;\n this._markDirty(nextMarker);\n this.removeMarker(marker);\n }\n\n marker = nextMarker;\n }\n }\n }, {\n key: 'removeMarker',\n value: function removeMarker(marker) {\n this._scheduleForRemoval(marker);\n if (marker.section) {\n this._markDirty(marker.section);\n marker.section.markers.remove(marker);\n }\n }\n }, {\n key: '_scheduleForRemoval',\n value: function _scheduleForRemoval(postNode) {\n var _this4 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.scheduleForRemoval();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n var removedAdjacentToList = postNode.prev && postNode.prev.isListSection || postNode.next && postNode.next.isListSection;\n if (removedAdjacentToList) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this4._joinContiguousListSections();\n });\n }\n }\n }, {\n key: '_joinContiguousListSections',\n value: function _joinContiguousListSections() {\n var _this5 = this;\n\n var post = this.editor.post;\n\n var range = this._range;\n var prev = undefined;\n var groups = [];\n var currentGroup = undefined;\n\n // FIXME do we need to force a re-render of the range if changed sections\n // are contained within the range?\n var updatedHead = null;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n if (prev && prev.isListSection && section.isListSection && prev.tagName === section.tagName) {\n\n currentGroup = currentGroup || [prev];\n currentGroup.push(section);\n } else {\n if (currentGroup) {\n groups.push(currentGroup);\n }\n currentGroup = null;\n }\n prev = section;\n });\n\n if (currentGroup) {\n groups.push(currentGroup);\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(groups, function (group) {\n var list = group[0];\n (0, _mobiledocKitUtilsArrayUtils.forEach)(group, function (listSection) {\n if (listSection === list) {\n return;\n }\n\n var currentHead = range.head;\n var prevPosition = undefined;\n\n // FIXME is there a currentHead if there is no range?\n // is the current head a list item in the section\n if (!range.isBlank && currentHead.section.isListItem && currentHead.section.parent === listSection) {\n prevPosition = list.tailPosition();\n }\n _this5._joinListSections(list, listSection);\n if (prevPosition) {\n updatedHead = prevPosition.move(FORWARD);\n }\n });\n });\n\n if (updatedHead) {\n this.setRange(updatedHead);\n }\n }\n }, {\n key: '_joinListSections',\n value: function _joinListSections(baseList, nextList) {\n baseList.join(nextList);\n this._markDirty(baseList);\n this.removeSection(nextList);\n }\n }, {\n key: '_markDirty',\n value: function _markDirty(postNode) {\n var _this6 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.markDirty();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n if (postNode.section) {\n this._markDirty(postNode.section);\n }\n if (postNode.isMarkerable) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this6._coalesceMarkers(postNode);\n });\n }\n }\n\n /**\n * @param {Position} position object with {section, offset} the marker and offset to delete from\n * @param {Number} direction The direction to delete in (default is BACKWARD)\n * @return {Position} for positioning the cursor\n * @public\n * @deprecated after v0.10.3\n */\n }, {\n key: 'deleteFrom',\n value: function deleteFrom(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n (0, _mobiledocKitUtilsDeprecate['default'])(\"`postEditor#deleteFrom is deprecated. Use `deleteAtPosition(position, direction=BACKWARD, {unit}={unit: 'char'})` instead\");\n return this.deleteAtPosition(position, direction, { unit: 'char' });\n }\n\n /**\n * Delete 1 `unit` (can be 'char' or 'word') in the given `direction` at the given\n * `position`. In almost all cases this will be equivalent to deleting the range formed\n * by expanding the position 1 unit in the given direction. The exception is when deleting\n * backward from the beginning of a list item, which reverts the list item into a markup section\n * instead of joining it with its previous list item (if any).\n *\n * Usage:\n *\n * let position = section.tailPosition();\n * // Section has text of \"Howdy!\"\n * editor.run((postEditor) => {\n * postEditor.deleteAtPosition(position);\n * });\n * // section has text of \"Howdy\"\n *\n * @param {Position} position The position to delete at\n * @param {Direction} [direction=DIRECTION.BACKWARD] direction The direction to delete in\n * @param {Object} [options]\n * @param {String} [options.unit=\"char\"] The unit of deletion (\"word\" or \"char\")\n * @return {Position}\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n var _ref = arguments.length <= 2 || arguments[2] === undefined ? { unit: 'char' } : arguments[2];\n\n var unit = _ref.unit;\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n return this._deleteAtPositionBackward(position, unit);\n } else {\n return this._deleteAtPositionForward(position, unit);\n }\n }\n }, {\n key: '_deleteAtPositionBackward',\n value: function _deleteAtPositionBackward(position, unit) {\n if (position.isHead() && position.section.isListItem) {\n this.toggleSection('p', position);\n return this._range.head;\n } else {\n var prevPosition = unit === 'word' ? position.moveWord(BACKWARD) : position.move(BACKWARD);\n var range = prevPosition.toRange(position);\n return this.deleteRange(range);\n }\n }\n }, {\n key: '_deleteAtPositionForward',\n value: function _deleteAtPositionForward(position, unit) {\n var nextPosition = unit === 'word' ? position.moveWord(FORWARD) : position.move(FORWARD);\n var range = position.toRange(nextPosition);\n return this.deleteRange(range);\n }\n\n /**\n * Split markers at two positions, once at the head, and if necessary once\n * at the tail.\n *\n * Usage:\n * ```\n * let range = editor.range;\n * editor.run((postEditor) => {\n * postEditor.splitMarkers(range);\n * });\n * ```\n * The return value will be marker object completely inside the offsets\n * provided. Markers outside of the split may also have been modified.\n *\n * @param {Range} markerRange\n * @return {Array} of markers that are inside the split\n * @private\n */\n }, {\n key: 'splitMarkers',\n value: function splitMarkers(range) {\n var post = this.editor.post;\n var head = range.head;\n var tail = range.tail;\n\n this.splitSectionMarkerAtOffset(head.section, head.offset);\n this.splitSectionMarkerAtOffset(tail.section, tail.offset);\n\n return post.markersContainedByRange(range);\n }\n }, {\n key: 'splitSectionMarkerAtOffset',\n value: function splitSectionMarkerAtOffset(section, offset) {\n var _this7 = this;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (m) {\n return _this7.removeMarker(m);\n });\n }\n\n /**\n * Split the section at the position.\n *\n * Usage:\n * ```\n * let position = editor.cursor.offsets.head;\n * editor.run((postEditor) => {\n * postEditor.splitSection(position);\n * });\n * // Will result in the creation of two new sections\n * // replacing the old one at the cursor position\n * ```\n * The return value will be the two new sections. One or both of these\n * sections can be blank (contain only a blank marker), for example if the\n * headMarkerOffset is 0.\n *\n * @param {Position} position\n * @return {Array} new sections, one for the first half and one for the second (either one can be null)\n * @public\n */\n }, {\n key: 'splitSection',\n value: function splitSection(position) {\n var _this8 = this;\n\n var section = position.section;\n\n if (section.isCardSection) {\n return this._splitCardSection(section, position);\n } else if (section.isListItem) {\n var isLastAndBlank = section.isBlank && !section.next;\n if (isLastAndBlank) {\n // if is last, replace the item with a blank markup section\n var _parent = section.parent;\n var collection = this.editor.post.sections;\n var blank = this.builder.createMarkupSection();\n this.removeSection(section);\n this.insertSectionBefore(collection, blank, _parent.next);\n\n return [null, blank];\n } else {\n var _splitListItem2 = this._splitListItem(section, position);\n\n var _splitListItem22 = _slicedToArray(_splitListItem2, 2);\n\n var pre = _splitListItem22[0];\n var post = _splitListItem22[1];\n\n return [pre, post];\n }\n } else {\n var splitSections = section.splitAtPosition(position);\n splitSections.forEach(function (s) {\n return _this8._coalesceMarkers(s);\n });\n this._replaceSection(section, splitSections);\n\n return splitSections;\n }\n }\n\n /**\n * @param {Section} cardSection\n * @param {Position} position to split at\n * @return {Section[]} 2-item array of pre and post-split sections\n * @private\n */\n }, {\n key: '_splitCardSection',\n value: function _splitCardSection(cardSection, position) {\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cards section must be split at offset 0 or 1', offset === 0 || offset === 1);\n\n var newSection = this.builder.createMarkupSection();\n var nextSection = undefined;\n var surroundingSections = undefined;\n\n if (offset === 0) {\n nextSection = cardSection;\n surroundingSections = [newSection, cardSection];\n } else {\n nextSection = cardSection.next;\n surroundingSections = [cardSection, newSection];\n }\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, newSection, nextSection);\n\n return surroundingSections;\n }\n\n /**\n * @param {Section} section\n * @param {Section} newSection\n * @return null\n * @public\n */\n }, {\n key: 'replaceSection',\n value: function replaceSection(section, newSection) {\n if (!section) {\n // FIXME should a falsy section be a valid argument?\n this.insertSectionBefore(this.editor.post.sections, newSection, null);\n } else {\n this._replaceSection(section, [newSection]);\n }\n }\n }, {\n key: 'moveSectionBefore',\n value: function moveSectionBefore(collection, renderedSection, beforeSection) {\n var newSection = renderedSection.clone();\n this.removeSection(renderedSection);\n this.insertSectionBefore(collection, newSection, beforeSection);\n return newSection;\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionUp',\n value: function moveSectionUp(renderedSection) {\n var isFirst = !renderedSection.prev;\n if (isFirst) {\n return renderedSection;\n }\n\n var collection = renderedSection.parent.sections;\n var beforeSection = renderedSection.prev;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionDown',\n value: function moveSectionDown(renderedSection) {\n var isLast = !renderedSection.next;\n if (isLast) {\n return renderedSection;\n }\n\n var beforeSection = renderedSection.next.next;\n var collection = renderedSection.parent.sections;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * Insert an array of markers at the given position. If the position is in\n * a non-markerable section (like a card section), this method throws an error.\n *\n * @param {Position} position\n * @param {Marker[]} markers\n * @return {Position} The position that represents the end of the inserted markers.\n * @public\n */\n }, {\n key: 'insertMarkers',\n value: function insertMarkers(position, markers) {\n var _this9 = this;\n\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert markers at non-markerable position', section.isMarkerable);\n\n this.editActionTaken = EDIT_ACTIONS.INSERT_TEXT;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (marker) {\n return _this9._scheduleForRemoval(marker);\n });\n\n var prevMarker = section.markerBeforeOffset(offset);\n markers.forEach(function (marker) {\n section.markers.insertAfter(marker, prevMarker);\n offset += marker.length;\n prevMarker = marker;\n });\n\n this._coalesceMarkers(section);\n this._markDirty(section);\n\n var nextPosition = section.toPosition(offset);\n this.setRange(nextPosition);\n return nextPosition;\n }\n\n /**\n * Inserts text with the given markups, ignoring the existing markups at\n * the position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @param {Markup[]} markups\n * @return {Position} position at the end of the inserted text\n */\n }, {\n key: 'insertTextWithMarkup',\n value: function insertTextWithMarkup(position, text) {\n var markups = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var marker = this.builder.createMarker(text, markups);\n return this.insertMarkers(position, [marker]);\n }\n\n /**\n * Insert the text at the given position\n * Inherits the markups already at that position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @return {Position} position at the end of the inserted text.\n */\n }, {\n key: 'insertText',\n value: function insertText(position, text) {\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var markups = position.marker && position.marker.markups;\n markups = markups || [];\n return this.insertTextWithMarkup(position, text, markups);\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this10 = this;\n\n var nextSection = section.next;\n var collection = section.parent.sections;\n\n var nextNewSection = newSections[0];\n if (nextNewSection.isMarkupSection && section.isListItem) {\n // put the new section after the ListSection (section.parent)\n // instead of after the ListItem\n collection = section.parent.parent.sections;\n nextSection = section.parent.next;\n }\n\n newSections.forEach(function (s) {\n return _this10.insertSectionBefore(collection, s, nextSection);\n });\n this.removeSection(section);\n }\n\n /**\n * Given a markerRange (for example `editor.range`) mark all markers\n * inside it as a given markup. The markup must be provided as a post\n * abstract node.\n *\n * Usage:\n *\n * let range = editor.range;\n * let strongMarkup = editor.builder.createMarkup('strong');\n * editor.run((postEditor) => {\n * postEditor.addMarkupToRange(range, strongMarkup);\n * });\n * // Will result some markers possibly being split, and the markup\n * // being applied to all markers between the split.\n *\n * @param {Range} range\n * @param {Markup} markup A markup post abstract node\n * @public\n */\n }, {\n key: 'addMarkupToRange',\n value: function addMarkupToRange(range, markup) {\n var _this11 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n var markers = this.splitMarkers(range);\n if (markers.length) {\n (function () {\n // We insert the new markup at a consistent index across the range.\n // If we just push on the end of the list, it can end up in different positions\n // of the markup stack. This results in unnecessary closing and re-opening of\n // the markup each time it changes position.\n // If we just push it at the beginning of the list, this causes unnecessary closing\n // and re-opening of surrounding tags.\n // So, we look for any tags open across the whole range, and push into the stack\n // at the end of those.\n // Prompted by https://github.com/bustle/mobiledoc-kit/issues/360\n\n var markupsOpenAcrossRange = (0, _mobiledocKitUtilsArrayUtils.reduce)(markers, function (soFar, marker) {\n return (0, _mobiledocKitUtilsArrayUtils.commonItems)(soFar, marker.markups);\n }, markers[0].markups);\n var indexToInsert = markupsOpenAcrossRange.length;\n\n markers.forEach(function (marker) {\n marker.addMarkupAtIndex(markup, indexToInsert);\n _this11._markDirty(marker);\n });\n })();\n }\n }\n\n /**\n * Given a markerRange (for example `editor.range`) remove the given\n * markup from all contained markers.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let markup = markerRange.headMarker.markups[0];\n * editor.run(postEditor => {\n * postEditor.removeMarkupFromRange(range, markup);\n * });\n * // Will result in some markers possibly being split, and the markup\n * // being removed from all markers between the split.\n * ```\n * @param {Range} range Object with offsets\n * @param {Markup|Function} markupOrCallback A markup post abstract node or\n * a function that returns true when passed a markup that should be removed\n * @private\n */\n }, {\n key: 'removeMarkupFromRange',\n value: function removeMarkupFromRange(range, markupOrMarkupCallback) {\n var _this12 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n this.splitMarkers(range).forEach(function (marker) {\n marker.removeMarkup(markupOrMarkupCallback);\n _this12._markDirty(marker);\n });\n }\n\n /**\n * Toggle the given markup in the given range (or at the position given). If the range/position\n * has the markup, the markup will be removed. If nothing in the range/position\n * has the markup, the markup will be added to everything in the range/position.\n *\n * Usage:\n * ```\n * // Remove any 'strong' markup if it exists in the selection, otherwise\n * // make it all 'strong'\n * editor.run(postEditor => postEditor.toggleMarkup('strong'));\n *\n * // add/remove a link to 'bustle.com' to the selection\n * editor.run(postEditor => {\n * const linkMarkup = postEditor.builder.createMarkup('a', {href: 'http://bustle.com'});\n * postEditor.toggleMarkup(linkMarkup);\n * });\n * ```\n * @param {Markup|String} markupOrString Either a markup object created using\n * the builder (useful when adding a markup with attributes, like an 'a' markup),\n * or, if a string, the tag name of the markup (e.g. 'strong', 'em') to toggle.\n * @param {Range|Position} range in which to toggle. Defaults to current editor range.\n * @public\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markupOrMarkupString) {\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n var markup = typeof markupOrMarkupString === 'string' ? this.builder.createMarkup(markupOrMarkupString) : markupOrMarkupString;\n\n var hasMarkup = this.editor.detectMarkupInRange(range, markup.tagName);\n // FIXME: This implies only a single markup in a range. This may not be\n // true for links (which are not the same object instance like multiple\n // strong tags would be).\n if (hasMarkup) {\n this.removeMarkupFromRange(range, hasMarkup);\n } else {\n this.addMarkupToRange(range, markup);\n }\n\n this.setRange(range);\n }\n\n /**\n * Toggles the tagName of the active section or sections in the given range/position.\n * If every section has the tag name, they will all be reset to default sections.\n * Otherwise, every section will be changed to the requested type\n *\n * @param {String} sectionTagName A valid markup section or\n * list section tag name (e.g. 'blockquote', 'h2', 'ul')\n * @param {Range|Position} range The range over which to toggle.\n * Defaults to the current editor range.\n * @public\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(sectionTagName) {\n var _this13 = this;\n\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName);\n var post = this.editor.post;\n\n var nextRange = range;\n\n var everySectionHasTagName = true;\n post.walkMarkerableSections(range, function (section) {\n if (!_this13._isSameSectionType(section, sectionTagName)) {\n everySectionHasTagName = false;\n }\n });\n\n var tagName = everySectionHasTagName ? 'p' : sectionTagName;\n var firstChanged = undefined;\n post.walkMarkerableSections(range, function (section) {\n var changedSection = _this13.changeSectionTagName(section, tagName);\n firstChanged = firstChanged || changedSection;\n });\n\n if (firstChanged) {\n nextRange = firstChanged.headPosition().toRange();\n }\n this.setRange(nextRange);\n }\n }, {\n key: '_isSameSectionType',\n value: function _isSameSectionType(section, sectionTagName) {\n return section.isListItem ? section.parent.tagName === sectionTagName : section.tagName === sectionTagName;\n }\n\n /**\n * @param {Markerable} section\n * @private\n */\n }, {\n key: 'changeSectionTagName',\n value: function changeSectionTagName(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot pass non-markerable section to `changeSectionTagName`', section.isMarkerable);\n\n if (isListSectionTagName(newTagName)) {\n return this._changeSectionToListItem(section, newTagName);\n } else if (section.isListItem) {\n return this._changeSectionFromListItem(section, newTagName);\n } else {\n section.tagName = newTagName;\n this._markDirty(section);\n return section;\n }\n }\n\n /**\n * Splits the item at the position given.\n * If the position is at the start or end of the item, the pre- or post-item\n * will contain a single empty (\"\") marker.\n * @param {ListItem} item\n * @param {Position} position\n * @return {Array} the pre-item and post-item on either side of the split\n * @private\n */\n }, {\n key: '_splitListItem',\n value: function _splitListItem(item, position) {\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list item at position that does not include item', item === section);\n\n item.splitMarkerAtOffset(offset);\n var prevMarker = item.markerBeforeOffset(offset);\n var preItem = this.builder.createListItem(),\n postItem = this.builder.createListItem();\n\n var currentItem = preItem;\n item.markers.forEach(function (marker) {\n currentItem.markers.append(marker.clone());\n if (marker === prevMarker) {\n currentItem = postItem;\n }\n });\n this._replaceSection(item, [preItem, postItem]);\n return [preItem, postItem];\n }\n\n /**\n * Splits the list at the position given.\n * @return {Array} pre-split list and post-split list, either of which could\n * be blank (0-item list) if the position is at the start or end of the list.\n *\n * Note: Contiguous list sections will be joined in the before_complete queue\n * of the postEditor.\n *\n * @private\n */\n }, {\n key: '_splitListAtPosition',\n value: function _splitListAtPosition(list, position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at position not in list', position.section.parent === list);\n\n var positionIsMiddle = !position.isHead() && !position.isTail();\n if (positionIsMiddle) {\n var item = position.section;\n\n var _splitListItem3 = // jshint ignore:line\n this._splitListItem(item, position);\n\n var _splitListItem32 = _slicedToArray(_splitListItem3, 2);\n\n var pre = _splitListItem32[0];\n var post = _splitListItem32[1];\n\n position = pre.tailPosition();\n }\n\n var preList = this.builder.createListSection(list.tagName);\n var postList = this.builder.createListSection(list.tagName);\n\n var preItem = position.section;\n var currentList = preList;\n list.items.forEach(function (item) {\n // If this item matches the start item and the position is at its start,\n // it should be appended to the postList instead of the preList\n if (item === preItem && position.isEqual(item.headPosition())) {\n currentList = postList;\n }\n currentList.items.append(item.clone());\n // If we just appended the preItem, append the remaining items to the postList\n if (item === preItem) {\n currentList = postList;\n }\n });\n\n this._replaceSection(list, [preList, postList]);\n return [preList, postList];\n }\n\n /**\n * @return Array of [prev, mid, next] lists. `prev` and `next` can\n * be blank, depending on the position of `item`. `mid` will always\n * be a 1-item list containing `item`. `prev` and `next` will be\n * removed in the before_complete queue if they are blank\n * (and still attached).\n *\n * @private\n */\n }, {\n key: '_splitListAtItem',\n value: function _splitListAtItem(list, item) {\n var _this14 = this;\n\n var next = list;\n var prev = this.builder.createListSection(next.tagName);\n var mid = this.builder.createListSection(next.tagName);\n\n var addToPrev = true;\n // must turn the LinkedList into an array so that we can remove items\n // as we iterate through it\n var items = next.items.toArray();\n items.forEach(function (i) {\n var listToAppend = undefined;\n if (i === item) {\n addToPrev = false;\n listToAppend = mid;\n } else if (addToPrev) {\n listToAppend = prev;\n } else {\n return; // break after iterating prev and mid parts of the list\n }\n listToAppend.join(i);\n _this14.removeSection(i);\n });\n var found = !addToPrev;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found);\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, mid, next);\n this.insertSectionBefore(collection, prev, mid);\n\n // Remove possibly blank prev/next lists\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n [prev, next].forEach(function (_list) {\n var isAttached = !!_list.parent;\n if (_list.isBlank && isAttached) {\n _this14.removeSection(_list);\n }\n });\n });\n\n return [prev, mid, next];\n }\n }, {\n key: '_changeSectionFromListItem',\n value: function _changeSectionFromListItem(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass list item to `_changeSectionFromListItem`', section.isListItem);\n\n var listSection = section.parent;\n var markupSection = this.builder.createMarkupSection(newTagName);\n markupSection.join(section);\n\n var _splitListAtItem2 = this._splitListAtItem(listSection, section);\n\n var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 3);\n\n var prev = _splitListAtItem22[0];\n var mid = _splitListAtItem22[1];\n var next = _splitListAtItem22[2];\n // jshint ignore:line\n this.replaceSection(mid, markupSection);\n return markupSection;\n }\n }, {\n key: '_changeSectionToListItem',\n value: function _changeSectionToListItem(section, newTagName) {\n var isAlreadyCorrectListItem = section.isListItem && section.parent.tagName === newTagName;\n\n if (isAlreadyCorrectListItem) {\n return section;\n }\n\n var listSection = this.builder.createListSection(newTagName);\n listSection.join(section);\n\n var sectionToReplace = undefined;\n if (section.isListItem) {\n var _splitListAtItem3 = this._splitListAtItem(section.parent, section);\n\n var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 3);\n\n var prev = _splitListAtItem32[0];\n var mid = _splitListAtItem32[1];\n var next = _splitListAtItem32[2];\n // jshint ignore:line\n sectionToReplace = mid;\n } else {\n sectionToReplace = section;\n }\n this.replaceSection(sectionToReplace, listSection);\n return listSection;\n }\n\n /**\n * Insert a given section before another one, updating the post abstract\n * and the rendered UI.\n *\n * Usage:\n * ```\n * let markerRange = editor.range;\n * let sectionWithCursor = markerRange.headMarker.section;\n * let section = editor.builder.createCardSection('my-image');\n * let collection = sectionWithCursor.parent.sections;\n * editor.run((postEditor) => {\n * postEditor.insertSectionBefore(collection, section, sectionWithCursor);\n * });\n * ```\n * @param {LinkedList} collection The list of sections to insert into\n * @param {Object} section The new section\n * @param {Object} beforeSection Optional The section \"before\" is relative to,\n * if falsy the new section will be appended to the collection\n * @public\n */\n }, {\n key: 'insertSectionBefore',\n value: function insertSectionBefore(collection, section, beforeSection) {\n collection.insertBefore(section, beforeSection);\n this._markDirty(section.parent);\n }\n\n /**\n * Insert the given section after the current active section, or, if no\n * section is active, at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSection',\n value: function insertSection(section) {\n var activeSection = this.editor.activeSection;\n var nextSection = activeSection && activeSection.next;\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, section, nextSection);\n }\n\n /**\n * Insert the given section at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSectionAtEnd',\n value: function insertSectionAtEnd(section) {\n this.insertSectionBefore(this.editor.post.sections, section, null);\n }\n\n /**\n * Insert the `post` at the given position in the editor's post.\n * @param {Position} position\n * @param {Post} post\n * @private\n */\n }, {\n key: 'insertPost',\n value: function insertPost(position, newPost) {\n var post = this.editor.post;\n var inserter = new _mobiledocKitEditorPostPostInserter['default'](this, post);\n var nextPosition = inserter.insert(position, newPost);\n return nextPosition;\n }\n\n /**\n * Remove a given section from the post abstract and the rendered UI.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let sectionWithCursor = range.head.section;\n * editor.run((postEditor) => {\n * postEditor.removeSection(sectionWithCursor);\n * });\n * ```\n * @param {Object} section The section to remove\n * @public\n */\n }, {\n key: 'removeSection',\n value: function removeSection(section) {\n var parent = section.parent;\n this._scheduleForRemoval(section);\n parent.sections.remove(section);\n\n if (parent.isListSection) {\n this._scheduleListRemovalIfEmpty(parent);\n }\n }\n }, {\n key: 'removeAllSections',\n value: function removeAllSections() {\n var _this15 = this;\n\n this.editor.post.sections.toArray().forEach(function (section) {\n _this15.removeSection(section);\n });\n }\n }, {\n key: 'migrateSectionsFromPost',\n value: function migrateSectionsFromPost(post) {\n var _this16 = this;\n\n post.sections.toArray().forEach(function (section) {\n post.sections.remove(section);\n _this16.insertSectionBefore(_this16.editor.post.sections, section, null);\n });\n }\n }, {\n key: '_scheduleListRemovalIfEmpty',\n value: function _scheduleListRemovalIfEmpty(listSection) {\n var _this17 = this;\n\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n // if the list is attached and blank after we do other rendering stuff,\n // remove it\n var isAttached = !!listSection.parent;\n if (isAttached && listSection.isBlank) {\n _this17.removeSection(listSection);\n }\n });\n }\n\n /**\n * A method for adding work the deferred queue\n *\n * @param {Function} callback to run during completion\n * @param {Boolean} [once=false] Whether to only schedule the callback once.\n * @public\n */\n }, {\n key: 'schedule',\n value: function schedule(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Work can only be scheduled before a post edit has completed', !this._didComplete);\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.COMPLETE, callback);\n }\n }\n\n /**\n * A method for adding work the deferred queue. The callback will only\n * be added to the queue once, even if `scheduleOnce` is called multiple times.\n * The function cannot be an anonymous function.\n *\n * @param {Function} callback to run during completion\n * @public\n */\n }, {\n key: 'scheduleOnce',\n value: function scheduleOnce(callback) {\n this.schedule(callback, true);\n }\n\n /**\n * Add a rerender job to the queue\n *\n * @public\n */\n }, {\n key: 'scheduleRerender',\n value: function scheduleRerender() {\n this.scheduleOnce(this._rerender);\n }\n\n /**\n * Schedule a notification that the post has been changed.\n * The notification will result in the editor firing its `postDidChange`\n * hook after the postEditor completes its work (at the end of {@link Editor#run}).\n *\n * @public\n */\n }, {\n key: 'scheduleDidUpdate',\n value: function scheduleDidUpdate() {\n this.scheduleOnce(this._postDidChange);\n }\n }, {\n key: 'scheduleAfterRender',\n value: function scheduleAfterRender(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n }\n }\n\n /**\n * Flush any work on the queue. {@link Editor#run} calls this method; it\n * should not be called directly.\n *\n * @private\n */\n }, {\n key: 'complete',\n value: function complete() {\n (0, _mobiledocKitUtilsAssert['default'])('Post editing can only be completed once', !this._didComplete);\n\n this.runCallbacks(CALLBACK_QUEUES.BEFORE_COMPLETE);\n this._didComplete = true;\n this.runCallbacks(CALLBACK_QUEUES.COMPLETE);\n this.runCallbacks(CALLBACK_QUEUES.AFTER_COMPLETE);\n }\n }, {\n key: 'undoLastChange',\n value: function undoLastChange() {\n this.editor._editHistory.stepBackward(this);\n }\n }, {\n key: 'redoLastChange',\n value: function redoLastChange() {\n this.editor._editHistory.stepForward(this);\n }\n }, {\n key: 'cancelSnapshot',\n value: function cancelSnapshot() {\n this._shouldCancelSnapshot = true;\n }\n }]);\n\n return PostEditor;\n })();\n\n exports['default'] = PostEditor;\n});","define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MARKERABLE = 'markerable',\n NESTED_MARKERABLE = 'nested_markerable',\n NON_MARKERABLE = 'non_markerable';\n\n var Visitor = (function () {\n function Visitor(inserter, cursorPosition) {\n _classCallCheck(this, Visitor);\n\n var postEditor = inserter.postEditor;\n var post = inserter.post;\n\n this.postEditor = postEditor;\n this._post = post;\n this.cursorPosition = cursorPosition;\n this.builder = this.postEditor.builder;\n\n this._hasInsertedFirstLeafSection = false;\n }\n\n _createClass(Visitor, [{\n key: 'visit',\n value: function visit(node) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit node of type ' + node.type, !!this[method]);\n this[method](node);\n }\n }, {\n key: '_canMergeSection',\n value: function _canMergeSection(section) {\n if (this._hasInsertedFirstLeafSection) {\n return false;\n } else {\n return this._isMarkerable && section.isMarkerable;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(node) {\n var _this = this;\n\n if (this.cursorSection.isBlank && !this._isNested) {\n // replace blank section with entire post\n var newSections = node.sections.map(function (s) {\n return s.clone();\n });\n this._replaceSection(this.cursorSection, newSections);\n } else {\n node.sections.forEach(function (section) {\n return _this.visit(section);\n });\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(node) {\n this[MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(node) {\n var _this2 = this;\n\n var hasNext = !!node.next;\n node.items.forEach(function (item) {\n return _this2.visit(item);\n });\n\n if (this._isNested && hasNext) {\n this._breakNestedAtCursor();\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(node) {\n this[NESTED_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: NON_MARKERABLE,\n value: function value(section) {\n if (this._isNested) {\n this._breakNestedAtCursor();\n } else if (!this.cursorSection.isBlank) {\n this._breakAtCursor();\n }\n\n this._insertLeafSection(section);\n }\n }, {\n key: MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n } else if (this._isNested && this._isMarkerable) {\n // If we are attaching a markerable section to a list item,\n // insert a linebreak then merge the section onto the resulting blank list item\n this._breakAtCursor();\n\n // Advance the cursor to the head of the blank list item\n var nextPosition = this.cursorSection.next.headPosition();\n this.cursorPosition = nextPosition;\n\n // Merge this section onto the list item\n this._mergeSection(section);\n } else {\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n }\n }, {\n key: NESTED_MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n return;\n }\n\n section = this._isNested ? section : this._wrapNestedSection(section);\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n\n // break out of a nested cursor position\n }, {\n key: '_breakNestedAtCursor',\n value: function _breakNestedAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call _breakNestedAtCursor if not nested', this._isNested);\n\n var parent = this.cursorSection.parent;\n var cursorAtEndOfList = this.cursorPosition.isEqual(parent.tailPosition());\n\n if (cursorAtEndOfList) {\n var blank = this.builder.createMarkupSection();\n this._insertSectionAfter(blank, parent);\n } else {\n var _breakListAtCursor2 = this._breakListAtCursor();\n\n var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 3);\n\n var pre = _breakListAtCursor22[0];\n var blank = _breakListAtCursor22[1];\n var post = _breakListAtCursor22[2];\n // jshint ignore:line\n this.cursorPosition = blank.tailPosition();\n }\n }\n }, {\n key: '_breakListAtCursor',\n value: function _breakListAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _splitParentSection if cursor position is not nested', this._isNested);\n\n var list = this.cursorSection.parent,\n position = this.cursorPosition,\n blank = this.builder.createMarkupSection();\n\n var _postEditor$_splitListAtPosition = this.postEditor._splitListAtPosition(list, position);\n\n var _postEditor$_splitListAtPosition2 = _slicedToArray(_postEditor$_splitListAtPosition, 2);\n\n var pre = _postEditor$_splitListAtPosition2[0];\n var post = _postEditor$_splitListAtPosition2[1];\n\n var collection = this._post.sections,\n reference = post;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n return [pre, blank, post];\n }\n }, {\n key: '_wrapNestedSection',\n value: function _wrapNestedSection(section) {\n var tagName = section.parent.tagName;\n var parent = this.builder.createListSection(tagName);\n parent.items.append(section.clone());\n return parent;\n }\n }, {\n key: '_mergeSection',\n value: function _mergeSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only merge markerable sections', this._isMarkerable && section.isMarkerable);\n this._hasInsertedFirstLeafSection = true;\n\n var markers = section.markers.map(function (m) {\n return m.clone();\n });\n var position = this.postEditor.insertMarkers(this.cursorPosition, markers);\n\n this.cursorPosition = position;\n }\n\n // Can be called to add a line break when in a nested section or a parent\n // section.\n }, {\n key: '_breakAtCursor',\n value: function _breakAtCursor() {\n if (this.cursorSection.isBlank) {\n return;\n } else if (this._isMarkerable) {\n this._breakMarkerableAtCursor();\n } else {\n this._breakNonMarkerableAtCursor();\n }\n }\n\n // Inserts a blank section before/after the cursor,\n // depending on cursor position.\n }, {\n key: '_breakNonMarkerableAtCursor',\n value: function _breakNonMarkerableAtCursor() {\n var collection = this._post.sections,\n blank = this.builder.createMarkupSection(),\n reference = this.cursorPosition.isHead() ? this.cursorSection : this.cursorSection.next;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n this.cursorPosition = blank.tailPosition();\n }\n }, {\n key: '_breakMarkerableAtCursor',\n value: function _breakMarkerableAtCursor() {\n var _postEditor$splitSection = // jshint ignore:line\n this.postEditor.splitSection(this.cursorPosition);\n\n var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 2);\n\n var pre = _postEditor$splitSection2[0];\n var post = _postEditor$splitSection2[1];\n\n this.cursorPosition = pre.tailPosition();\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot replace section that does not have parent.sections', section.parent && section.parent.sections);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass enumerable to _replaceSection', !!newSections.forEach);\n\n var collection = section.parent.sections;\n var reference = section.next;\n this.postEditor.removeSection(section);\n newSections.forEach(function (section) {\n _this3.postEditor.insertSectionBefore(collection, section, reference);\n });\n var lastSection = newSections[newSections.length - 1];\n\n this.cursorPosition = lastSection.tailPosition();\n }\n }, {\n key: '_insertSectionBefore',\n value: function _insertSectionBefore(section, reference) {\n var collection = this.cursorSection.parent.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n\n this.cursorPosition = section.tailPosition();\n }\n\n // Insert a section after the parent section.\n // E.g., add a markup section after a list section\n }, {\n key: '_insertSectionAfter',\n value: function _insertSectionAfter(section, parent) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _insertSectionAfter nested section', !parent.isNested);\n var reference = parent.next;\n var collection = this._post.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n this.cursorPosition = section.tailPosition();\n }\n }, {\n key: '_insertLeafSection',\n value: function _insertLeafSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only _insertLeafSection when cursor is at end of section', this.cursorPosition.isTail());\n\n this._hasInsertedFirstLeafSection = true;\n section = section.clone();\n\n if (this.cursorSection.isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert leaf non-markerable section when cursor is nested', !(section.isMarkerable && this._isNested));\n this._replaceSection(this.cursorSection, [section]);\n } else if (this.cursorSection.next && this.cursorSection.next.isBlank) {\n this._replaceSection(this.cursorSection.next, [section]);\n } else {\n var reference = this.cursorSection.next;\n this._insertSectionBefore(section, reference);\n }\n }\n }, {\n key: 'cursorPosition',\n get: function get() {\n return this._cursorPosition;\n },\n set: function set(position) {\n this._cursorPosition = position;\n this.postEditor.setRange(position);\n }\n }, {\n key: '_isMarkerable',\n get: function get() {\n return this.cursorSection.isMarkerable;\n }\n }, {\n key: 'cursorSection',\n get: function get() {\n return this.cursorPosition.section;\n }\n }, {\n key: 'cursorOffset',\n get: function get() {\n return this.cursorPosition.offset;\n }\n }, {\n key: '_isNested',\n get: function get() {\n return this.cursorSection.isNested;\n }\n }]);\n\n return Visitor;\n })();\n\n var Inserter = (function () {\n function Inserter(postEditor, post) {\n _classCallCheck(this, Inserter);\n\n this.postEditor = postEditor;\n this.post = post;\n }\n\n _createClass(Inserter, [{\n key: 'insert',\n value: function insert(cursorPosition, newPost) {\n var visitor = new Visitor(this, cursorPosition);\n visitor.visit(newPost);\n return visitor.cursorPosition;\n }\n }]);\n\n return Inserter;\n })();\n\n exports['default'] = Inserter;\n});","define(\"mobiledoc-kit/editor/selection-change-observer\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var instance = undefined;\n\n var SelectionChangeObserver = (function () {\n function SelectionChangeObserver() {\n _classCallCheck(this, SelectionChangeObserver);\n\n this.started = false;\n this.listeners = [];\n this.selection = {};\n }\n\n _createClass(SelectionChangeObserver, [{\n key: \"addListener\",\n value: function addListener(listener) {\n if (this.listeners.indexOf(listener) === -1) {\n this.listeners.push(listener);\n this.start();\n }\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n var index = this.listeners.indexOf(listener);\n if (index !== -1) {\n this.listeners.splice(index, 1);\n if (this.listeners.length === 0) {\n this.stop();\n }\n }\n }\n }, {\n key: \"start\",\n value: function start() {\n if (this.started) {\n return;\n }\n this.started = true;\n\n this.poll();\n }\n }, {\n key: \"stop\",\n value: function stop() {\n this.started = false;\n this.selection = {};\n }\n }, {\n key: \"notifyListeners\",\n value: function notifyListeners() /* newSelection, prevSelection */{\n var _arguments = arguments;\n\n this.listeners.forEach(function (listener) {\n listener.selectionDidChange.apply(listener, _arguments);\n });\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.stop();\n this.listeners = [];\n }\n }, {\n key: \"getSelection\",\n value: function getSelection() {\n var selection = window.getSelection();\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n return { anchorNode: anchorNode, focusNode: focusNode, anchorOffset: anchorOffset, focusOffset: focusOffset };\n }\n }, {\n key: \"poll\",\n value: function poll() {\n var _this = this;\n\n if (this.started) {\n this.update();\n this.runNext(function () {\n return _this.poll();\n });\n }\n }\n }, {\n key: \"runNext\",\n value: function runNext(fn) {\n window.requestAnimationFrame(fn);\n }\n }, {\n key: \"update\",\n value: function update() {\n var prevSelection = this.selection;\n var curSelection = this.getSelection();\n if (!this.selectionIsEqual(prevSelection, curSelection)) {\n this.selection = curSelection;\n this.notifyListeners(curSelection, prevSelection);\n }\n }\n }, {\n key: \"selectionIsEqual\",\n value: function selectionIsEqual(s1, s2) {\n return s1.anchorNode === s2.anchorNode && s1.anchorOffset === s2.anchorOffset && s1.focusNode === s2.focusNode && s1.focusOffset === s2.focusOffset;\n }\n }], [{\n key: \"getInstance\",\n value: function getInstance() {\n if (!instance) {\n instance = new SelectionChangeObserver();\n }\n return instance;\n }\n }, {\n key: \"addListener\",\n value: function addListener(listener) {\n SelectionChangeObserver.getInstance().addListener(listener);\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n SelectionChangeObserver.getInstance().removeListener(listener);\n }\n }]);\n\n return SelectionChangeObserver;\n })();\n\n exports[\"default\"] = SelectionChangeObserver;\n});","define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/editor/selection-change-observer'], function (exports, _mobiledocKitEditorSelectionChangeObserver) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SelectionManager = (function () {\n function SelectionManager(editor, callback) {\n _classCallCheck(this, SelectionManager);\n\n this.editor = editor;\n this.callback = callback;\n this.started = false;\n }\n\n _createClass(SelectionManager, [{\n key: 'start',\n value: function start() {\n if (this.started) {\n return;\n }\n\n _mobiledocKitEditorSelectionChangeObserver['default'].addListener(this);\n this.started = true;\n }\n }, {\n key: 'stop',\n value: function stop() {\n this.started = false;\n _mobiledocKitEditorSelectionChangeObserver['default'].removeListener(this);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stop();\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange() {\n if (this.started) {\n this.callback.apply(this, arguments);\n }\n }\n }]);\n\n return SelectionManager;\n })();\n\n exports['default'] = SelectionManager;\n});","define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var TextInputHandler = (function () {\n function TextInputHandler(editor) {\n _classCallCheck(this, TextInputHandler);\n\n this.editor = editor;\n this._handlers = [];\n }\n\n _createClass(TextInputHandler, [{\n key: 'register',\n value: function register(handler) {\n (0, _mobiledocKitUtilsAssert['default'])('Input Handler is not valid', this._validateHandler(handler));\n this._handlers.push(handler);\n }\n }, {\n key: 'unregister',\n value: function unregister(name) {\n var handlers = this._handlers;\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i].name === name) {\n handlers.splice(i, 1);\n }\n }\n }\n }, {\n key: 'handle',\n value: function handle(string) {\n var editor = this.editor;\n\n editor.insertText(string);\n\n var matchedHandler = this._findHandler();\n if (matchedHandler) {\n var _matchedHandler = _slicedToArray(matchedHandler, 2);\n\n var handler = _matchedHandler[0];\n var matches = _matchedHandler[1];\n\n handler.run(editor, matches);\n }\n }\n }, {\n key: '_findHandler',\n value: function _findHandler() {\n var _editor$range = this.editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n var preText = section.textUntil(head);\n\n for (var i = 0; i < this._handlers.length; i++) {\n var handler = this._handlers[i];\n var text = handler.text;\n var match = handler.match;\n\n if (text && (0, _mobiledocKitUtilsStringUtils.endsWith)(preText, text)) {\n return [handler, [text]];\n } else if (match && match.test(preText)) {\n return [handler, match.exec(preText)];\n }\n }\n }\n }, {\n key: '_validateHandler',\n value: function _validateHandler(handler) {\n (0, _mobiledocKitUtilsDeprecate['default'])('Registered input handlers require a \"name\" property so that they can be unregistered', !!handler.name);\n return !!handler.run && ( // has `run`\n !!handler.text || !!handler.match) && // and `text` or `match`\n !(!!handler.text && !!handler.match); // not both `text` and `match`\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._handlers = [];\n }\n }]);\n\n return TextInputHandler;\n })();\n\n exports['default'] = TextInputHandler;\n});","define('mobiledoc-kit/editor/text-input-handlers', ['exports'], function (exports) {\n /**\n * Convert section at the editor's cursor position into a list.\n * Does nothing if the cursor position is not at the start of the section,\n * or if the section is already a list item.\n *\n * @param {Editor} editor\n * @param {String} listTagName (\"ul\" or \"ol\")\n * @public\n */\n 'use strict';\n\n exports.replaceWithListSection = replaceWithListSection;\n exports.replaceWithHeaderSection = replaceWithHeaderSection;\n\n function replaceWithListSection(editor, listTagName) {\n var _editor$range = editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n if (section.isListItem) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var item = builder.createListItem();\n var listSection = builder.createListSection(listTagName, [item]);\n\n postEditor.replaceSection(section, listSection);\n postEditor.setRange(listSection.headPosition());\n });\n }\n\n /**\n * Convert section at the editor's cursor position into a header section.\n * Does nothing if the cursor position is not at the start of the section.\n *\n * @param {Editor} editor\n * @param {String} headingTagName ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')\n * @public\n */\n\n function replaceWithHeaderSection(editor, headingTagName) {\n var _editor$range2 = editor.range;\n var head = _editor$range2.head;\n var section = _editor$range2.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var newSection = builder.createMarkupSection(headingTagName);\n postEditor.replaceSection(section, newSection);\n postEditor.setRange(newSection.headPosition());\n });\n }\n\n var DEFAULT_TEXT_INPUT_HANDLERS = [{\n name: 'ul',\n // \"* \" -> ul\n match: /^\\* $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ul');\n }\n }, {\n name: 'ol',\n // \"1\" -> ol, \"1.\" -> ol\n match: /^1\\.? $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ol');\n }\n }, {\n name: 'heading',\n /*\n * \"# \" -> h1\n * \"## \" -> h2\n * \"### \" -> h3\n * \"#### \" -> h4\n * \"##### \" -> h5\n * \"###### \" -> h6\n */\n match: /^(#{1,6}) $/,\n run: function run(editor, matches) {\n var capture = matches[1];\n var headingTag = 'h' + capture.length;\n replaceWithHeaderSection(editor, headingTag);\n }\n }];\n exports.DEFAULT_TEXT_INPUT_HANDLERS = DEFAULT_TEXT_INPUT_HANDLERS;\n});","define('mobiledoc-kit/editor/ui', ['exports'], function (exports) {\n /**\n * @module UI\n */\n\n /**\n * @callback promptCallback\n * @param {String} url The URL to pass back to the editor for linking\n * to the selected text.\n */\n\n /**\n * @callback showPrompt\n * @param {String} message The text of the prompt.\n * @param {String} defaultValue The initial URL to display in the prompt.\n * @param {module:UI~promptCallback} callback Once your handler has accepted a URL,\n * it should pass it to `callback` so that the editor may link the\n * selected text.\n */\n\n /**\n * Exposes the core behavior for linking and unlinking text, and allows for\n * customization of the URL input handler.\n * @param {Editor} editor An editor instance to operate on. If a range is selected,\n * either prompt for a URL and add a link or un-link the\n * currently linked text.\n * @param {module:UI~showPrompt} [showPrompt] An optional custom input handler. Defaults\n * to using `window.prompt`.\n * @example\n * let myPrompt = (message, defaultURL, promptCallback) => {\n * let url = window.prompt(\"Overriding the defaults\", \"http://placekitten.com\");\n * promptCallback(url);\n * };\n *\n * editor.registerKeyCommand({\n * str: \"META+K\",\n * run(editor) {\n * toggleLink(editor, myPrompt);\n * }\n * });\n * @public\n */\n\n 'use strict';\n\n exports.toggleLink = toggleLink;\n var defaultShowPrompt = function defaultShowPrompt(message, defaultValue, callback) {\n return callback(window.prompt(message, defaultValue));\n };\n\n function toggleLink(editor) {\n var showPrompt = arguments.length <= 1 || arguments[1] === undefined ? defaultShowPrompt : arguments[1];\n\n if (editor.range.isCollapsed) {\n return;\n }\n\n var selectedText = editor.cursor.selectedText();\n var defaultUrl = '';\n if (selectedText.indexOf('http') !== -1) {\n defaultUrl = selectedText;\n }\n\n var range = editor.range;\n\n var hasLink = editor.detectMarkupInRange(range, 'a');\n\n if (hasLink) {\n editor.run(function (postEditor) {\n return postEditor.toggleMarkup('a');\n });\n } else {\n showPrompt('Enter a URL', defaultUrl, function (url) {\n if (!url) {\n return;\n }\n\n editor.run(function (postEditor) {\n var markup = postEditor.builder.createMarkup('a', { href: url });\n postEditor.toggleMarkup(markup);\n });\n });\n }\n }\n});","define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n var Mobiledoc = {\n Editor: _mobiledocKitEditorEditor['default'],\n UI: _mobiledocKitEditorUi,\n ImageCard: _mobiledocKitCardsImage['default'],\n Range: _mobiledocKitUtilsCursorRange['default'],\n Position: _mobiledocKitUtilsCursorPosition['default'],\n Error: _mobiledocKitUtilsMobiledocError['default'],\n VERSION: _mobiledocKitVersion['default']\n };\n\n function registerGlobal(global) {\n global.Mobiledoc = Mobiledoc;\n }\n\n exports.Editor = _mobiledocKitEditorEditor['default'];\n exports.UI = _mobiledocKitEditorUi;\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports['default'] = Mobiledoc;\n});","define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Markerable = (function (_Section) {\n _inherits(Markerable, _Section);\n\n function Markerable(type, tagName) {\n var _this = this;\n\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n _classCallCheck(this, Markerable);\n\n _get(Object.getPrototypeOf(Markerable.prototype), 'constructor', this).call(this, type);\n this.isMarkerable = true;\n this.tagName = tagName;\n this.markers = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(m) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only insert markers and atoms into markerable (was: ' + m.type + ')', m.isMarker || m.isAtom);\n m.section = m.parent = _this;\n },\n freeItem: function freeItem(m) {\n return m.section = m.parent = null;\n }\n });\n\n markers.forEach(function (m) {\n return _this.markers.append(m);\n });\n }\n\n _createClass(Markerable, [{\n key: 'canJoin',\n value: function canJoin(other) {\n return other.isMarkerable && other.type === this.type && other.tagName === this.tagName;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newMarkers = this.markers.map(function (m) {\n return m.clone();\n });\n return this.builder.createMarkerableSection(this.type, this.tagName, newMarkers);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get textUntil for a position not in this section', position.section === this);\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n var text = '';\n var currentMarker = this.markers.head;\n while (currentMarker) {\n if (currentMarker === marker) {\n text += currentMarker.textUntil(offsetInMarker);\n break;\n } else {\n text += currentMarker.text;\n currentMarker = currentMarker.next;\n }\n }\n return text;\n }\n\n /**\n * @param {Marker}\n * @param {Number} markerOffset The offset relative to the start of the marker\n *\n * @return {Number} The offset relative to the start of this section\n */\n }, {\n key: 'offsetOfMarker',\n value: function offsetOfMarker(marker) {\n var markerOffset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get offsetOfMarker for marker that is not child of this', marker.section === this);\n\n // FIXME it is possible, when we get a cursor position before having finished reparsing,\n // for markerOffset to be > marker.length. We shouldn't rely on this functionality.\n\n var offset = 0;\n var currentMarker = this.markers.head;\n while (currentMarker && currentMarker !== marker.next) {\n var _length = currentMarker === marker ? markerOffset : currentMarker.length;\n offset += _length;\n currentMarker = currentMarker.next;\n }\n\n return offset;\n }\n\n // puts clones of this.markers into beforeSection and afterSection,\n // all markers before the marker/offset split go in beforeSection, and all\n // after the marker/offset split go in afterSection\n // @return {Array} [beforeSection, afterSection], two new sections\n }, {\n key: '_redistributeMarkers',\n value: function _redistributeMarkers(beforeSection, afterSection, marker) {\n var offset = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3];\n\n var currentSection = beforeSection;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.markers, function (m) {\n if (m === marker) {\n var _marker$split = marker.split(offset);\n\n var _marker$split2 = _toArray(_marker$split);\n\n var beforeMarker = _marker$split2[0];\n\n var afterMarkers = _marker$split2.slice(1);\n\n beforeSection.markers.append(beforeMarker);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(afterMarkers, function (_m) {\n return afterSection.markers.append(_m);\n });\n currentSection = afterSection;\n } else {\n currentSection.markers.append(m.clone());\n }\n });\n\n return [beforeSection, afterSection];\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker() /*marker, offset=0*/{\n (0, _mobiledocKitUtilsAssert['default'])('splitAtMarker must be implemented by sub-class', false);\n }\n\n /**\n * Split this section's marker (if any) at the given offset, so that\n * there is now a marker boundary at that offset (useful for later applying\n * a markup to a range)\n * @param {Number} sectionOffset The offset relative to start of this section\n * @return {EditObject} An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank.\n * After calling `splitMarkerAtOffset(offset)`, there will always be a valid\n * result returned from `markerBeforeOffset(offset)`.\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset(sectionOffset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot splitMarkerAtOffset when offset is > length', sectionOffset <= this.length);\n var markerOffset = undefined;\n var len = 0;\n var currentMarker = this.markers.head;\n var edit = { added: [], removed: [] };\n\n if (!currentMarker) {\n var blankMarker = this.builder.createMarker();\n this.markers.prepend(blankMarker);\n edit.added.push(blankMarker);\n } else {\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n // nothing to do, there is a gap at the requested offset\n break;\n } else if (len > sectionOffset) {\n var _edit$added;\n\n markerOffset = currentMarker.length - (len - sectionOffset);\n var newMarkers = currentMarker.splitAtOffset(markerOffset);\n (_edit$added = edit.added).push.apply(_edit$added, _toConsumableArray(newMarkers));\n edit.removed.push(currentMarker);\n this.markers.splice(currentMarker, 1, newMarkers);\n break;\n } else {\n currentMarker = currentMarker.next;\n }\n }\n }\n\n return edit;\n }\n }, {\n key: 'splitAtPosition',\n value: function splitAtPosition(position) {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n return this.splitAtMarker(marker, offsetInMarker);\n }\n\n // returns the marker just before this offset.\n // It is an error to call this method with an offset that is in the middle\n // of a marker.\n }, {\n key: 'markerBeforeOffset',\n value: function markerBeforeOffset(sectionOffset) {\n var len = 0;\n var currentMarker = this.markers.head;\n\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n return currentMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('markerBeforeOffset called with sectionOffset not between markers', len < sectionOffset);\n currentMarker = currentMarker.next;\n }\n }\n }\n }, {\n key: 'markerPositionAtOffset',\n value: function markerPositionAtOffset(offset) {\n var currentOffset = 0;\n var currentMarker = undefined;\n var remaining = offset;\n this.markers.detect(function (marker) {\n currentOffset = Math.min(remaining, marker.length);\n remaining -= currentOffset;\n if (remaining === 0) {\n currentMarker = marker;\n return true; // break out of detect\n }\n });\n\n return { marker: currentMarker, offset: currentOffset };\n }\n }, {\n key: 'markersFor',\n\n /**\n * @return {Array} New markers that match the boundaries of the\n * range. Does not change the existing markers in this section.\n */\n value: function markersFor(headOffset, tailOffset) {\n var range = { head: { section: this, offset: headOffset },\n tail: { section: this, offset: tailOffset } };\n\n var markers = [];\n this._markersInRange(range, function (marker, _ref) {\n var markerHead = _ref.markerHead;\n var markerTail = _ref.markerTail;\n var isContained = _ref.isContained;\n\n var cloned = marker.clone();\n if (!isContained) {\n // cannot do marker.value.slice if the marker is an atom -- this breaks the atom's \"atomic\" value\n // If a marker is an atom `isContained` should always be true so\n // we shouldn't hit this code path. FIXME add tests\n cloned.value = marker.value.slice(markerHead, markerTail);\n }\n markers.push(cloned);\n });\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n this._markersInRange(range, function (marker) {\n marker.markups.forEach(function (m) {\n return markups.add(m);\n });\n });\n return markups.toArray();\n }\n\n // calls the callback with (marker, {markerHead, markerTail, isContained})\n // for each marker that is wholly or partially contained in the range.\n }, {\n key: '_markersInRange',\n value: function _markersInRange(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call #_markersInRange if range expands beyond this section', head.section === this && tail.section === this);\n var headOffset = head.offset;var tailOffset = tail.offset;\n\n var currentHead = 0,\n currentTail = 0,\n currentMarker = this.markers.head;\n\n while (currentMarker) {\n currentTail += currentMarker.length;\n\n if (currentTail > headOffset && currentHead < tailOffset) {\n var markerHead = Math.max(headOffset - currentHead, 0);\n var markerTail = currentMarker.length - Math.max(currentTail - tailOffset, 0);\n var isContained = markerHead === 0 && markerTail === currentMarker.length;\n\n callback(currentMarker, { markerHead: markerHead, markerTail: markerTail, isContained: isContained });\n }\n\n currentHead += currentMarker.length;\n currentMarker = currentMarker.next;\n\n if (currentHead > tailOffset) {\n break;\n }\n }\n }\n\n // mutates this by appending the other section's (cloned) markers to it\n }, {\n key: 'join',\n value: function join(otherSection) {\n var _this2 = this;\n\n var beforeMarker = this.markers.tail;\n var afterMarker = null;\n\n otherSection.markers.forEach(function (m) {\n if (!m.isBlank) {\n m = m.clone();\n _this2.markers.append(m);\n if (!afterMarker) {\n afterMarker = m;\n }\n }\n });\n\n return { beforeMarker: beforeMarker, afterMarker: afterMarker };\n }\n }, {\n key: 'isBlank',\n get: function get() {\n if (!this.markers.length) {\n return true;\n }\n return this.markers.every(function (m) {\n return m.isBlank;\n });\n }\n }, {\n key: 'text',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.value;\n }, '');\n }\n }, {\n key: 'length',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.length;\n }, 0);\n }\n }]);\n\n return Markerable;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Markerable;\n});","define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/cursor/position'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCursorPosition) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function unimplementedMethod(methodName, me) {\n (0, _mobiledocKitUtilsAssert['default'])('`' + methodName + '()` must be implemented by ' + me.constructor.name, false);\n }\n\n var Section = (function (_LinkedItem) {\n _inherits(Section, _LinkedItem);\n\n function Section(type) {\n _classCallCheck(this, Section);\n\n _get(Object.getPrototypeOf(Section.prototype), 'constructor', this).call(this);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create section without type', !!type);\n this.type = type;\n this.isSection = true;\n this.isMarkerable = false;\n this.isNested = false;\n this.isSection = true;\n this.isLeafSection = true;\n }\n\n _createClass(Section, [{\n key: 'isValidTagName',\n value: function isValidTagName() /* normalizedTagName */{\n unimplementedMethod('isValidTagName', this);\n }\n }, {\n key: 'clone',\n value: function clone() {\n unimplementedMethod('clone', this);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* otherSection */{\n unimplementedMethod('canJoin', this);\n }\n\n /**\n * @return {Position} The position at the start of this section\n * @public\n */\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.toPosition(0);\n }\n\n /**\n * @return {Position} The position at the end of this section\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.toPosition(this.length);\n }\n\n /**\n * @param {Number} offset\n * @return {Position} The position in this section at the given offset\n * @public\n */\n }, {\n key: 'toPosition',\n value: function toPosition(offset) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass number to `toPosition`\", typeof offset === 'number');\n (0, _mobiledocKitUtilsAssert['default'])(\"Cannot call `toPosition` with offset > length\", offset <= this.length);\n\n return new _mobiledocKitUtilsCursorPosition['default'](this, offset);\n }\n\n /**\n * @return {Range} A range from this section's head to tail positions\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'join',\n value: function join() {\n unimplementedMethod('join', this);\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* position */{\n return '';\n }\n\n /**\n * Markerable sections should override this method\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset() {\n var blankEdit = { added: [], removed: [] };\n return blankEdit;\n }\n }, {\n key: 'nextLeafSection',\n value: function nextLeafSection() {\n var next = this.next;\n if (next) {\n if (!!next.items) {\n return next.items.head;\n } else {\n return next;\n }\n } else {\n if (this.isNested) {\n return this.parent.nextLeafSection();\n }\n }\n }\n }, {\n key: 'immediatelyNextMarkerableSection',\n value: function immediatelyNextMarkerableSection() {\n var next = this.nextLeafSection();\n while (next && !next.isMarkerable) {\n next = next.nextLeafSection();\n }\n return next;\n }\n }, {\n key: 'previousLeafSection',\n value: function previousLeafSection() {\n var prev = this.prev;\n\n if (prev) {\n if (!!prev.items) {\n return prev.items.tail;\n } else {\n return prev;\n }\n } else {\n if (this.isNested) {\n return this.parent.previousLeafSection();\n }\n }\n }\n }, {\n key: 'tagName',\n set: function set(val) {\n var normalizedTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(val);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot set section tagName to ' + val, this.isValidTagName(normalizedTagName));\n this._tagName = normalizedTagName;\n },\n get: function get() {\n return this._tagName;\n }\n }, {\n key: 'length',\n get: function get() {\n return 0;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n unimplementedMethod('isBlank', this);\n }\n }]);\n\n return Section;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = Section;\n});","define('mobiledoc-kit/models/atom-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var AtomNode = (function () {\n function AtomNode(editor, atom, model, element, atomOptions) {\n _classCallCheck(this, AtomNode);\n\n this.editor = editor;\n this.atom = atom;\n this.model = model;\n this.atomOptions = atomOptions;\n this.element = element;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(AtomNode, [{\n key: 'render',\n value: function render() {\n if (!this._rendered) {\n var options = this.atomOptions;\n var env = this.env;\n var _model = this.model;\n var value = _model.value;\n var payload = _model.payload;\n\n // cache initial render\n this._rendered = this.atom.render({ options: options, env: env, value: value, payload: payload });\n }\n\n this._validateAndAppendRenderResult(this._rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.atom.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + name + '\" must return a DOM node (returned value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n }\n }, {\n key: 'env',\n get: function get() {\n var _this = this;\n\n return {\n name: this.atom.name,\n onTeardown: function onTeardown(callback) {\n return _this._teardownCallback = callback;\n },\n save: function save(value) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _this.model.value = value;\n _this.model.payload = payload;\n\n _this.editor._postDidChange();\n _this.teardown();\n _this.render();\n }\n };\n }\n }]);\n\n return AtomNode;\n })();\n\n exports['default'] = AtomNode;\n});","define('mobiledoc-kit/models/atom', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var ATOM_LENGTH = 1;\n\n var Atom = (function (_LinkedItem) {\n _inherits(Atom, _LinkedItem);\n\n function Atom(name, value, payload) {\n var _this = this;\n\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n _classCallCheck(this, Atom);\n\n _get(Object.getPrototypeOf(Atom.prototype), 'constructor', this).call(this);\n this.name = name;\n this.value = value;\n this.text = ''; // An atom never has text, but it does have a value\n (0, _mobiledocKitUtilsAssert['default'])('Atom must have value', value !== undefined && value !== null);\n this.payload = payload;\n this.type = _mobiledocKitModelsTypes.ATOM_TYPE;\n this.isMarker = false;\n this.isAtom = true;\n\n this.markups = [];\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Atom, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createAtom(this.name, this.value, this.payload, clonedMarkups);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* other */{\n return false;\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* offset */{\n return '';\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? offset : arguments[1];\n return (function () {\n var markers = [];\n\n if (endOffset === 0) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n markers.push(this.clone());\n\n if (offset === ATOM_LENGTH) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n return markers;\n }).apply(this, arguments);\n }\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n\n var builder = this.builder;\n\n var clone = this.clone();\n var blankMarker = builder.createMarker('');\n var pre = undefined,\n post = undefined;\n\n if (offset === 0) {\n pre = blankMarker;\n post = clone;\n } else if (offset === ATOM_LENGTH) {\n pre = clone;\n post = blankMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Invalid offset given to Atom#splitAtOffset: \"' + offset + '\"', false);\n }\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n return [pre, post];\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return ATOM_LENGTH;\n }\n }]);\n\n return Atom;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Atom, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Atom;\n});","define('mobiledoc-kit/models/card-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CardNode = (function () {\n function CardNode(editor, card, section, element, options) {\n _classCallCheck(this, CardNode);\n\n this.editor = editor;\n this.card = card;\n this.section = section;\n this.element = element;\n this.options = options;\n\n this.mode = null;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(CardNode, [{\n key: 'render',\n value: function render(mode) {\n if (this.mode === mode) {\n return;\n }\n\n this.teardown();\n\n this.mode = mode;\n\n var method = mode === 'display' ? 'render' : 'edit';\n method = this.card[method];\n\n (0, _mobiledocKitUtilsAssert['default'])('Card is missing \"' + method + '\" (tried to render mode: \"' + mode + '\")', !!method);\n var rendered = method({\n env: this.env,\n options: this.options,\n payload: this.section.payload\n });\n\n this._validateAndAppendRenderResult(rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: 'didRender',\n value: function didRender() {\n if (this._didRenderCallback) {\n this._didRenderCallback();\n }\n }\n }, {\n key: 'display',\n value: function display() {\n this.render('display');\n }\n }, {\n key: 'edit',\n value: function edit() {\n this.render('edit');\n }\n }, {\n key: 'remove',\n value: function remove() {\n var _this = this;\n\n this.editor.run(function (postEditor) {\n return postEditor.removeSection(_this.section);\n });\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.card.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + name + '\" must render dom (render value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n this._rendered = rendered;\n this.didRender();\n }\n }, {\n key: 'env',\n get: function get() {\n var _this2 = this;\n\n return {\n name: this.card.name,\n isInEditor: true,\n onTeardown: function onTeardown(callback) {\n return _this2._teardownCallback = callback;\n },\n didRender: function didRender(callback) {\n return _this2._didRenderCallback = callback;\n },\n edit: function edit() {\n return _this2.edit();\n },\n save: function save(payload) {\n var transition = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\n _this2.section.payload = payload;\n\n _this2.editor._postDidChange();\n if (transition) {\n _this2.display();\n }\n },\n cancel: function cancel() {\n return _this2.display();\n },\n remove: function remove() {\n return _this2.remove();\n },\n postModel: this.section\n };\n }\n }]);\n\n return CardNode;\n })();\n\n exports['default'] = CardNode;\n});","define('mobiledoc-kit/models/card', ['exports', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/copy'], function (exports, _mobiledocKitModels_section, _mobiledocKitModelsTypes, _mobiledocKitUtilsCopy) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var CARD_MODES = {\n DISPLAY: 'display',\n EDIT: 'edit'\n };\n\n exports.CARD_MODES = CARD_MODES;\n var CARD_LENGTH = 1;\n\n var DEFAULT_INITIAL_MODE = CARD_MODES.DISPLAY;\n\n var Card = (function (_Section) {\n _inherits(Card, _Section);\n\n function Card(name, payload) {\n _classCallCheck(this, Card);\n\n _get(Object.getPrototypeOf(Card.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.CARD_TYPE);\n this.name = name;\n this.payload = payload;\n this.setInitialMode(DEFAULT_INITIAL_MODE);\n this.isCardSection = true;\n }\n\n _createClass(Card, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var payload = (0, _mobiledocKitUtilsCopy.shallowCopyObject)(this.payload);\n var card = this.builder.createCardSection(this.name, payload);\n // If this card is currently rendered, clone the mode it is\n // currently in as the default mode of the new card.\n var mode = this._initialMode;\n if (this.renderNode && this.renderNode.cardNode) {\n mode = this.renderNode.cardNode.mode;\n }\n card.setInitialMode(mode);\n return card;\n }\n\n /**\n * set the mode that this will be rendered into initially\n * @private\n */\n }, {\n key: 'setInitialMode',\n value: function setInitialMode(initialMode) {\n // TODO validate initialMode\n this._initialMode = initialMode;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return CARD_LENGTH;\n }\n }]);\n\n return Card;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Card;\n});","define('mobiledoc-kit/models/image', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Image = (function (_Section) {\n _inherits(Image, _Section);\n\n function Image() {\n _classCallCheck(this, Image);\n\n _get(Object.getPrototypeOf(Image.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE);\n this.src = null;\n }\n\n _createClass(Image, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return 1;\n }\n }]);\n\n return Image;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Image;\n});","define('mobiledoc-kit/models/lifecycle-callbacks', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LifecycleCallbacks = (function () {\n function LifecycleCallbacks() {\n var _this = this;\n\n var queueNames = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, LifecycleCallbacks);\n\n this.callbackQueues = {};\n this.removalQueues = {};\n\n queueNames.forEach(function (name) {\n _this.callbackQueues[name] = [];\n _this.removalQueues[name] = [];\n });\n }\n\n _createClass(LifecycleCallbacks, [{\n key: 'runCallbacks',\n value: function runCallbacks(queueName) {\n var args = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var queue = this._getQueue(queueName);\n queue.forEach(function (cb) {\n return cb.apply(undefined, _toConsumableArray(args));\n });\n\n var toRemove = this.removalQueues[queueName];\n toRemove.forEach(function (cb) {\n var index = queue.indexOf(cb);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n });\n\n this.removalQueues[queueName] = [];\n }\n }, {\n key: 'addCallback',\n value: function addCallback(queueName, callback) {\n this._getQueue(queueName).push(callback);\n }\n }, {\n key: '_scheduleCallbackForRemoval',\n value: function _scheduleCallbackForRemoval(queueName, callback) {\n this.removalQueues[queueName].push(callback);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce(queueName, callback) {\n var queue = this._getQueue(queueName);\n if (queue.indexOf(callback) === -1) {\n queue.push(callback);\n this._scheduleCallbackForRemoval(queueName, callback);\n }\n }\n }, {\n key: '_getQueue',\n value: function _getQueue(queueName) {\n var queue = this.callbackQueues[queueName];\n (0, _mobiledocKitUtilsAssert['default'])('No queue found for \"' + queueName + '\"', !!queue);\n return queue;\n }\n }]);\n\n return LifecycleCallbacks;\n })();\n\n exports['default'] = LifecycleCallbacks;\n});","define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_ITEM_TAGNAMES = ['li'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_ITEM_TAGNAMES = VALID_LIST_ITEM_TAGNAMES;\n\n var ListItem = (function (_Markerable) {\n _inherits(ListItem, _Markerable);\n\n function ListItem(tagName) {\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, ListItem);\n\n _get(Object.getPrototypeOf(ListItem.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, tagName, markers);\n this.isListItem = true;\n this.isNested = true;\n }\n\n _createClass(ListItem, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_ITEM_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n // FIXME need to check if we are going to split into two list items\n // or a list item and a new markup section:\n var isLastItem = !this.next;\n var createNewSection = !marker && offset === 0 && isLastItem;\n\n var beforeSection = this.builder.createListItem();\n var afterSection = createNewSection ? this.builder.createMarkupSection() : this.builder.createListItem();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }, {\n key: 'post',\n get: function get() {\n return this.section.post;\n }\n }]);\n\n return ListItem;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = ListItem;\n});","define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_SECTION_TAGNAMES = ['ul', 'ol'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_SECTION_TAGNAMES = VALID_LIST_SECTION_TAGNAMES;\n var DEFAULT_TAG_NAME = VALID_LIST_SECTION_TAGNAMES[0];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n\n var ListSection = (function (_Section) {\n _inherits(ListSection, _Section);\n\n function ListSection() {\n var _this = this;\n\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, ListSection);\n\n _get(Object.getPrototypeOf(ListSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_SECTION_TYPE);\n this.tagName = tagName;\n this.isListSection = true;\n this.isLeafSection = false;\n\n this.items = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(i) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem);\n i.section = i.parent = _this;\n },\n freeItem: function freeItem(i) {\n return i.section = i.parent = null;\n }\n });\n this.sections = this.items;\n\n items.forEach(function (i) {\n return _this.items.append(i);\n });\n }\n\n _createClass(ListSection, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.items.head.headPosition();\n }\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.items.tail.tailPosition();\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newSection = this.builder.createListSection(this.tagName);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.items, function (i) {\n return newSection.items.append(i.clone());\n });\n return newSection;\n }\n\n /**\n * Mutates this list\n * @param {ListSection|Markerable}\n * @return null\n */\n }, {\n key: 'join',\n value: function join(other) {\n var _this2 = this;\n\n if (other.isListSection) {\n other.items.forEach(function (i) {\n return _this2.join(i);\n });\n } else if (other.isMarkerable) {\n var item = this.builder.createListItem();\n item.join(other);\n this.items.append(item);\n }\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.items.isEmpty;\n }\n }]);\n\n return ListSection;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = ListSection;\n});","define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // Unicode uses a pair of \"surrogate\" characters\" (a high- and low-surrogate)\n // to encode characters outside the basic multilingual plane (like emoji and\n // some languages).\n // These values are the unicode code points for the start and end of the\n // high- and low-surrogate characters.\n // See \"high surrogate\" and \"low surrogate\" on\n // https://en.wikipedia.org/wiki/Unicode_block\n var HIGH_SURROGATE_RANGE = [0xD800, 0xDBFF];\n exports.HIGH_SURROGATE_RANGE = HIGH_SURROGATE_RANGE;\n var LOW_SURROGATE_RANGE = [0xDC00, 0xDFFF];\n\n exports.LOW_SURROGATE_RANGE = LOW_SURROGATE_RANGE;\n var Marker = (function (_LinkedItem) {\n _inherits(Marker, _LinkedItem);\n\n function Marker() {\n var _this = this;\n\n var value = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, Marker);\n\n _get(Object.getPrototypeOf(Marker.prototype), 'constructor', this).call(this);\n this.value = value;\n (0, _mobiledocKitUtilsAssert['default'])('Marker must have value', value !== undefined && value !== null);\n this.markups = [];\n this.type = _mobiledocKitModelsTypes.MARKER_TYPE;\n this.isMarker = true;\n this.isAtom = false;\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Marker, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createMarker(this.value, clonedMarkups);\n }\n }, {\n key: 'charAt',\n value: function charAt(offset) {\n return this.value.slice(offset, offset + 1);\n }\n\n /**\n * A marker's text is equal to its value.\n * Compare with an Atom which distinguishes between text and value\n */\n }, {\n key: 'deleteValueAtOffset',\n\n // delete the character at this offset,\n // update the value with the new value\n value: function deleteValueAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot delete value at offset outside bounds', offset >= 0 && offset <= this.length);\n\n var width = 1;\n var code = this.value.charCodeAt(offset);\n if (code >= HIGH_SURROGATE_RANGE[0] && code <= HIGH_SURROGATE_RANGE[1]) {\n width = 2;\n } else if (code >= LOW_SURROGATE_RANGE[0] && code <= LOW_SURROGATE_RANGE[1]) {\n width = 2;\n offset = offset - 1;\n }\n\n var left = this.value.slice(0, offset);\n var right = this.value.slice(offset + width);\n\n this.value = left + right;\n\n return width;\n }\n }, {\n key: 'canJoin',\n value: function canJoin(other) {\n return other && other.isMarker && (0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(this.markups, other.markups);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(offset) {\n return this.value.slice(0, offset);\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? this.length : arguments[1];\n\n var markers = [this.builder.createMarker(this.value.substring(0, offset)), this.builder.createMarker(this.value.substring(offset, endOffset)), this.builder.createMarker(this.value.substring(endOffset))];\n\n this.markups.forEach(function (mu) {\n return markers.forEach(function (m) {\n return m.addMarkup(mu);\n });\n });\n return markers;\n }\n\n /**\n * @return {Array} 2 markers either or both of which could be blank\n */\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n var value = this.value;\n var builder = this.builder;\n\n var pre = builder.createMarker(value.substring(0, offset));\n var post = builder.createMarker(value.substring(offset));\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n\n return [pre, post];\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.isBlank;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.length === 0;\n }\n }, {\n key: 'text',\n get: function get() {\n return this.value;\n }\n }, {\n key: 'length',\n get: function get() {\n return this.value.length;\n }\n }]);\n\n return Marker;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Marker, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Marker;\n});","define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // valid values of `tagName` for a MarkupSection\n var VALID_MARKUP_SECTION_TAGNAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_SECTION_TAGNAMES = VALID_MARKUP_SECTION_TAGNAMES;\n // valid element names for a MarkupSection. A MarkupSection with a tagName\n // not in this will be rendered as a div with a className matching the\n // tagName\n var MARKUP_SECTION_ELEMENT_NAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n exports.MARKUP_SECTION_ELEMENT_NAMES = MARKUP_SECTION_ELEMENT_NAMES;\n var DEFAULT_TAG_NAME = VALID_MARKUP_SECTION_TAGNAMES[8];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n var MarkupSection = (function (_Markerable) {\n _inherits(MarkupSection, _Markerable);\n\n function MarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, MarkupSection);\n\n _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers);\n this.isMarkupSection = true;\n }\n\n _createClass(MarkupSection, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_MARKUP_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var beforeSection = this.builder.createMarkupSection(this.tagName, []);\n var afterSection = this.builder.createMarkupSection();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }]);\n\n return MarkupSection;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = MarkupSection;\n});","define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var VALID_MARKUP_TAGNAMES = ['a', 'b', 'code', 'em', 'i', 's', // strikethrough\n 'strong', 'sub', // subscript\n 'sup', // superscript\n 'u'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_TAGNAMES = VALID_MARKUP_TAGNAMES;\n var VALID_ATTRIBUTES = ['href', 'rel'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n\n var Markup = (function () {\n /*\n * @param {Object} attributes key-values\n */\n\n function Markup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, Markup);\n\n this.tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must use attributes object param (not array) for Markup', !Array.isArray(attributes));\n\n this.attributes = (0, _mobiledocKitUtilsArrayUtils.filterObject)(attributes, VALID_ATTRIBUTES);\n this.type = _mobiledocKitModelsTypes.MARKUP_TYPE;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1);\n }\n\n _createClass(Markup, [{\n key: 'isForwardInclusive',\n value: function isForwardInclusive() {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(\"a\") ? false : true;\n }\n }, {\n key: 'isBackwardInclusive',\n value: function isBackwardInclusive() {\n return false;\n }\n }, {\n key: 'hasTag',\n value: function hasTag(tagName) {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n }\n }, {\n key: 'getAttribute',\n value: function getAttribute(name) {\n return this.attributes[name];\n }\n }], [{\n key: 'isValidElement',\n value: function isValidElement(element) {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n return VALID_MARKUP_TAGNAMES.indexOf(tagName) !== -1;\n }\n }]);\n\n return Markup;\n })();\n\n exports['default'] = Markup;\n});","define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/models/atom', 'mobiledoc-kit/models/post', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/image', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsAtom, _mobiledocKitModelsPost, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsImage, _mobiledocKitModelsMarker, _mobiledocKitModelsMarkup, _mobiledocKitModelsCard, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function cacheKey(tagName, attributes) {\n return (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName) + '-' + (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(attributes).join('-');\n }\n\n function addMarkupToCache(cache, markup) {\n cache[cacheKey(markup.tagName, markup.attributes)] = markup;\n }\n\n function findMarkupInCache(cache, tagName, attributes) {\n var key = cacheKey(tagName, attributes);\n return cache[key];\n }\n\n /**\n * The PostNodeBuilder is used to create new {@link Post} primitives, such\n * as a MarkupSection, a CardSection, a Markup, etc. Every instance of an\n * {@link Editor} has its own builder instance. The builder can be used\n * inside an {@link Editor#run} callback to programmatically create new\n * Post primitives to insert into the document.\n * A PostNodeBuilder should be read from the Editor, *not* instantiated on its own.\n */\n\n var PostNodeBuilder = (function () {\n /**\n * @private\n */\n\n function PostNodeBuilder() {\n _classCallCheck(this, PostNodeBuilder);\n\n this.markupCache = {};\n }\n\n /**\n * @return {Post} A new, blank post\n */\n\n _createClass(PostNodeBuilder, [{\n key: 'createPost',\n value: function createPost() {\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var post = new _mobiledocKitModelsPost['default']();\n post.builder = this;\n\n sections.forEach(function (s) {\n return post.sections.append(s);\n });\n\n return post;\n }\n }, {\n key: 'createMarkerableSection',\n value: function createMarkerableSection(type, tagName) {\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.createListItem(markers);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.createMarkupSection(tagName, markers);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markerable section of type ' + type, false);\n }\n }\n\n /**\n * @param {tagName} [tagName='P']\n * @param {Marker[]} [markers=[]]\n * @return {MarkupSection}\n */\n }, {\n key: 'createMarkupSection',\n value: function createMarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0];\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers);\n if (isGenerated) {\n section.isGenerated = true;\n }\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListSection',\n value: function createListSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0];\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsListSection['default'](tagName, items);\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListItem',\n value: function createListItem() {\n var markers = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('li');\n var item = new _mobiledocKitModelsListItem['default'](tagName, markers);\n item.builder = this;\n return item;\n }\n }, {\n key: 'createImageSection',\n value: function createImageSection(url) {\n var section = new _mobiledocKitModelsImage['default']();\n if (url) {\n section.src = url;\n }\n return section;\n }\n\n /**\n * @param {String} name\n * @param {Object} [payload={}]\n * @return {CardSection}\n */\n }, {\n key: 'createCardSection',\n value: function createCardSection(name) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var card = new _mobiledocKitModelsCard['default'](name, payload);\n card.builder = this;\n return card;\n }\n\n /**\n * @param {String} value\n * @param {Markup[]} [markups=[]]\n * @return {Marker}\n */\n }, {\n key: 'createMarker',\n value: function createMarker(value) {\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var marker = new _mobiledocKitModelsMarker['default'](value, markups);\n marker.builder = this;\n return marker;\n }\n\n /**\n * @param {String} name\n * @param {String} [value='']\n * @param {Object} [payload={}]\n * @param {Markup[]} [markups=[]]\n * @return {Atom}\n */\n }, {\n key: 'createAtom',\n value: function createAtom(name) {\n var value = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var payload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n var atom = new _mobiledocKitModelsAtom['default'](name, value, payload, markups);\n atom.builder = this;\n return atom;\n }\n\n /**\n * @param {String} tagName\n * @param {Object} attributes Key-value pairs of attributes for the markup\n * @return {Markup}\n */\n }, {\n key: 'createMarkup',\n value: function createMarkup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n var markup = findMarkupInCache(this.markupCache, tagName, attributes);\n if (!markup) {\n markup = new _mobiledocKitModelsMarkup['default'](tagName, attributes);\n markup.builder = this;\n addMarkupToCache(this.markupCache, markup);\n }\n\n return markup;\n }\n }]);\n\n return PostNodeBuilder;\n })();\n\n exports['default'] = PostNodeBuilder;\n});","define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * The Post is an in-memory representation of an editor's document.\n * An editor always has a single post. The post is organized into a list of\n * sections. Each section may be markerable (contains \"markers\", aka editable\n * text) or non-markerable (e.g., a card).\n * When persisting a post, it must first be serialized (loss-lessly) into\n * mobiledoc using {@link Editor#serialize}.\n */\n\n var Post = (function () {\n /**\n * @private\n */\n\n function Post() {\n var _this = this;\n\n _classCallCheck(this, Post);\n\n this.type = _mobiledocKitModelsTypes.POST_TYPE;\n this.sections = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(s) {\n return s.post = s.parent = _this;\n },\n freeItem: function freeItem(s) {\n return s.post = s.parent = null;\n }\n });\n }\n\n /**\n * @return {Position} The position at the start of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n\n _createClass(Post, [{\n key: 'headPosition',\n value: function headPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.head.headPosition();\n }\n }\n\n /**\n * @return {Position} The position at the end of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.tail.tailPosition();\n }\n }\n\n /**\n * @return {Range} A range encompassing the entire post\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'markersContainedByRange',\n\n /**\n * @param {Range} range\n * @return {Array} markers that are completely contained by the range\n */\n value: function markersContainedByRange(range) {\n var markers = [];\n\n this.walkMarkerableSections(range, function (section) {\n section._markersInRange(range.trimTo(section), function (m, _ref) {\n var isContained = _ref.isContained;\n if (isContained) {\n markers.push(m);\n }\n });\n });\n\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n\n if (range.isCollapsed) {\n var pos = range.head;\n if (pos.isMarkerable) {\n var back = pos.markerIn(-1);\n var forward = pos.markerIn(1);\n\n if (back && forward && back === forward) {\n back.markups.forEach(function (m) {\n return markups.add(m);\n });\n } else {\n (back && back.markups || []).forEach(function (m) {\n if (m.isForwardInclusive()) {\n markups.add(m);\n }\n });\n (forward && forward.markups || []).forEach(function (m) {\n if (m.isBackwardInclusive()) {\n markups.add(m);\n }\n });\n }\n }\n } else {\n this.walkMarkerableSections(range, function (section) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markupsInRange(range.trimTo(section)), function (m) {\n return markups.add(m);\n });\n });\n }\n\n return markups.toArray();\n }\n }, {\n key: 'walkAllLeafSections',\n value: function walkAllLeafSections(callback) {\n var range = this.headPosition().toRange(this.tailPosition());\n return this.walkLeafSections(range, callback);\n }\n }, {\n key: 'walkLeafSections',\n value: function walkLeafSections(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n var index = 0;\n var nextSection = undefined,\n shouldStop = undefined;\n var currentSection = head.section;\n\n while (currentSection) {\n nextSection = this._nextLeafSection(currentSection);\n shouldStop = currentSection === tail.section;\n\n callback(currentSection, index);\n index++;\n\n if (shouldStop) {\n break;\n } else {\n currentSection = nextSection;\n }\n }\n }\n }, {\n key: 'walkMarkerableSections',\n value: function walkMarkerableSections(range, callback) {\n this.walkLeafSections(range, function (section) {\n if (section.isMarkerable) {\n callback(section);\n }\n });\n }\n\n // return the next section that has markers after this one,\n // possibly skipping non-markerable sections\n }, {\n key: '_nextLeafSection',\n value: function _nextLeafSection(section) {\n if (!section) {\n return null;\n }\n\n var next = section.next;\n if (next) {\n if (next.isLeafSection) {\n return next;\n } else if (!!next.items) {\n return next.items.head;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false);\n }\n } else if (section.isNested) {\n // if there is no section after this, but this section is a child\n // (e.g. a ListItem inside a ListSection), check for a markerable\n // section after its parent\n return this._nextLeafSection(section.parent);\n }\n }\n\n /**\n * @param {Range} range\n * @return {Post} A new post, constrained to {range}\n */\n }, {\n key: 'trimTo',\n value: function trimTo(range) {\n var post = this.builder.createPost();\n var builder = this.builder;\n\n var sectionParent = post,\n listParent = null;\n this.walkLeafSections(range, function (section) {\n var newSection = undefined;\n if (section.isMarkerable) {\n if (section.isListItem) {\n if (listParent) {\n sectionParent = null;\n } else {\n listParent = builder.createListSection(section.parent.tagName);\n post.sections.append(listParent);\n sectionParent = null;\n }\n newSection = builder.createListItem();\n listParent.items.append(newSection);\n } else {\n listParent = null;\n sectionParent = post;\n newSection = builder.createMarkupSection(section.tagName);\n }\n\n var currentRange = range.trimTo(section);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markersFor(currentRange.headSectionOffset, currentRange.tailSectionOffset), function (m) {\n return newSection.markers.append(m);\n });\n } else {\n newSection = section.clone();\n }\n if (sectionParent) {\n sectionParent.sections.append(newSection);\n }\n });\n return post;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.sections.isEmpty;\n }\n\n /**\n * If the post has no sections, or only has one, blank section, then it does\n * not have content and this method returns false. Otherwise it is true.\n * @return {Boolean}\n * @public\n */\n }, {\n key: 'hasContent',\n get: function get() {\n if (this.sections.length > 1 || this.sections.length === 1 && !this.sections.head.isBlank) {\n return true;\n } else {\n return false;\n }\n }\n }]);\n\n return Post;\n })();\n\n exports['default'] = Post;\n});","define('mobiledoc-kit/models/render-node', ['exports', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var RenderNode = (function (_LinkedItem) {\n _inherits(RenderNode, _LinkedItem);\n\n function RenderNode(postNode, renderTree) {\n _classCallCheck(this, RenderNode);\n\n _get(Object.getPrototypeOf(RenderNode.prototype), 'constructor', this).call(this);\n this.parent = null;\n this.isDirty = true;\n this.isRemoved = false;\n this.postNode = postNode;\n this._childNodes = null;\n this._element = null;\n this._cursorElement = null; // blank render nodes need a cursor element\n this.renderTree = renderTree;\n\n // RenderNodes for Markers keep track of their markupElement\n this.markupElement = null;\n\n // RenderNodes for Atoms use these properties\n this.headTextNode = null;\n this.tailTextNode = null;\n this.atomNode = null;\n\n // RenderNodes for cards use this property\n this.cardNode = null;\n }\n\n _createClass(RenderNode, [{\n key: 'isAttached',\n value: function isAttached() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot check if a renderNode is attached without an element.', !!this.element);\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(this.renderTree.rootElement, this.element);\n }\n }, {\n key: 'scheduleForRemoval',\n value: function scheduleForRemoval() {\n this.isRemoved = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markDirty',\n value: function markDirty() {\n this.isDirty = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markClean',\n value: function markClean() {\n this.isDirty = false;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.element = null;\n this.parent = null;\n this.postNode = null;\n this.renderTree = null;\n }\n }, {\n key: 'reparsesMutationOfChildNode',\n value: function reparsesMutationOfChildNode(node) {\n if (this.postNode.isCardSection) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.cardNode.element, node);\n } else if (this.postNode.isAtom) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.atomNode.element, node);\n }\n return true;\n }\n }, {\n key: 'childNodes',\n get: function get() {\n var _this = this;\n\n if (!this._childNodes) {\n this._childNodes = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(item) {\n return item.parent = _this;\n },\n freeItem: function freeItem(item) {\n return item.destroy();\n }\n });\n }\n return this._childNodes;\n }\n }, {\n key: 'isRendered',\n get: function get() {\n return !!this.element;\n }\n }, {\n key: 'element',\n set: function set(element) {\n var currentElement = this._element;\n this._element = element;\n\n if (currentElement) {\n this.renderTree.removeElementRenderNode(currentElement);\n }\n\n if (element) {\n this.renderTree.setElementRenderNode(element, this);\n }\n },\n get: function get() {\n return this._element;\n }\n }, {\n key: 'cursorElement',\n set: function set(cursorElement) {\n this._cursorElement = cursorElement;\n },\n get: function get() {\n return this._cursorElement || this.element;\n }\n }]);\n\n return RenderNode;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = RenderNode;\n});","define('mobiledoc-kit/models/render-tree', ['exports', 'mobiledoc-kit/models/render-node', 'mobiledoc-kit/utils/element-map'], function (exports, _mobiledocKitModelsRenderNode, _mobiledocKitUtilsElementMap) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var RenderTree = (function () {\n function RenderTree(rootPostNode) {\n _classCallCheck(this, RenderTree);\n\n this._rootNode = this.buildRenderNode(rootPostNode);\n this._elements = new _mobiledocKitUtilsElementMap['default']();\n }\n\n /*\n * @return {RenderNode} The root render node in this tree\n */\n\n _createClass(RenderTree, [{\n key: 'getElementRenderNode',\n\n /*\n * @param {DOMNode} element\n * @return {RenderNode} The renderNode for this element, if any\n */\n value: function getElementRenderNode(element) {\n return this._elements.get(element);\n }\n }, {\n key: 'setElementRenderNode',\n value: function setElementRenderNode(element, renderNode) {\n this._elements.set(element, renderNode);\n }\n }, {\n key: 'removeElementRenderNode',\n value: function removeElementRenderNode(element) {\n this._elements.remove(element);\n }\n\n /**\n * @param {DOMNode} element\n * Walk up from the dom element until we find a renderNode element\n */\n }, {\n key: 'findRenderNodeFromElement',\n value: function findRenderNodeFromElement(element) {\n var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {\n return true;\n } : arguments[1];\n\n var renderNode = undefined;\n while (element) {\n renderNode = this.getElementRenderNode(element);\n if (renderNode && conditionFn(renderNode)) {\n return renderNode;\n }\n\n // continue loop\n element = element.parentNode;\n\n // stop if we are at the root element\n if (element === this.rootElement) {\n if (conditionFn(this.rootNode)) {\n return this.rootNode;\n } else {\n return;\n }\n }\n }\n }\n }, {\n key: 'buildRenderNode',\n value: function buildRenderNode(postNode) {\n var renderNode = new _mobiledocKitModelsRenderNode['default'](postNode, this);\n postNode.renderNode = renderNode;\n return renderNode;\n }\n }, {\n key: 'rootNode',\n get: function get() {\n return this._rootNode;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'isDirty',\n get: function get() {\n return this.rootNode && this.rootNode.isDirty;\n }\n\n /*\n * @return {DOMNode} The root DOM element in this tree\n */\n }, {\n key: 'rootElement',\n get: function get() {\n return this.rootNode.element;\n }\n }]);\n\n return RenderTree;\n })();\n\n exports['default'] = RenderTree;\n});","define('mobiledoc-kit/models/types', ['exports'], function (exports) {\n 'use strict';\n\n var MARKUP_SECTION_TYPE = 'markup-section';\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var LIST_SECTION_TYPE = 'list-section';\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var MARKUP_TYPE = 'markup';\n exports.MARKUP_TYPE = MARKUP_TYPE;\n var MARKER_TYPE = 'marker';\n exports.MARKER_TYPE = MARKER_TYPE;\n var POST_TYPE = 'post';\n exports.POST_TYPE = POST_TYPE;\n var LIST_ITEM_TYPE = 'list-item';\n exports.LIST_ITEM_TYPE = LIST_ITEM_TYPE;\n var CARD_TYPE = 'card-section';\n exports.CARD_TYPE = CARD_TYPE;\n var IMAGE_SECTION_TYPE = 'image-section';\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var ATOM_TYPE = 'atom';\n exports.ATOM_TYPE = ATOM_TYPE;\n});","define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/parsers/section', 'mobiledoc-kit/models/markup'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCharacters, _mobiledocKitParsersSection, _mobiledocKitModelsMarkup) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.transformHTMLText = transformHTMLText;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var GOOGLE_DOCS_CONTAINER_ID_REGEX = /^docs\\-internal\\-guid/;\n\n var NO_BREAK_SPACE_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.NO_BREAK_SPACE, 'g');\n var TAB_CHARACTER_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.TAB_CHARACTER, 'g');\n\n function transformHTMLText(textContent) {\n var text = textContent;\n text = text.replace(NO_BREAK_SPACE_REGEX, ' ');\n text = text.replace(TAB_CHARACTER_REGEX, _mobiledocKitUtilsCharacters.TAB);\n return text;\n }\n\n function isGoogleDocsContainer(element) {\n return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id);\n }\n\n function detectRootElement(element) {\n var childNodes = element.childNodes || [];\n var googleDocsContainer = (0, _mobiledocKitUtilsArrayUtils.detect)(childNodes, isGoogleDocsContainer);\n\n if (googleDocsContainer) {\n return googleDocsContainer;\n } else {\n return element;\n }\n }\n\n var TAG_REMAPPING = {\n 'b': 'strong',\n 'i': 'em'\n };\n\n function remapTagName(tagName) {\n var normalized = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var remapped = TAG_REMAPPING[normalized];\n return remapped || normalized;\n }\n\n function trim(str) {\n return str.replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n\n function walkMarkerableNodes(parent, callback) {\n var currentNode = parent;\n\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(currentNode) || (0, _mobiledocKitUtilsDomUtils.isElementNode)(currentNode) && currentNode.classList.contains(_mobiledocKitRenderersEditorDom.ATOM_CLASS_NAME)) {\n callback(currentNode);\n } else {\n currentNode = currentNode.firstChild;\n while (currentNode) {\n walkMarkerableNodes(currentNode, callback);\n currentNode = currentNode.nextSibling;\n }\n }\n }\n\n /**\n * Parses DOM element -> Post\n * @private\n */\n\n var DOMParser = (function () {\n function DOMParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, DOMParser);\n\n this.builder = builder;\n this.sectionParser = new _mobiledocKitParsersSection['default'](this.builder, options);\n }\n\n _createClass(DOMParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n var post = this.builder.createPost();\n var rootElement = detectRootElement(element);\n\n this._eachChildNode(rootElement, function (child) {\n var sections = _this.parseSections(child);\n _this.appendSections(post, sections);\n });\n\n return post;\n }\n }, {\n key: 'appendSections',\n value: function appendSections(post, sections) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(sections, function (section) {\n return _this2.appendSection(post, section);\n });\n }\n }, {\n key: 'appendSection',\n value: function appendSection(post, section) {\n if (section.isBlank || section.isMarkerable && trim(section.text) === '') {\n return;\n }\n\n var lastSection = post.sections.tail;\n if (lastSection && lastSection._inferredTagName && section._inferredTagName && lastSection.tagName === section.tagName) {\n lastSection.join(section);\n } else {\n post.sections.append(section);\n }\n }\n }, {\n key: '_eachChildNode',\n value: function _eachChildNode(element, callback) {\n var nodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n return callback(node);\n });\n }\n }, {\n key: 'parseSections',\n value: function parseSections(element) {\n return this.sectionParser.parse(element);\n }\n\n // walk up from the textNode until the rootNode, converting each\n // parentNode into a markup\n }, {\n key: 'collectMarkups',\n value: function collectMarkups(textNode, rootNode) {\n var markups = [];\n var currentNode = textNode.parentNode;\n while (currentNode && currentNode !== rootNode) {\n var markup = this.markupFromNode(currentNode);\n if (markup) {\n markups.push(markup);\n }\n\n currentNode = currentNode.parentNode;\n }\n return markups;\n }\n\n // Turn an element node into a markup\n }, {\n key: 'markupFromNode',\n value: function markupFromNode(node) {\n if (_mobiledocKitModelsMarkup['default'].isValidElement(node)) {\n var tagName = remapTagName(node.tagName);\n var attributes = (0, _mobiledocKitUtilsDomUtils.getAttributes)(node);\n return this.builder.createMarkup(tagName, attributes);\n }\n }\n\n // FIXME should move to the section parser?\n // FIXME the `collectMarkups` logic could simplify the section parser?\n }, {\n key: 'reparseSection',\n value: function reparseSection(section, renderTree) {\n switch (section.type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n return this.reparseListSection(section, renderTree);\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.reparseListItem(section, renderTree);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.reparseMarkupSection(section, renderTree);\n default:\n return; // can only parse the above types\n }\n }\n }, {\n key: 'reparseMarkupSection',\n value: function reparseMarkupSection(section, renderTree) {\n return this._reparseSectionContainingMarkers(section, renderTree);\n }\n }, {\n key: 'reparseListItem',\n value: function reparseListItem(listItem, renderTree) {\n return this._reparseSectionContainingMarkers(listItem, renderTree);\n }\n }, {\n key: 'reparseListSection',\n value: function reparseListSection(listSection, renderTree) {\n var _this3 = this;\n\n listSection.items.forEach(function (li) {\n return _this3.reparseListItem(li, renderTree);\n });\n }\n }, {\n key: '_reparseSectionContainingMarkers',\n value: function _reparseSectionContainingMarkers(section, renderTree) {\n var _this4 = this;\n\n var element = section.renderNode.element;\n var seenRenderNodes = [];\n var previousMarker = undefined;\n\n walkMarkerableNodes(element, function (node) {\n var marker = undefined;\n var renderNode = renderTree.getElementRenderNode(node);\n if (renderNode) {\n if (renderNode.postNode.isMarker) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n if (text.length) {\n marker = renderNode.postNode;\n marker.value = text;\n marker.markups = markups;\n } else {\n renderNode.scheduleForRemoval();\n }\n } else if (renderNode.postNode.isAtom) {\n var _renderNode = renderNode;\n var headTextNode = _renderNode.headTextNode;\n var tailTextNode = _renderNode.tailTextNode;\n\n if (headTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = headTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n headTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n if (previousMarker && previousMarker.isMarker) {\n previousMarker.value += value;\n if (previousMarker.renderNode) {\n previousMarker.renderNode.markDirty();\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newPreviousMarker = _this4.builder.createMarker(value, newMarkups);\n section.markers.insertBefore(newPreviousMarker, postNode);\n\n var newPreviousRenderNode = renderTree.buildRenderNode(newPreviousMarker);\n newPreviousRenderNode.markDirty();\n section.renderNode.markDirty();\n\n seenRenderNodes.push(newPreviousRenderNode);\n section.renderNode.childNodes.insertBefore(newPreviousRenderNode, renderNode);\n }\n }\n if (tailTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = tailTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n tailTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n\n if (renderNode.postNode.next && renderNode.postNode.next.isMarker) {\n var nextMarker = renderNode.postNode.next;\n\n if (nextMarker.renderNode) {\n var nextValue = nextMarker.renderNode.element.textContent;\n nextMarker.renderNode.element.textContent = value + nextValue;\n } else {\n var nextValue = value + nextMarker.value;\n nextMarker.value = nextValue;\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newMarker = _this4.builder.createMarker(value, newMarkups);\n\n section.markers.insertAfter(newMarker, postNode);\n\n var newRenderNode = renderTree.buildRenderNode(newMarker);\n seenRenderNodes.push(newRenderNode);\n\n newRenderNode.markDirty();\n section.renderNode.markDirty();\n\n section.renderNode.childNodes.insertAfter(newRenderNode, renderNode);\n }\n }\n if (renderNode) {\n marker = renderNode.postNode;\n }\n }\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n marker = _this4.builder.createMarker(text, markups);\n\n renderNode = renderTree.buildRenderNode(marker);\n renderNode.element = node;\n renderNode.markClean();\n section.renderNode.markDirty();\n\n var previousRenderNode = previousMarker && previousMarker.renderNode;\n section.markers.insertAfter(marker, previousMarker);\n section.renderNode.childNodes.insertAfter(renderNode, previousRenderNode);\n }\n\n if (renderNode) {\n seenRenderNodes.push(renderNode);\n }\n previousMarker = marker;\n });\n\n var renderNode = section.renderNode.childNodes.head;\n while (renderNode) {\n if (seenRenderNodes.indexOf(renderNode) === -1) {\n renderNode.scheduleForRemoval();\n }\n renderNode = renderNode.next;\n }\n }\n }]);\n\n return DOMParser;\n })();\n\n exports['default'] = DOMParser;\n});","define('mobiledoc-kit/parsers/html', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/parsers/dom'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitParsersDom) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var HTMLParser = (function () {\n function HTMLParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, HTMLParser);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass builder to HTMLParser', builder);\n this.builder = builder;\n this.options = options;\n }\n\n /**\n * @param {String} html to parse\n * @return {Post} A post abstract\n */\n\n _createClass(HTMLParser, [{\n key: 'parse',\n value: function parse(html) {\n var dom = (0, _mobiledocKitUtilsDomUtils.parseHTML)(html);\n var parser = new _mobiledocKitParsersDom['default'](this.builder, this.options);\n return parser.parse(dom);\n }\n }]);\n\n return HTMLParser;\n })();\n\n exports['default'] = HTMLParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var version = _ref.version;\n var sectionData = _ref.sections;\n\n try {\n var markerTypes = sectionData[0];\n var sections = sectionData[1];\n\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this2 = this;\n\n sections.forEach(function (section) {\n return _this2.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ' + type, false);\n }\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref3, post) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var type = _ref32[0];\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref4, post) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var src = _ref42[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 3);\n\n var type = _ref62[0];\n var tagName = _ref62[1];\n var items = _ref62[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this3 = this;\n\n items.forEach(function (i) {\n return _this3.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this4 = this;\n\n markers.forEach(function (m) {\n return _this4.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref7, parent) {\n var _this5 = this;\n\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var markerTypeIndexes = _ref72[0];\n var closeCount = _ref72[1];\n var value = _ref72[2];\n\n markerTypeIndexes.forEach(function (index) {\n _this5.markups.push(_this5.markerTypes[index]);\n });\n var marker = this.builder.createMarker(value, this.markups.slice());\n parent.markers.append(marker);\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var version = _ref.version;\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var type = _ref52[0];\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var type = _ref62[0];\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var type = _ref72[0];\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var type = _ref82[0];\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE:\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value),\n _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3),\n atomName = _getAtomTypeFromIndex2[0],\n atomValue = _getAtomTypeFromIndex2[1],\n atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc03, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var version = _ref.version;\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var type = _ref52[0];\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var type = _ref62[0];\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var type = _ref72[0];\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var type = _ref82[0];\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE:\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value),\n _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3),\n atomName = _getAtomTypeFromIndex2[0],\n atomValue = _getAtomTypeFromIndex2[1],\n atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n function parseVersion(mobiledoc) {\n return mobiledoc.version;\n }\n\n exports['default'] = {\n parse: function parse(builder, mobiledoc) {\n var version = parseVersion(mobiledoc);\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc02['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false);\n }\n }\n };\n});","define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkup, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitParsersDom, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SKIPPABLE_ELEMENT_TAG_NAMES = ['style', 'head', 'title', 'meta'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n var NEWLINES = /\\n/g;\n function sanitize(text) {\n text = text.replace(NEWLINES, '');\n return text;\n }\n\n /**\n * parses an element into a section, ignoring any non-markup\n * elements contained within\n * @private\n */\n\n var SectionParser = (function () {\n function SectionParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, SectionParser);\n\n this.builder = builder;\n this.plugins = options.plugins || [];\n }\n\n _createClass(SectionParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n if (this._isSkippable(element)) {\n return [];\n }\n this.sections = [];\n this.state = {};\n\n this._updateStateFromElement(element);\n\n var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n\n if (this.state.section.isListSection) {\n this.parseListItems(childNodes);\n } else {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n _this.parseNode(el);\n });\n }\n\n this._closeCurrentSection();\n\n return this.sections;\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(childNodes) {\n var _this2 = this;\n\n var state = this.state;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n var parsed = new _this2.constructor(_this2.builder).parse(el);\n var li = parsed[0];\n if (li && li.isListItem) {\n state.section.items.append(li);\n }\n });\n }\n }, {\n key: 'runPlugins',\n value: function runPlugins(node) {\n var _this3 = this;\n\n var isNodeFinished = false;\n var env = {\n addSection: function addSection(section) {\n _this3._closeCurrentSection();\n _this3.sections.push(section);\n },\n addMarkerable: function addMarkerable(marker) {\n var state = _this3.state;\n var section = state.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable);\n if (state.text) {\n _this3._createMarker();\n }\n section.markers.append(marker);\n },\n nodeFinished: function nodeFinished() {\n isNodeFinished = true;\n }\n };\n for (var i = 0; i < this.plugins.length; i++) {\n var plugin = this.plugins[i];\n plugin(node, this.builder, env);\n if (isNodeFinished) {\n return true;\n }\n }\n return false;\n }\n }, {\n key: 'parseNode',\n value: function parseNode(node) {\n if (!this.state.section) {\n this._updateStateFromElement(node);\n }\n\n var nodeFinished = this.runPlugins(node);\n if (nodeFinished) {\n return;\n }\n\n switch (node.nodeType) {\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT:\n this.parseTextNode(node);\n break;\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT:\n this.parseElementNode(node);\n break;\n }\n }\n }, {\n key: 'parseElementNode',\n value: function parseElementNode(element) {\n var _state$markups,\n _this4 = this;\n\n var state = this.state;\n\n var markups = this._markupsFromElement(element);\n if (markups.length && state.text.length) {\n this._createMarker();\n }\n (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups));\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.childNodes, function (node) {\n _this4.parseNode(node);\n });\n\n if (markups.length && state.text.length) {\n // create the marker started for this node\n this._createMarker();\n }\n\n // pop the current markups from the stack\n state.markups.splice(-markups.length, markups.length);\n }\n }, {\n key: 'parseTextNode',\n value: function parseTextNode(textNode) {\n var state = this.state;\n\n state.text += sanitize(textNode.textContent);\n }\n }, {\n key: '_updateStateFromElement',\n value: function _updateStateFromElement(element) {\n var state = this.state;\n\n state.section = this._createSectionFromElement(element);\n state.markups = this._markupsFromElement(element);\n state.text = '';\n }\n }, {\n key: '_closeCurrentSection',\n value: function _closeCurrentSection() {\n var sections = this.sections;\n var state = this.state;\n\n if (!state.section) {\n return;\n }\n\n // close a trailing text node if it exists\n if (state.text.length) {\n this._createMarker();\n }\n\n sections.push(state.section);\n state.section = null;\n }\n }, {\n key: '_markupsFromElement',\n value: function _markupsFromElement(element) {\n var builder = this.builder;\n\n var markups = [];\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n return markups;\n }\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n if (this._isValidMarkupForElement(tagName, element)) {\n markups.push(builder.createMarkup(tagName, (0, _mobiledocKitUtilsDomUtils.getAttributes)(element)));\n }\n\n this._markupsFromElementStyle(element).forEach(function (markup) {\n return markups.push(markup);\n });\n\n return markups;\n }\n }, {\n key: '_isValidMarkupForElement',\n value: function _isValidMarkupForElement(tagName, element) {\n if (_mobiledocKitModelsMarkup.VALID_MARKUP_TAGNAMES.indexOf(tagName) === -1) {\n return false;\n } else if (tagName === 'b') {\n // google docs add a that should not\n // create a \"b\" markup\n return element.style.fontWeight !== 'normal';\n }\n return true;\n }\n }, {\n key: '_markupsFromElementStyle',\n value: function _markupsFromElementStyle(element) {\n var builder = this.builder;\n\n var markups = [];\n var _element$style = element.style;\n var fontStyle = _element$style.fontStyle;\n var fontWeight = _element$style.fontWeight;\n\n if (fontStyle === 'italic') {\n markups.push(builder.createMarkup('em'));\n }\n if (fontWeight === 'bold' || fontWeight === '700') {\n markups.push(builder.createMarkup('strong'));\n }\n return markups;\n }\n }, {\n key: '_createMarker',\n value: function _createMarker() {\n var state = this.state;\n\n var text = (0, _mobiledocKitParsersDom.transformHTMLText)(state.text);\n var marker = this.builder.createMarker(text, state.markups);\n state.section.markers.append(marker);\n state.text = '';\n }\n }, {\n key: '_getSectionDetails',\n value: function _getSectionDetails(element) {\n var sectionType = undefined,\n tagName = undefined,\n inferredTagName = false;\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n inferredTagName = true;\n } else {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_ITEM_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n } else {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n inferredTagName = true;\n }\n }\n\n return { sectionType: sectionType, tagName: tagName, inferredTagName: inferredTagName };\n }\n }, {\n key: '_createSectionFromElement',\n value: function _createSectionFromElement(element) {\n var builder = this.builder;\n\n var section = undefined;\n\n var _getSectionDetails2 = this._getSectionDetails(element);\n\n var tagName = _getSectionDetails2.tagName;\n var sectionType = _getSectionDetails2.sectionType;\n var inferredTagName = _getSectionDetails2.inferredTagName;\n\n switch (sectionType) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n section = builder.createListSection(tagName);\n break;\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n section = builder.createListItem();\n break;\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = builder.createMarkupSection(tagName);\n section._inferredTagName = inferredTagName;\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot parse section from element', false);\n }\n\n return section;\n }\n }, {\n key: '_isSkippable',\n value: function _isSkippable(element) {\n return (0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) || element.nodeType === _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT && (0, _mobiledocKitUtilsArrayUtils.contains)(SKIPPABLE_ELEMENT_TAG_NAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName));\n }\n }]);\n\n return SectionParser;\n })();\n\n exports['default'] = SectionParser;\n});","define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup-section'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkupSection) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var UL_LI_REGEX = /^\\* (.*)$/;\n var OL_LI_REGEX = /^\\d\\.? (.*)$/;\n var CR = '\\r';\n var LF = '\\n';\n var CR_REGEX = new RegExp(CR, 'g');\n var CR_LF_REGEX = new RegExp(CR + LF, 'g');\n\n var SECTION_BREAK = LF;\n\n exports.SECTION_BREAK = SECTION_BREAK;\n function normalizeLineEndings(text) {\n return text.replace(CR_LF_REGEX, LF).replace(CR_REGEX, LF);\n }\n\n var TextParser = (function () {\n function TextParser(builder, options) {\n _classCallCheck(this, TextParser);\n\n this.builder = builder;\n this.options = options;\n\n this.post = this.builder.createPost();\n this.prevSection = null;\n }\n\n /**\n * @param {String} text to parse\n * @return {Post} a post abstract\n */\n\n _createClass(TextParser, [{\n key: 'parse',\n value: function parse(text) {\n var _this = this;\n\n text = normalizeLineEndings(text);\n text.split(SECTION_BREAK).forEach(function (text) {\n var section = _this._parseSection(text);\n _this._appendSection(section);\n });\n\n return this.post;\n }\n }, {\n key: '_parseSection',\n value: function _parseSection(text) {\n var tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME,\n type = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n section = undefined;\n\n if (UL_LI_REGEX.test(text)) {\n tagName = 'ul';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(UL_LI_REGEX)[1];\n } else if (OL_LI_REGEX.test(text)) {\n tagName = 'ol';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(OL_LI_REGEX)[1];\n }\n\n var markers = [this.builder.createMarker(text)];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n var item = this.builder.createListItem(markers);\n var list = this.builder.createListSection(tagName, [item]);\n section = list;\n break;\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = this.builder.createMarkupSection(tagName, markers);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown type encountered ' + type, false);\n }\n\n return section;\n }\n }, {\n key: '_appendSection',\n value: function _appendSection(section) {\n var _this2 = this;\n\n var isSameListSection = section.isListSection && this.prevSection && this.prevSection.isListSection && this.prevSection.tagName === section.tagName;\n\n if (isSameListSection) {\n section.items.forEach(function (item) {\n _this2.prevSection.items.append(item.clone());\n });\n } else {\n this.post.sections.insertAfter(section, this.prevSection);\n this.prevSection = section;\n }\n }\n }]);\n\n return TextParser;\n })();\n\n exports['default'] = TextParser;\n});","define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/card-node', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/atom-node', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitModelsCardNode, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsAtomNode, _mobiledocKitModelsTypes, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitModelsMarkupSection, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCharacters) {\n 'use strict';\n\n var _destroyHooks;\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CARD_ELEMENT_CLASS_NAME = '__mobiledoc-card';\n exports.CARD_ELEMENT_CLASS_NAME = CARD_ELEMENT_CLASS_NAME;\n var NO_BREAK_SPACE = ' ';\n exports.NO_BREAK_SPACE = NO_BREAK_SPACE;\n var TAB_CHARACTER = ' ';\n exports.TAB_CHARACTER = TAB_CHARACTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n var ZWNJ = '‌';\n exports.ZWNJ = ZWNJ;\n var ATOM_CLASS_NAME = '-mobiledoc-kit__atom';\n exports.ATOM_CLASS_NAME = ATOM_CLASS_NAME;\n var EDITOR_HAS_NO_CONTENT_CLASS_NAME = '__has-no-content';\n exports.EDITOR_HAS_NO_CONTENT_CLASS_NAME = EDITOR_HAS_NO_CONTENT_CLASS_NAME;\n var EDITOR_ELEMENT_CLASS_NAME = '__mobiledoc-editor';\n\n exports.EDITOR_ELEMENT_CLASS_NAME = EDITOR_ELEMENT_CLASS_NAME;\n function createElementFromMarkup(doc, markup) {\n var element = doc.createElement(markup.tagName);\n Object.keys(markup.attributes).forEach(function (k) {\n element.setAttribute(k, markup.attributes[k]);\n });\n return element;\n }\n\n var TWO_SPACES = '' + SPACE + SPACE;\n var SPACE_AND_NO_BREAK = '' + SPACE + NO_BREAK_SPACE;\n var SPACES_REGEX = new RegExp(TWO_SPACES, 'g');\n var TAB_REGEX = new RegExp(_mobiledocKitUtilsCharacters.TAB, 'g');\n var endsWithSpace = function endsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.endsWith)(text, SPACE);\n };\n var startsWithSpace = function startsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.startsWith)(text, SPACE);\n };\n\n // FIXME: This can be done more efficiently with a single pass\n // building a correct string based on the original.\n function renderHTMLText(marker) {\n var text = marker.value;\n text = text.replace(SPACES_REGEX, SPACE_AND_NO_BREAK).replace(TAB_REGEX, TAB_CHARACTER);\n\n // If the first marker has a leading space or the last marker has a\n // trailing space, the browser will collapse the space when we position\n // the cursor.\n // See https://github.com/bustle/mobiledoc-kit/issues/68\n // and https://github.com/bustle/mobiledoc-kit/issues/75\n if (marker.isMarker && endsWithSpace(text) && !marker.next) {\n text = text.substr(0, text.length - 1) + NO_BREAK_SPACE;\n }\n if (marker.isMarker && startsWithSpace(text) && (!marker.prev || marker.prev.isMarker && endsWithSpace(marker.prev.value))) {\n text = NO_BREAK_SPACE + text.substr(1);\n }\n return text;\n }\n\n // ascends from element upward, returning the last parent node that is not\n // parentElement\n function penultimateParentOf(element, parentElement) {\n while (parentElement && element.parentNode !== parentElement && element.parentNode !== document.body // ensure the while loop stops\n ) {\n element = element.parentNode;\n }\n return element;\n }\n\n function renderMarkupSection(section) {\n var element = undefined;\n if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) {\n element = document.createElement(section.tagName);\n } else {\n element = document.createElement('div');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName);\n }\n\n return element;\n }\n\n function renderListSection(section) {\n return document.createElement(section.tagName);\n }\n\n function renderListItem() {\n return document.createElement('li');\n }\n\n function renderCursorPlaceholder() {\n return document.createElement('br');\n }\n\n function renderInlineCursorPlaceholder() {\n return document.createTextNode(ZWNJ);\n }\n\n function renderCard() {\n var wrapper = document.createElement('div');\n var cardElement = document.createElement('div');\n cardElement.contentEditable = false;\n (0, _mobiledocKitUtilsDomUtils.addClassName)(cardElement, CARD_ELEMENT_CLASS_NAME);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n wrapper.appendChild(cardElement);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n return { wrapper: wrapper, cardElement: cardElement };\n }\n\n /**\n * Wrap the element in all of the opened markups\n * @return {DOMElement} the wrapped element\n * @private\n */\n function wrapElement(element, openedMarkups) {\n var wrappedElement = element;\n\n for (var i = openedMarkups.length - 1; i >= 0; i--) {\n var markup = openedMarkups[i];\n var openedElement = createElementFromMarkup(document, markup);\n openedElement.appendChild(wrappedElement);\n wrappedElement = openedElement;\n }\n\n return wrappedElement;\n }\n\n // Attach the element to its parent element at the correct position based on the\n // previousRenderNode\n function attachElementToParent(element, parentElement) {\n var previousRenderNode = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n if (previousRenderNode) {\n var previousSibling = previousRenderNode.element;\n var previousSiblingPenultimate = penultimateParentOf(previousSibling, parentElement);\n parentElement.insertBefore(element, previousSiblingPenultimate.nextSibling);\n } else {\n parentElement.insertBefore(element, parentElement.firstChild);\n }\n }\n\n function renderAtom(atom, element, previousRenderNode) {\n var atomElement = document.createElement('span');\n atomElement.contentEditable = false;\n\n var wrapper = document.createElement('span');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(wrapper, ATOM_CLASS_NAME);\n var headTextNode = renderInlineCursorPlaceholder();\n var tailTextNode = renderInlineCursorPlaceholder();\n\n wrapper.appendChild(headTextNode);\n wrapper.appendChild(atomElement);\n wrapper.appendChild(tailTextNode);\n\n var wrappedElement = wrapElement(wrapper, atom.openedMarkups);\n attachElementToParent(wrappedElement, element, previousRenderNode);\n\n return {\n markupElement: wrappedElement,\n wrapper: wrapper,\n atomElement: atomElement,\n headTextNode: headTextNode,\n tailTextNode: tailTextNode\n };\n }\n\n function getNextMarkerElement(renderNode) {\n var element = renderNode.element.parentNode;\n var marker = renderNode.postNode;\n var closedCount = marker.closedMarkups.length;\n\n while (closedCount--) {\n element = element.parentNode;\n }\n return element;\n }\n\n /**\n * Render the marker\n * @param {Marker} marker the marker to render\n * @param {DOMNode} element the element to attach the rendered marker to\n * @param {RenderNode} [previousRenderNode] The render node before this one, which\n * affects the determination of where to insert this rendered marker.\n * @return {Object} With properties `element` and `markupElement`.\n * The element (textNode) that has the text for\n * this marker, and the outermost rendered element. If the marker has no\n * markups, element and markupElement will be the same textNode\n * @private\n */\n function renderMarker(marker, parentElement, previousRenderNode) {\n var text = renderHTMLText(marker);\n\n var element = document.createTextNode(text);\n var markupElement = wrapElement(element, marker.openedMarkups);\n attachElementToParent(markupElement, parentElement, previousRenderNode);\n\n return { element: element, markupElement: markupElement };\n }\n\n // Attach the render node's element to the DOM,\n // replacing the originalElement if it exists\n function attachRenderNodeElementToDOM(renderNode) {\n var originalElement = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n var element = renderNode.element;\n var hasRendered = !!originalElement;\n\n if (hasRendered) {\n var parentElement = renderNode.parent.element;\n parentElement.replaceChild(element, originalElement);\n } else {\n var parentElement = undefined,\n nextSiblingElement = undefined;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n parentElement = previousElement.parentNode;\n nextSiblingElement = previousElement.nextSibling;\n } else {\n parentElement = renderNode.parent.element;\n nextSiblingElement = parentElement.firstChild;\n }\n parentElement.insertBefore(element, nextSiblingElement);\n }\n }\n\n function removeRenderNodeSectionFromParent(renderNode, section) {\n var parent = renderNode.parent.postNode;\n parent.sections.remove(section);\n }\n\n function removeRenderNodeElementFromParent(renderNode) {\n if (renderNode.element && renderNode.element.parentNode) {\n renderNode.element.parentNode.removeChild(renderNode.element);\n }\n }\n\n function validateCards() {\n var cards = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(cards, function (card) {\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define type \"dom\", has: \"' + card.type + '\"', card.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define `render` method', !!card.render);\n });\n return cards;\n }\n\n function validateAtoms() {\n var atoms = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(atoms, function (atom) {\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define type \"dom\", has: \"' + atom.type + '\"', atom.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define `render` method', !!atom.render);\n });\n return atoms;\n }\n\n var Visitor = (function () {\n function Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Visitor);\n\n this.editor = editor;\n this.cards = validateCards(cards);\n this.atoms = validateAtoms(atoms);\n this.unknownCardHandler = unknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler;\n this.options = options;\n }\n\n _createClass(Visitor, [{\n key: '_findCard',\n value: function _findCard(cardName) {\n var card = (0, _mobiledocKitUtilsArrayUtils.detect)(this.cards, function (card) {\n return card.name === cardName;\n });\n return card || this._createUnknownCard(cardName);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(cardName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown card \"' + cardName + '\" found, but no unknownCardHandler is defined', !!this.unknownCardHandler);\n\n return {\n name: cardName,\n type: 'dom',\n render: this.unknownCardHandler,\n edit: this.unknownCardHandler\n };\n }\n }, {\n key: '_findAtom',\n value: function _findAtom(atomName) {\n var atom = (0, _mobiledocKitUtilsArrayUtils.detect)(this.atoms, function (atom) {\n return atom.name === atomName;\n });\n return atom || this._createUnknownAtom(atomName);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(atomName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown atom \"' + atomName + '\" found, but no unknownAtomHandler is defined', !!this.unknownAtomHandler);\n\n return {\n name: atomName,\n type: 'dom',\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(renderNode, post, visit) {\n if (!renderNode.element) {\n renderNode.element = document.createElement('div');\n }\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_ELEMENT_CLASS_NAME);\n if (post.hasContent) {\n (0, _mobiledocKitUtilsDomUtils.removeClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n } else {\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n }\n visit(renderNode, post.sections);\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n // Always rerender the section -- its tag name or attributes may have changed.\n // TODO make this smarter, only rerendering and replacing the element when necessary\n renderNode.element = renderMarkupSection(section);\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n if (section.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, section.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n renderNode.element = renderListSection(section);\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var visitAll = true;\n visit(renderNode, section.items, visitAll);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(renderNode, item, visit) {\n // FIXME do we need to do anything special for rerenders?\n renderNode.element = renderListItem();\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, null);\n\n if (item.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, item.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKER_TYPE,\n value: function value(renderNode, marker) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var _renderMarker = renderMarker(marker, parentElement, renderNode.prev);\n\n var element = _renderMarker.element;\n var markupElement = _renderMarker.markupElement;\n\n renderNode.element = element;\n renderNode.markupElement = markupElement;\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(renderNode, section) {\n if (renderNode.element) {\n if (renderNode.element.src !== section.src) {\n renderNode.element.src = section.src;\n }\n } else {\n var element = document.createElement('img');\n element.src = section.src;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n var nextElement = previousElement.nextSibling;\n if (nextElement) {\n nextElement.parentNode.insertBefore(element, nextElement);\n }\n }\n if (!element.parentNode) {\n renderNode.parent.element.appendChild(element);\n }\n renderNode.element = element;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(renderNode, section) {\n var originalElement = renderNode.element;\n var editor = this.editor;\n var options = this.options;\n\n var card = this._findCard(section.name);\n\n var _renderCard = renderCard();\n\n var wrapper = _renderCard.wrapper;\n var cardElement = _renderCard.cardElement;\n\n renderNode.element = wrapper;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var cardNode = new _mobiledocKitModelsCardNode['default'](editor, card, section, cardElement, options);\n renderNode.cardNode = cardNode;\n\n var initialMode = section._initialMode;\n cardNode[initialMode]();\n }\n }, {\n key: _mobiledocKitModelsTypes.ATOM_TYPE,\n value: function value(renderNode, atomModel) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var editor = this.editor;\n var options = this.options;\n\n var _renderAtom = renderAtom(atomModel, parentElement, renderNode.prev);\n\n var wrapper = _renderAtom.wrapper;\n var markupElement = _renderAtom.markupElement;\n var atomElement = _renderAtom.atomElement;\n var headTextNode = _renderAtom.headTextNode;\n var tailTextNode = _renderAtom.tailTextNode;\n\n var atom = this._findAtom(atomModel.name);\n\n var atomNode = renderNode.atomNode;\n if (!atomNode) {\n // create new AtomNode\n atomNode = new _mobiledocKitModelsAtomNode['default'](editor, atom, atomModel, atomElement, options);\n } else {\n // retarget atomNode to new atom element\n atomNode.element = atomElement;\n }\n\n atomNode.render();\n\n renderNode.atomNode = atomNode;\n renderNode.element = wrapper;\n renderNode.headTextNode = headTextNode;\n renderNode.tailTextNode = tailTextNode;\n renderNode.markupElement = markupElement;\n }\n }]);\n\n return Visitor;\n })();\n\n var destroyHooks = (_destroyHooks = {}, _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.POST_TYPE, function () /*renderNode, post*/{\n (0, _mobiledocKitUtilsAssert['default'])('post destruction is not supported by the renderer', false);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (renderNode, li) {\n removeRenderNodeSectionFromParent(renderNode, li);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKER_TYPE, function (renderNode, marker) {\n // FIXME before we render marker, should delete previous renderNode's element\n // and up until the next marker element\n\n // If an atom throws during render we may end up later destroying a renderNode\n // that has not rendered yet, so exit early here if so.\n if (!renderNode.isRendered) {\n return;\n }\n var markupElement = renderNode.markupElement;\n\n if (marker.section) {\n marker.section.markers.remove(marker);\n }\n\n if (markupElement.parentNode) {\n // if no parentNode, the browser already removed this element\n markupElement.parentNode.removeChild(markupElement);\n }\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.CARD_TYPE, function (renderNode, section) {\n if (renderNode.cardNode) {\n renderNode.cardNode.teardown();\n }\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.ATOM_TYPE, function (renderNode, atom) {\n if (renderNode.atomNode) {\n renderNode.atomNode.teardown();\n }\n\n // an atom is a kind of marker so just call its destroy hook vs copying here\n destroyHooks[_mobiledocKitModelsTypes.MARKER_TYPE](renderNode, atom);\n }), _destroyHooks);\n\n // removes children from parentNode (a RenderNode) that are scheduled for removal\n function removeDestroyedChildren(parentNode) {\n var forceRemoval = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n var child = parentNode.childNodes.head;\n var nextChild = undefined,\n method = undefined;\n while (child) {\n nextChild = child.next;\n if (child.isRemoved || forceRemoval) {\n removeDestroyedChildren(child, true);\n method = child.postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('editor-dom cannot destroy \"' + method + '\"', !!destroyHooks[method]);\n destroyHooks[method](child, child.postNode);\n parentNode.childNodes.remove(child);\n }\n child = nextChild;\n }\n }\n\n // Find an existing render node for the given postNode, or\n // create one, insert it into the tree, and return it\n function lookupNode(renderTree, parentNode, postNode, previousNode) {\n if (postNode.renderNode) {\n return postNode.renderNode;\n } else {\n var renderNode = renderTree.buildRenderNode(postNode);\n parentNode.childNodes.insertAfter(renderNode, previousNode);\n return renderNode;\n }\n }\n\n var Renderer = (function () {\n function Renderer(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Renderer);\n\n this.editor = editor;\n this.visitor = new Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options);\n this.nodes = [];\n this.hasRendered = false;\n }\n\n _createClass(Renderer, [{\n key: 'destroy',\n value: function destroy() {\n if (!this.hasRendered) {\n return;\n }\n var renderNode = this.renderTree.rootNode;\n var force = true;\n removeDestroyedChildren(renderNode, force);\n }\n }, {\n key: 'visit',\n value: function visit(renderTree, parentNode, postNodes) {\n var _this = this;\n\n var visitAll = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];\n\n var previousNode = undefined;\n postNodes.forEach(function (postNode) {\n var node = lookupNode(renderTree, parentNode, postNode, previousNode);\n if (node.isDirty || visitAll) {\n _this.nodes.push(node);\n }\n previousNode = node;\n });\n }\n }, {\n key: 'render',\n value: function render(renderTree) {\n var _this2 = this;\n\n this.hasRendered = true;\n this.renderTree = renderTree;\n var renderNode = renderTree.rootNode;\n var method = undefined,\n postNode = undefined;\n\n while (renderNode) {\n removeDestroyedChildren(renderNode);\n postNode = renderNode.postNode;\n\n method = postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]);\n // jshint -W083\n this.visitor[method](renderNode, postNode, function () {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return _this2.visit.apply(_this2, [renderTree].concat(args));\n });\n // jshint +W083\n renderNode.markClean();\n renderNode = this.nodes.shift();\n }\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-kit/renderers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.2.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, name, payload]);\n },\n openPost: function openPost() {\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n sections: [this.markerTypes, this.sections]\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.1';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n exports['default'] = {\n render: function render(post, version) {\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc02['default'].render(post);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc03['default'].render(post);\n case undefined:\n case null:\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc031['default'].render(post);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false);\n }\n }\n };\n});","define(\"mobiledoc-kit/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function detect(enumerable, callback) {\n if (enumerable.detect) {\n return enumerable.detect(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return enumerable[i];\n }\n }\n }\n }\n\n function any(enumerable, callback) {\n if (enumerable.any) {\n return enumerable.any(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return true;\n }\n }\n\n return false;\n }\n\n function every(enumerable, callback) {\n if (enumerable.every) {\n return enumerable.every(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (!callback(enumerable[i])) {\n return false;\n }\n }\n return true;\n }\n\n function toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n }\n\n /**\n * Useful for array-like things that aren't\n * actually arrays, like NodeList\n * @private\n */\n function forEach(enumerable, callback) {\n if (enumerable.forEach) {\n enumerable.forEach(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n callback(enumerable[i], i);\n }\n }\n }\n\n function filter(enumerable, conditionFn) {\n var filtered = [];\n forEach(enumerable, function (i) {\n if (conditionFn(i)) {\n filtered.push(i);\n }\n });\n return filtered;\n }\n\n /**\n * @return {Integer} the number of items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItemLength(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return offset;\n }\n\n /**\n * @return {Array} the items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItems(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return listA.slice(0, offset);\n }\n\n // return new array without falsy items like ruby's `compact`\n function compact(enumerable) {\n return filter(enumerable, function (i) {\n return !!i;\n });\n }\n\n function reduce(enumerable, callback, initialValue) {\n var previousValue = initialValue;\n forEach(enumerable, function (val, index) {\n previousValue = callback(previousValue, val, index);\n });\n return previousValue;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n function kvArrayToObject(array) {\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n\n // check shallow equality of two non-nested arrays\n function isArrayEqual(arr1, arr2) {\n var l1 = arr1.length,\n l2 = arr2.length;\n if (l1 !== l2) {\n return false;\n }\n\n for (var i = 0; i < l1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n return true;\n }\n\n // return an object with only the valid keys\n function filterObject(object) {\n var validKeys = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var result = {};\n forEach(filter(Object.keys(object), function (key) {\n return validKeys.indexOf(key) !== -1;\n }), function (key) {\n return result[key] = object[key];\n });\n return result;\n }\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function values(object) {\n return Object.keys(object).map(function (key) {\n return object[key];\n });\n }\n\n exports.detect = detect;\n exports.forEach = forEach;\n exports.any = any;\n exports.every = every;\n exports.filter = filter;\n exports.commonItemLength = commonItemLength;\n exports.commonItems = commonItems;\n exports.compact = compact;\n exports.reduce = reduce;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n exports.kvArrayToObject = kvArrayToObject;\n exports.isArrayEqual = isArrayEqual;\n exports.toArray = toArray;\n exports.filterObject = filterObject;\n exports.contains = contains;\n exports.values = values;\n});","define('mobiledoc-kit/utils/assert', ['exports', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n exports['default'] = function (message, conditional) {\n if (!conditional) {\n throw new _mobiledocKitUtilsMobiledocError['default'](message);\n }\n };\n});","define('mobiledoc-kit/utils/browser', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n isMac: function isMac() {\n return typeof window !== 'undefined' && window.navigator && /Mac/.test(window.navigator.platform);\n },\n isWin: function isWin() {\n return typeof window !== 'undefined' && window.navigator && /Win/.test(window.navigator.platform);\n }\n };\n});","define('mobiledoc-kit/utils/characters', ['exports'], function (exports) {\n 'use strict';\n\n var TAB = '\\t';\n exports.TAB = TAB;\n var ENTER = '\\n';\n exports.ENTER = ENTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n});","define('mobiledoc-kit/utils/compiler', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports.visit = visit;\n exports.compile = compile;\n exports.visitArray = visitArray;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function visit(visitor, node, opcodes) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit unknown type ' + method, !!visitor[method]);\n visitor[method](node, opcodes);\n }\n\n function compile(compiler, opcodes) {\n for (var i = 0, l = opcodes.length; i < l; i++) {\n var _opcodes$i = _toArray(opcodes[i]);\n\n var method = _opcodes$i[0];\n\n var params = _opcodes$i.slice(1);\n\n var _length = params.length;\n if (_length === 0) {\n compiler[method].call(compiler);\n } else if (_length === 1) {\n compiler[method].call(compiler, params[0]);\n } else if (_length === 2) {\n compiler[method].call(compiler, params[0], params[1]);\n } else {\n compiler[method].apply(compiler, params);\n }\n }\n }\n\n function visitArray(visitor, nodes, opcodes) {\n if (!nodes || nodes.length === 0) {\n return;\n }\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n visit(visitor, node, opcodes);\n });\n }\n});","define(\"mobiledoc-kit/utils/copy\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function shallowCopyObject(object) {\n var copy = {};\n Object.keys(object).forEach(function (key) {\n copy[key] = object[key];\n });\n return copy;\n }\n\n exports.shallowCopyObject = shallowCopyObject;\n});","define('mobiledoc-kit/utils/cursor', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/key'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKey) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n\n var Cursor = (function () {\n function Cursor(editor) {\n _classCallCheck(this, Cursor);\n\n this.editor = editor;\n this.renderTree = editor._renderTree;\n this.post = editor.post;\n }\n\n _createClass(Cursor, [{\n key: 'clearSelection',\n value: function clearSelection() {\n (0, _mobiledocKitUtilsSelectionUtils.clearSelection)();\n }\n\n /**\n * @return {Boolean} true when there is either a collapsed cursor in the\n * editor's element or a selection that is contained in the editor's element\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.editor.hasRendered && (this._hasCollapsedSelection() || this._hasSelection());\n }\n }, {\n key: 'hasSelection',\n value: function hasSelection() {\n return this.editor.hasRendered && this._hasSelection();\n }\n\n /**\n * @return {Boolean} Can the cursor be on this element?\n */\n }, {\n key: 'isAddressable',\n value: function isAddressable(element) {\n var renderTree = this.renderTree;\n\n var renderNode = renderTree.findRenderNodeFromElement(element);\n if (renderNode && renderNode.postNode.isCardSection) {\n var renderedElement = renderNode.element;\n\n // card sections have addressable text nodes containing ‌\n // as their first and last child\n if (element !== renderedElement && element !== renderedElement.firstChild && element !== renderedElement.lastChild) {\n return false;\n }\n }\n\n return !!renderNode;\n }\n\n /*\n * @return {Range} Cursor#Range object\n */\n }, {\n key: '_findNodeForPosition',\n value: function _findNodeForPosition(position) {\n var section = position.section;\n\n var node = undefined,\n offset = undefined;\n if (section.isCardSection) {\n offset = 0;\n if (position.offset === 0) {\n node = section.renderNode.element.firstChild;\n } else {\n node = section.renderNode.element.lastChild;\n }\n } else if (section.isBlank) {\n node = section.renderNode.cursorElement;\n offset = 0;\n } else {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n if (marker.isAtom) {\n if (offsetInMarker > 0) {\n // FIXME -- if there is a next marker, focus on it?\n offset = 0;\n node = marker.renderNode.tailTextNode;\n } else {\n offset = 0;\n node = marker.renderNode.headTextNode;\n }\n } else {\n node = marker.renderNode.element;\n offset = offsetInMarker;\n }\n }\n\n return { node: node, offset: offset };\n }\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n if (range.isBlank) {\n this.clearSelection();\n return;\n }\n\n var head = range.head;\n var tail = range.tail;\n var direction = range.direction;\n\n var _findNodeForPosition2 = this._findNodeForPosition(head);\n\n var headNode = _findNodeForPosition2.node;\n var headOffset = _findNodeForPosition2.offset;\n\n var _findNodeForPosition3 = this._findNodeForPosition(tail);\n\n var tailNode = _findNodeForPosition3.node;\n var tailOffset = _findNodeForPosition3.offset;\n\n this._moveToNode(headNode, headOffset, tailNode, tailOffset, direction);\n\n // Firefox sometimes doesn't keep focus in the editor after adding a card\n this.editor._ensureFocus();\n }\n }, {\n key: 'selectedText',\n value: function selectedText() {\n // FIXME remove this\n return this.selection.toString();\n }\n\n /**\n * @param {textNode} node\n * @param {integer} offset\n * @param {textNode} endNode\n * @param {integer} endOffset\n * @param {integer} direction forward or backward, default forward\n * @private\n */\n }, {\n key: '_moveToNode',\n value: function _moveToNode(node, offset, endNode, endOffset) {\n var direction = arguments.length <= 4 || arguments[4] === undefined ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : arguments[4];\n\n this.clearSelection();\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n var _ref = [endNode, endOffset, node, offset];\n node = _ref[0];\n offset = _ref[1];\n endNode = _ref[2];\n endOffset = _ref[3];\n }\n\n var range = document.createRange();\n range.setStart(node, offset);\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD && !!this.selection.extend) {\n this.selection.addRange(range);\n this.selection.extend(endNode, endOffset);\n } else {\n range.setEnd(endNode, endOffset);\n this.selection.addRange(range);\n }\n }\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var element = this.editor.element;\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange || _selectionRange.collapsed) {\n return false;\n }\n\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode) && (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.focusNode);\n }\n }, {\n key: '_hasCollapsedSelection',\n value: function _hasCollapsedSelection() {\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange) {\n return false;\n }\n\n var element = this.editor.element;\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode);\n }\n }, {\n key: 'offsets',\n get: function get() {\n if (!this.hasCursor()) {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n\n var selection = this.selection;\n var renderTree = this.renderTree;\n\n var parentNode = this.editor.element;\n selection = (0, _mobiledocKitUtilsSelectionUtils.constrainSelectionTo)(selection, parentNode);\n\n var _comparePosition = (0, _mobiledocKitUtilsSelectionUtils.comparePosition)(selection);\n\n var headNode = _comparePosition.headNode;\n var headOffset = _comparePosition.headOffset;\n var tailNode = _comparePosition.tailNode;\n var tailOffset = _comparePosition.tailOffset;\n var direction = _comparePosition.direction;\n\n var headPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, headNode, headOffset);\n var tailPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, tailNode, tailOffset);\n\n return new _mobiledocKitUtilsCursorRange['default'](headPosition, tailPosition, direction);\n }\n }, {\n key: 'selection',\n get: function get() {\n return window.getSelection();\n }\n }, {\n key: '_selectionRange',\n get: function get() {\n var selection = this.selection;\n\n if (selection.rangeCount === 0) {\n return null;\n }\n return selection.getRangeAt(0);\n }\n }]);\n\n return Cursor;\n })();\n\n exports['default'] = Cursor;\n});","define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitModelsMarker, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsKey, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n var WORD_CHAR_REGEX = /\\w|_|:/;\n\n function findParentSectionFromNode(renderTree, node) {\n var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) {\n return renderNode.postNode.isSection;\n });\n\n return renderNode && renderNode.postNode;\n }\n\n function findOffsetInMarkerable(markerable, node, offset) {\n var offsetInSection = 0;\n var marker = markerable.markers.head;\n while (marker) {\n var markerNode = marker.renderNode.element;\n if (markerNode === node) {\n return offsetInSection + offset;\n } else if (marker.isAtom) {\n if (marker.renderNode.headTextNode === node) {\n return offsetInSection;\n } else if (marker.renderNode.tailTextNode === node) {\n return offsetInSection + 1;\n }\n }\n\n offsetInSection += marker.length;\n marker = marker.next;\n }\n\n return offsetInSection;\n }\n\n function findOffsetInSection(section, node, offset) {\n if (section.isMarkerable) {\n return findOffsetInMarkerable(section, node, offset);\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('findOffsetInSection must be called with markerable or card section', section.isCardSection);\n\n var wrapperNode = section.renderNode.element;\n var endTextNode = wrapperNode.lastChild;\n if (node === endTextNode) {\n return 1;\n }\n return 0;\n }\n }\n\n var Position = undefined,\n BlankPosition = undefined;\n\n Position = (function () {\n /**\n * A position is a logical location (zero-width, or \"collapsed\") in a post,\n * typically between two characters in a section.\n * Two positions (a head and a tail) make up a {@link Range}.\n * @constructor\n */\n\n function Position(section) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var isBlank = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n _classCallCheck(this, Position);\n\n if (!isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Position must have a section that is addressable by the cursor', section && section.isLeafSection);\n (0, _mobiledocKitUtilsAssert['default'])('Position must have numeric offset', typeof offset === 'number');\n }\n\n this.section = section;\n this.offset = offset;\n this.isBlank = isBlank;\n }\n\n /**\n * @param {integer} x x-position in current viewport\n * @param {integer} y y-position in current viewport\n * @param {Editor} editor\n * @return {Position|null}\n */\n\n _createClass(Position, [{\n key: 'toRange',\n\n /**\n * Returns a range from this position to the given tail. If no explicit\n * tail is given this returns a collapsed range focused on this position.\n * @param {Position} [tail=this] The ending position\n * @return {Range}\n * @public\n */\n value: function toRange() {\n var tail = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0];\n var direction = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n return new _mobiledocKitUtilsCursorRange['default'](this, tail, direction);\n }\n }, {\n key: 'markerIn',\n\n /**\n * Returns the marker in `direction` from this position.\n * If the position is in the middle of a marker, the direction is irrelevant.\n * Otherwise, if the position is at a boundary between two markers, returns the\n * marker to the left if `direction` === BACKWARD and the marker to the right\n * if `direction` === FORWARD (assuming left-to-right text direction).\n * @param {Direction}\n * @return {Marker|undefined}\n */\n value: function markerIn(direction) {\n if (!this.isMarkerable) {\n return;\n }\n\n var marker = this.marker;\n var offsetInMarker = this.offsetInMarker;\n\n if (!marker) {\n return;\n }\n\n if (offsetInMarker > 0 && offsetInMarker < marker.length) {\n return marker;\n } else if (offsetInMarker === 0) {\n return direction === BACKWARD ? marker : marker.prev;\n } else if (offsetInMarker === marker.length) {\n return direction === FORWARD ? marker.next : marker;\n }\n }\n }, {\n key: 'isEqual',\n value: function isEqual(position) {\n return this.section === position.section && this.offset === position.offset;\n }\n\n /**\n * @return {Boolean} If this position is at the head of the post\n */\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return this.move(BACKWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the tail of the post\n */\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return this.move(FORWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the head of its section\n */\n }, {\n key: 'isHead',\n value: function isHead() {\n return this.isEqual(this.section.headPosition());\n }\n\n /**\n * @return {Boolean} If this position is at the tail of its section\n */\n }, {\n key: 'isTail',\n value: function isTail() {\n return this.isEqual(this.section.tailPosition());\n }\n\n /**\n * Move the position 1 unit in `direction`.\n *\n * @param {Number} units to move. > 0 moves right, < 0 moves left\n * @return {Position} Return a new position one unit in the given\n * direction. If the position is moving left and at the beginning of the post,\n * the same position will be returned. Same if the position is moving right and\n * at the end of the post.\n */\n }, {\n key: 'move',\n value: function move(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Position#move', typeof units === 'number');\n\n if (units < 0) {\n return this.moveLeft().move(++units);\n } else if (units > 0) {\n return this.moveRight().move(--units);\n } else {\n return this;\n }\n }\n\n /**\n * @param {Number} direction (FORWARD or BACKWARD)\n * @return {Position} The result of moving 1 \"word\" unit in `direction`\n */\n }, {\n key: 'moveWord',\n value: function moveWord(direction) {\n var isPostBoundary = direction === BACKWARD ? this.isHeadOfPost() : this.isTailOfPost();\n if (isPostBoundary) {\n return this;\n }\n\n if (!this.isMarkerable) {\n return this.move(direction);\n }\n\n var pos = this;\n\n // Helper fn to check if the pos is at the `dir` boundary of its section\n var isBoundary = function isBoundary(pos, dir) {\n return dir === BACKWARD ? pos.isHead() : pos.isTail();\n };\n // Get the char at this position (looking forward/right)\n var getChar = function getChar(pos) {\n var marker = pos.marker;\n var offsetInMarker = pos.offsetInMarker;\n\n return marker.charAt(offsetInMarker);\n };\n // Get the char in `dir` at this position\n var peekChar = function peekChar(pos, dir) {\n return dir === BACKWARD ? getChar(pos.move(BACKWARD)) : getChar(pos);\n };\n // Whether there is an atom in `dir` from this position\n var isAtom = function isAtom(pos, dir) {\n // Special case when position is at end, the marker associated with it is\n // the marker to its left. Normally `pos#marker` is the marker to the right of the pos's offset.\n if (dir === BACKWARD && pos.isTail() && pos.marker.isAtom) {\n return true;\n }\n return dir === BACKWARD ? pos.move(BACKWARD).marker.isAtom : pos.marker.isAtom;\n };\n\n if (isBoundary(pos, direction)) {\n // extend movement into prev/next section\n return pos.move(direction).moveWord(direction);\n }\n\n var seekWord = function seekWord(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && !WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first word char\n while (seekWord(pos)) {\n pos = pos.move(direction);\n }\n\n if (isAtom(pos, direction)) {\n return pos.move(direction);\n }\n\n var seekBoundary = function seekBoundary(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first boundary position\n while (seekBoundary(pos)) {\n pos = pos.move(direction);\n }\n\n return pos;\n }\n\n /**\n * The position to the left of this position.\n * If this position is the post's headPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveLeft',\n value: function moveLeft() {\n if (this.isHead()) {\n var prev = this.section.previousLeafSection();\n return prev ? prev.tailPosition() : this;\n } else {\n var offset = this.offset - 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset);\n if (code >= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[1]) {\n offset = offset - 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n\n /**\n * The position to the right of this position.\n * If this position is the post's tailPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveRight',\n value: function moveRight() {\n if (this.isTail()) {\n var next = this.section.nextLeafSection();\n return next ? next.headPosition() : this;\n } else {\n var offset = this.offset + 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset - 1);\n if (code >= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[1]) {\n offset = offset + 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n var _this = this;\n\n var post = this.section.post;\n var leafSectionIndex = undefined;\n post.walkAllLeafSections(function (section, index) {\n if (section === _this.section) {\n leafSectionIndex = index;\n }\n });\n return leafSectionIndex;\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return this.section && this.section.isMarkerable;\n }\n\n /**\n * Returns the marker at this position, in the backward direction\n * (i.e., the marker to the left of the cursor if the cursor is on a marker boundary and text is left-to-right)\n * @return {Marker|undefined}\n */\n }, {\n key: 'marker',\n get: function get() {\n return this.isMarkerable && this.markerPosition.marker;\n }\n }, {\n key: 'offsetInMarker',\n get: function get() {\n return this.markerPosition.offset;\n }\n }, {\n key: 'markerPosition',\n\n /**\n * @private\n */\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get markerPosition without a section', !!this.section);\n (0, _mobiledocKitUtilsAssert['default'])('cannot get markerPosition of a non-markerable', !!this.section.isMarkerable);\n return this.section.markerPositionAtOffset(this.offset);\n }\n }], [{\n key: 'atPoint',\n value: function atPoint(x, y, editor) {\n var _renderTree = editor._renderTree;\n var rootElement = editor.element;\n\n var elementFromPoint = document.elementFromPoint(x, y);\n if (!(0, _mobiledocKitUtilsDomUtils.containsNode)(rootElement, elementFromPoint)) {\n return;\n }\n\n var _findOffsetInNode = (0, _mobiledocKitUtilsSelectionUtils.findOffsetInNode)(elementFromPoint, { left: x, top: y });\n\n var node = _findOffsetInNode.node;\n var offset = _findOffsetInNode.offset;\n\n return Position.fromNode(_renderTree, node, offset);\n }\n }, {\n key: 'blankPosition',\n value: function blankPosition() {\n return new BlankPosition();\n }\n }, {\n key: 'fromNode',\n value: function fromNode(renderTree, node, offset) {\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n return Position.fromTextNode(renderTree, node, offset);\n } else {\n return Position.fromElementNode(renderTree, node, offset);\n }\n }\n }, {\n key: 'fromTextNode',\n value: function fromTextNode(renderTree, textNode, offsetInNode) {\n var renderNode = renderTree.getElementRenderNode(textNode);\n var section = undefined,\n offsetInSection = undefined;\n\n if (renderNode) {\n var marker = renderNode.postNode;\n section = marker.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for mapped text node \"' + textNode.textContent + '\"', !!section);\n offsetInSection = section.offsetOfMarker(marker, offsetInNode);\n } else {\n // all text nodes should be rendered by markers except:\n // * text nodes inside cards\n // * text nodes created by the browser during text input\n // both of these should have rendered parent sections, though\n section = findParentSectionFromNode(renderTree, textNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for un-mapped text node \"' + textNode.textContent + '\"', !!section);\n\n offsetInSection = findOffsetInSection(section, textNode, offsetInNode);\n }\n\n return new Position(section, offsetInSection);\n }\n }, {\n key: 'fromElementNode',\n value: function fromElementNode(renderTree, elementNode, offset) {\n var position = undefined;\n\n // The browser may change the reported selection to equal the editor's root\n // element if the user clicks an element that is immediately removed,\n // which can happen when clicking to remove a card.\n if (elementNode === renderTree.rootElement) {\n var post = renderTree.rootNode.postNode;\n position = offset === 0 ? post.headPosition() : post.tailPosition();\n } else {\n var section = findParentSectionFromNode(renderTree, elementNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section from element node', !!section);\n\n if (section.isCardSection) {\n // Selections in cards are usually made on a text node\n // containing a ‌ on one side or the other of the card but\n // some scenarios (Firefox) will result in selecting the\n // card's wrapper div. If the offset is 2 we've selected\n // the final zwnj and should consider the cursor at the\n // end of the card (offset 1). Otherwise, the cursor is at\n // the start of the card\n position = offset < 2 ? section.headPosition() : section.tailPosition();\n } else {\n\n // In Firefox it is possible for the cursor to be on an atom's wrapper\n // element. (In Chrome/Safari, the browser corrects this to be on\n // one of the text nodes surrounding the wrapper).\n // This code corrects for when the browser reports the cursor position\n // to be on the wrapper element itself\n var renderNode = renderTree.getElementRenderNode(elementNode);\n var postNode = renderNode && renderNode.postNode;\n if (postNode && postNode.isAtom) {\n var sectionOffset = section.offsetOfMarker(postNode);\n if (offset > 1) {\n // we are on the tail side of the atom\n sectionOffset += postNode.length;\n }\n position = new Position(section, sectionOffset);\n } else {\n // The offset is 0 if the cursor is on a non-atom-wrapper element node\n // (e.g., a
    tag in a blank markup section)\n position = section.headPosition();\n }\n }\n }\n\n return position;\n }\n }]);\n\n return Position;\n })();\n\n BlankPosition = (function (_Position) {\n _inherits(BlankPosition, _Position);\n\n function BlankPosition() {\n _classCallCheck(this, BlankPosition);\n\n _get(Object.getPrototypeOf(BlankPosition.prototype), 'constructor', this).call(this, null, 0, true);\n }\n\n _createClass(BlankPosition, [{\n key: 'isEqual',\n value: function isEqual(other) {\n return other && other.isBlank;\n }\n }, {\n key: 'toRange',\n value: function toRange() {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return false;\n }\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return false;\n }\n }, {\n key: 'isHead',\n value: function isHead() {\n return false;\n }\n }, {\n key: 'isTail',\n value: function isTail() {\n return false;\n }\n }, {\n key: 'move',\n value: function move() {\n return this;\n }\n }, {\n key: 'moveWord',\n value: function moveWord() {\n return this;\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('must implement get leafSectionIndex', false);\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return false;\n }\n }, {\n key: 'marker',\n get: function get() {\n return false;\n }\n }, {\n key: 'markerPosition',\n get: function get() {\n return {};\n }\n }]);\n\n return BlankPosition;\n })(Position);\n\n exports['default'] = Position;\n});","define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsKey, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * A logical range of a {@link Post}.\n * Usually an instance of Range will be read from the {@link Editor#range} property,\n * but it may be useful to instantiate a range directly when programmatically modifying a Post.\n */\n\n var Range = (function () {\n /**\n * @param {Position} head\n * @param {Position} [tail=head]\n * @param {Direction} [direction=null]\n * @return {Range}\n * @private\n */\n\n function Range(head) {\n var tail = arguments.length <= 1 || arguments[1] === undefined ? head : arguments[1];\n var direction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n return (function () {\n _classCallCheck(this, Range);\n\n /** @property {Position} head */\n this.head = head;\n\n /** @property {Position} tail */\n this.tail = tail;\n\n /** @property {Direction} direction */\n this.direction = direction;\n }).apply(this, arguments);\n }\n\n /**\n * Shorthand to create a new range from a section(s) and offset(s).\n * When given only a head section and offset, creates a collapsed range.\n * @param {Section} headSection\n * @param {number} headOffset\n * @param {Section} [tailSection=headSection]\n * @param {number} [tailOffset=headOffset]\n * @param {Direction} [direction=null]\n * @return {Range}\n */\n\n _createClass(Range, [{\n key: 'trimTo',\n\n /**\n * @param {Markerable} section\n * @return {Range} A range that is constrained to only the part that\n * includes the section.\n * FIXME -- if the section isn't the head or tail, it's assumed to be\n * wholly contained. It's possible to call `trimTo` with a selection that is\n * outside of the range, though, which would invalidate that assumption.\n * There's no efficient way to determine if a section is within a range, yet.\n * @private\n */\n value: function trimTo(section) {\n var length = section.length;\n\n var headOffset = section === this.head.section ? Math.min(this.head.offset, length) : 0;\n var tailOffset = section === this.tail.section ? Math.min(this.tail.offset, length) : length;\n\n return Range.create(section, headOffset, section, tailOffset);\n }\n\n /**\n * Expands the range 1 unit in the given direction\n * If the range is expandable in the given direction, always returns a\n * non-collapsed range.\n * @param {Number} units If units is > 0, the range is extended to the right,\n * otherwise range is extended to the left.\n * @return {Range}\n * @public\n */\n }, {\n key: 'extend',\n value: function extend(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Range#extend', typeof units === 'number');\n\n if (units === 0) {\n return this;\n }\n\n var head = this.head;\n var tail = this.tail;\n var currentDirection = this.direction;\n\n switch (currentDirection) {\n case _mobiledocKitUtilsKey.DIRECTION.FORWARD:\n return new Range(head, tail.move(units), currentDirection);\n case _mobiledocKitUtilsKey.DIRECTION.BACKWARD:\n return new Range(head.move(units), tail, currentDirection);\n default:\n var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n return new Range(head, tail, newDirection).extend(units);\n }\n }\n\n /**\n * Moves this range 1 unit in the given direction.\n * If the range is collapsed, returns a collapsed range shifted by 1 unit,\n * otherwise collapses this range to the position at the `direction` end of the range.\n * Always returns a collapsed range.\n * @param {Direction} direction\n * @return {Range}\n * @public\n */\n }, {\n key: 'move',\n value: function move(direction) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass DIRECTION.FORWARD (' + _mobiledocKitUtilsKey.DIRECTION.FORWARD + ') or DIRECTION.BACKWARD (' + _mobiledocKitUtilsKey.DIRECTION.BACKWARD + ') to Range#move', direction === _mobiledocKitUtilsKey.DIRECTION.FORWARD || direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD);\n\n var focusedPosition = this.focusedPosition;\n var isCollapsed = this.isCollapsed;\n\n if (isCollapsed) {\n return new Range(focusedPosition.move(direction));\n } else {\n return this._collapse(direction);\n }\n }\n\n /**\n * expand a range to all markers matching a given check\n *\n * @param {Function} detectMarker\n * @return {Range} The expanded range\n *\n * @public\n */\n }, {\n key: 'expandByMarker',\n value: function expandByMarker(detectMarker) {\n var head = this.head;\n var tail = this.tail;\n var direction = this.direction;\n var headSection = head.section;\n\n if (headSection !== tail.section) {\n throw new Error('#expandByMarker does not work across sections. Perhaps you should confirm the range is collapsed');\n }\n\n var firstNotMatchingDetect = function firstNotMatchingDetect(i) {\n return !detectMarker(i);\n };\n\n var headMarker = head.section.markers.detect(firstNotMatchingDetect, head.marker, true);\n headMarker = headMarker && headMarker.next || head.marker;\n var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker));\n\n var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker);\n tailMarker = tailMarker && tailMarker.prev || tail.marker;\n var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length);\n\n return headPosition.toRange(tailPosition, direction);\n }\n }, {\n key: '_collapse',\n value: function _collapse(direction) {\n return new Range(direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail);\n }\n }, {\n key: 'isEqual',\n value: function isEqual(other) {\n return other && this.head.isEqual(other.head) && this.tail.isEqual(other.tail);\n }\n }, {\n key: 'focusedPosition',\n get: function get() {\n return this.direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.head.isBlank && this.tail.isBlank;\n }\n\n // \"legacy\" APIs\n }, {\n key: 'headSection',\n get: function get() {\n return this.head.section;\n }\n }, {\n key: 'tailSection',\n get: function get() {\n return this.tail.section;\n }\n }, {\n key: 'headSectionOffset',\n get: function get() {\n return this.head.offset;\n }\n }, {\n key: 'tailSectionOffset',\n get: function get() {\n return this.tail.offset;\n }\n }, {\n key: 'isCollapsed',\n get: function get() {\n return this.head.isEqual(this.tail);\n }\n }, {\n key: 'headMarker',\n get: function get() {\n return this.head.marker;\n }\n }, {\n key: 'tailMarker',\n get: function get() {\n return this.tail.marker;\n }\n }, {\n key: 'headMarkerOffset',\n get: function get() {\n return this.head.offsetInMarker;\n }\n }, {\n key: 'tailMarkerOffset',\n get: function get() {\n return this.tail.offsetInMarker;\n }\n }], [{\n key: 'create',\n value: function create(headSection, headOffset) {\n var tailSection = arguments.length <= 2 || arguments[2] === undefined ? headSection : arguments[2];\n var tailOffset = arguments.length <= 3 || arguments[3] === undefined ? headOffset : arguments[3];\n var direction = arguments.length <= 4 || arguments[4] === undefined ? null : arguments[4];\n return (function () {\n return new Range(new _mobiledocKitUtilsCursorPosition['default'](headSection, headOffset), new _mobiledocKitUtilsCursorPosition['default'](tailSection, tailOffset), direction);\n })();\n }\n }, {\n key: 'blankRange',\n value: function blankRange() {\n return new Range(_mobiledocKitUtilsCursorPosition['default'].blankPosition(), _mobiledocKitUtilsCursorPosition['default'].blankPosition());\n }\n }]);\n\n return Range;\n })();\n\n exports['default'] = Range;\n});","define(\"mobiledoc-kit/utils/deprecate\", [\"exports\"], function (exports) {\n /**\n * Usage:\n * Without a conditional, always prints deprecate message:\n * `deprecate('This is deprecated')`\n *\n * Conditional deprecation, works similarly to `assert`, prints deprecation if\n * conditional is false:\n * `deprecate('Deprecated only if foo !== bar', foo === bar)`\n */\n \"use strict\";\n\n exports[\"default\"] = deprecate;\n\n function deprecate(message) {\n var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (!conditional) {\n console.log(\"[mobiledoc-kit] [DEPRECATED]: \" + message); // jshint ignore:line\n }\n }\n});","define('mobiledoc-kit/utils/dom-utils', ['exports', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n COMMENT: 8\n };\n\n exports.NODE_TYPES = NODE_TYPES;\n function isTextNode(node) {\n return node.nodeType === NODE_TYPES.TEXT;\n }\n\n function isCommentNode(node) {\n return node.nodeType === NODE_TYPES.COMMENT;\n }\n\n function isElementNode(node) {\n return node.nodeType === NODE_TYPES.ELEMENT;\n }\n\n // perform a pre-order tree traversal of the dom, calling `callbackFn(node)`\n // for every node for which `conditionFn(node)` is true\n function walkDOM(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n var conditionFn = arguments.length <= 2 || arguments[2] === undefined ? function () {\n return true;\n } : arguments[2];\n\n var currentNode = topNode;\n\n if (conditionFn(currentNode)) {\n callbackFn(currentNode);\n }\n\n currentNode = currentNode.firstChild;\n\n while (currentNode) {\n walkDOM(currentNode, callbackFn, conditionFn);\n currentNode = currentNode.nextSibling;\n }\n }\n\n function walkTextNodes(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n\n var conditionFn = function conditionFn(node) {\n return isTextNode(node);\n };\n walkDOM(topNode, callbackFn, conditionFn);\n }\n\n function clearChildNodes(element) {\n while (element.childNodes.length) {\n element.removeChild(element.childNodes[0]);\n }\n }\n\n /**\n * @return {Boolean} true when the child node is contained or the same as\n * (e.g., inclusive containment) the parent node\n * see https://github.com/webmodules/node-contains/blob/master/index.js\n * Mimics the behavior of `Node.contains`, which is broken in IE 10\n * @private\n */\n function containsNode(parentNode, childNode) {\n if (parentNode === childNode) {\n return true;\n }\n var position = parentNode.compareDocumentPosition(childNode);\n return !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY);\n }\n\n /**\n * converts the element's NamedNodeMap of attrs into\n * an object with key-value pairs\n * @param {DOMNode} element\n * @return {Object} key-value pairs\n * @private\n */\n function getAttributes(element) {\n var result = {};\n if (element.hasAttributes()) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.attributes, function (_ref) {\n var name = _ref.name;\n var value = _ref.value;\n\n result[name] = value;\n });\n }\n return result;\n }\n\n function addClassName(element, className) {\n element.classList.add(className);\n }\n\n function removeClassName(element, className) {\n element.classList.remove(className);\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n\n function parseHTML(html) {\n var div = document.createElement('div');\n div.innerHTML = html;\n return div;\n }\n\n function serializeHTML(node) {\n var div = document.createElement('div');\n div.appendChild(node);\n return div.innerHTML;\n }\n\n exports.containsNode = containsNode;\n exports.clearChildNodes = clearChildNodes;\n exports.getAttributes = getAttributes;\n exports.walkDOM = walkDOM;\n exports.walkTextNodes = walkTextNodes;\n exports.addClassName = addClassName;\n exports.removeClassName = removeClassName;\n exports.normalizeTagName = normalizeTagName;\n exports.isTextNode = isTextNode;\n exports.isCommentNode = isCommentNode;\n exports.isElementNode = isElementNode;\n exports.parseHTML = parseHTML;\n exports.serializeHTML = serializeHTML;\n});","define('mobiledoc-kit/utils/element-map', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // start at one to make the falsy semantics easier\n var uuidGenerator = 1;\n\n var ElementMap = (function () {\n function ElementMap() {\n _classCallCheck(this, ElementMap);\n\n this._map = {};\n }\n\n _createClass(ElementMap, [{\n key: 'set',\n value: function set(key, value) {\n var uuid = key._uuid;\n if (!uuid) {\n key._uuid = uuid = '' + uuidGenerator++;\n }\n this._map[uuid] = value;\n }\n }, {\n key: 'get',\n value: function get(key) {\n if (key._uuid) {\n return this._map[key._uuid];\n }\n return null;\n }\n }, {\n key: 'remove',\n value: function remove(key) {\n (0, _mobiledocKitUtilsAssert['default'])('tried to fetch a value for an element not seen before', !!key._uuid);\n delete this._map[key._uuid];\n }\n }]);\n\n return ElementMap;\n })();\n\n exports['default'] = ElementMap;\n});","define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function getEventTargetMatchingTag(tagName, target, container) {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n // Traverses up DOM from an event target to find the node matching specifed tag\n while (target && target !== container) {\n if ((0, _mobiledocKitUtilsDomUtils.normalizeTagName)(target.tagName) === tagName) {\n return target;\n }\n target = target.parentNode;\n }\n }\n\n function getElementRelativeOffset(element) {\n var offset = { left: 0, top: -window.pageYOffset };\n var offsetParent = element.offsetParent;\n var offsetParentPosition = window.getComputedStyle(offsetParent).position;\n var offsetParentRect;\n\n if (offsetParentPosition === 'relative') {\n offsetParentRect = offsetParent.getBoundingClientRect();\n offset.left = offsetParentRect.left;\n offset.top = offsetParentRect.top;\n }\n return offset;\n }\n\n function getElementComputedStyleNumericProp(element, prop) {\n return parseFloat(window.getComputedStyle(element)[prop]);\n }\n\n function positionElementToRect(element, rect, topOffset, leftOffset) {\n var relativeOffset = getElementRelativeOffset(element);\n var style = element.style;\n var round = Math.round;\n var left, top;\n\n topOffset = topOffset || 0;\n leftOffset = leftOffset || 0;\n left = round(rect.left - relativeOffset.left - leftOffset);\n top = round(rect.top - relativeOffset.top - topOffset);\n style.left = left + 'px';\n style.top = top + 'px';\n return { left: left, top: top };\n }\n\n function positionElementHorizontallyCenteredToRect(element, rect, topOffset) {\n var horizontalCenter = element.offsetWidth / 2 - rect.width / 2;\n return positionElementToRect(element, rect, topOffset, horizontalCenter);\n }\n\n function positionElementCenteredBelow(element, belowElement) {\n var elementMargin = getElementComputedStyleNumericProp(element, 'marginTop');\n return positionElementHorizontallyCenteredToRect(element, belowElement.getBoundingClientRect(), -element.offsetHeight - elementMargin);\n }\n\n function setData(element, name, value) {\n if (element.dataset) {\n element.dataset[name] = value;\n } else {\n var dataName = (0, _mobiledocKitUtilsStringUtils.dasherize)(name);\n return element.setAttribute(dataName, value);\n }\n }\n\n exports.setData = setData;\n exports.getEventTargetMatchingTag = getEventTargetMatchingTag;\n exports.getElementRelativeOffset = getElementRelativeOffset;\n exports.getElementComputedStyleNumericProp = getElementComputedStyleNumericProp;\n exports.positionElementToRect = positionElementToRect;\n exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect;\n exports.positionElementCenteredBelow = positionElementCenteredBelow;\n});","define('mobiledoc-kit/utils/environment', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n hasDOM: function hasDOM() {\n return typeof document !== 'undefined';\n }\n };\n});","define(\"mobiledoc-kit/utils/fixed-queue\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var FixedQueue = (function () {\n function FixedQueue() {\n var length = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\n _classCallCheck(this, FixedQueue);\n\n this._maxLength = length;\n this._items = [];\n }\n\n _createClass(FixedQueue, [{\n key: \"pop\",\n value: function pop() {\n return this._items.pop();\n }\n }, {\n key: \"push\",\n value: function push(item) {\n this._items.push(item);\n if (this.length > this._maxLength) {\n this._items.shift();\n }\n }\n }, {\n key: \"clear\",\n value: function clear() {\n this._items = [];\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this._items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this._items.length;\n }\n }]);\n\n return FixedQueue;\n })();\n\n exports[\"default\"] = FixedQueue;\n});","define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.modifierMask = modifierMask;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * @typedef Direction\n * @enum {number}\n * @property {number} FORWARD\n * @property {number} BACKWARD\n */\n var DIRECTION = {\n FORWARD: 1,\n BACKWARD: -1\n };\n exports.DIRECTION = DIRECTION;\n var MODIFIERS = {\n META: 1, // also called \"command\" on OS X\n CTRL: 2,\n SHIFT: 4,\n ALT: 8 // also called \"option\" on OS X\n };\n\n exports.MODIFIERS = MODIFIERS;\n\n function modifierMask(event) {\n var metaKey = event.metaKey;\n var shiftKey = event.shiftKey;\n var ctrlKey = event.ctrlKey;\n var altKey = event.altKey;\n\n var modVal = function modVal(val, modifier) {\n return val && modifier || 0;\n };\n return modVal(metaKey, MODIFIERS.META) + modVal(shiftKey, MODIFIERS.SHIFT) + modVal(ctrlKey, MODIFIERS.CTRL) + modVal(altKey, MODIFIERS.ALT);\n }\n\n var SPECIAL_KEYS = {\n BACKSPACE: _mobiledocKitUtilsKeycodes['default'].BACKSPACE,\n TAB: _mobiledocKitUtilsKeycodes['default'].TAB,\n ENTER: _mobiledocKitUtilsKeycodes['default'].ENTER,\n ESC: _mobiledocKitUtilsKeycodes['default'].ESC,\n SPACE: _mobiledocKitUtilsKeycodes['default'].SPACE,\n PAGEUP: _mobiledocKitUtilsKeycodes['default'].PAGEUP,\n PAGEDOWN: _mobiledocKitUtilsKeycodes['default'].PAGEDOWN,\n END: _mobiledocKitUtilsKeycodes['default'].END,\n HOME: _mobiledocKitUtilsKeycodes['default'].HOME,\n LEFT: _mobiledocKitUtilsKeycodes['default'].LEFT,\n UP: _mobiledocKitUtilsKeycodes['default'].UP,\n RIGHT: _mobiledocKitUtilsKeycodes['default'].RIGHT,\n DOWN: _mobiledocKitUtilsKeycodes['default'].DOWN,\n INS: _mobiledocKitUtilsKeycodes['default'].INS,\n DEL: _mobiledocKitUtilsKeycodes['default'].DELETE\n };\n\n exports.SPECIAL_KEYS = SPECIAL_KEYS;\n // heuristic for determining if `event` is a key event\n function isKeyEvent(event) {\n return (/^key/.test(event.type)\n );\n }\n\n /**\n * An abstraction around a KeyEvent\n * that key listeners in the editor can use\n * to determine what sort of key was pressed\n */\n var Key = (function () {\n function Key(event) {\n _classCallCheck(this, Key);\n\n this.keyCode = event.keyCode;\n this.charCode = event.charCode;\n this.event = event;\n this.modifierMask = modifierMask(event);\n }\n\n _createClass(Key, [{\n key: 'toString',\n value: function toString() {\n if (this.isTab()) {\n return _mobiledocKitUtilsCharacters.TAB;\n }\n return String.fromCharCode(this.charCode);\n }\n }, {\n key: 'isEscape',\n value: function isEscape() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ESC;\n }\n }, {\n key: 'isDelete',\n value: function isDelete() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].BACKSPACE || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE;\n }\n }, {\n key: 'isForwardDelete',\n value: function isForwardDelete() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].DELETE;\n }\n }, {\n key: 'isArrow',\n value: function isArrow() {\n return this.isHorizontalArrow() || this.isVerticalArrow();\n }\n }, {\n key: 'isHorizontalArrow',\n value: function isHorizontalArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT || this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT;\n }\n }, {\n key: 'isHorizontalArrowWithoutModifiersOtherThanShift',\n value: function isHorizontalArrowWithoutModifiersOtherThanShift() {\n return this.isHorizontalArrow() && !(this.ctrlKey || this.metaKey || this.altKey);\n }\n }, {\n key: 'isVerticalArrow',\n value: function isVerticalArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].UP || this.keyCode === _mobiledocKitUtilsKeycodes['default'].DOWN;\n }\n }, {\n key: 'isLeftArrow',\n value: function isLeftArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].LEFT;\n }\n }, {\n key: 'isRightArrow',\n value: function isRightArrow() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].RIGHT;\n }\n }, {\n key: 'isHome',\n value: function isHome() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].HOME;\n }\n }, {\n key: 'isEnd',\n value: function isEnd() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].END;\n }\n }, {\n key: 'isSpace',\n value: function isSpace() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SPACE;\n }\n }, {\n key: 'isTab',\n value: function isTab() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].TAB;\n }\n }, {\n key: 'isEnter',\n value: function isEnter() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ENTER;\n }\n\n /**\n * If the shift key is depressed.\n * For example, while holding down meta+shift, pressing the \"v\"\n * key would result in an event whose `Key` had `isShift()` with a truthy value,\n * because the shift key is down when pressing the \"v\".\n * @see {isShiftKey} which checks if the key is actually the shift key itself.\n * @return {bool}\n */\n }, {\n key: 'isShift',\n value: function isShift() {\n return this.shiftKey;\n }\n\n /*\n * If the key is the actual shift key. This is false when the shift key\n * is held down and the source `event` is not the shift key.\n * @see {isShift}\n * @return {bool}\n */\n }, {\n key: 'isShiftKey',\n value: function isShiftKey() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].SHIFT;\n }\n\n /*\n * If the key is the actual alt key (aka \"option\" on mac). This is false when the alt key\n * is held down and the source `event` is not the alt key.\n * @return {bool}\n */\n }, {\n key: 'isAltKey',\n value: function isAltKey() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].ALT;\n }\n\n /*\n * If the key is the actual ctrl key. This is false when the ctrl key\n * is held down and the source `event` is not the ctrl key.\n * @return {bool}\n */\n }, {\n key: 'isCtrlKey',\n value: function isCtrlKey() {\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].CTRL;\n }\n }, {\n key: 'hasModifier',\n value: function hasModifier(modifier) {\n return modifier & this.modifierMask;\n }\n }, {\n key: 'hasAnyModifier',\n value: function hasAnyModifier() {\n return !!this.modifierMask;\n }\n }, {\n key: 'isPrintable',\n\n /**\n * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position\n * and http://stackoverflow.com/a/12467610/137784\n */\n value: function isPrintable() {\n if (this.ctrlKey || this.metaKey) {\n return false;\n }\n\n var code = this.keyCode;\n\n // Firefox calls keypress events for arrow keys, but they should not be\n // considered printable\n if (this.isArrow()) {\n return false;\n }\n\n return code !== 0 || this.toString().length > 0 || code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || // number keys\n this.isSpace() || this.isTab() || this.isEnter() || code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || // letter keys\n code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9 || // numpad keys\n code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || // punctuation\n code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['\"'] ||\n // FIXME the IME action seems to get lost when we issue an `editor.deleteSelection`\n // before it (in Chrome)\n code === _mobiledocKitUtilsKeycodes['default'].IME;\n }\n }, {\n key: 'direction',\n get: function get() {\n switch (true) {\n case this.isDelete():\n return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n case this.isHorizontalArrow():\n return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n }\n }\n }, {\n key: 'ctrlKey',\n get: function get() {\n return MODIFIERS.CTRL & this.modifierMask;\n }\n }, {\n key: 'metaKey',\n get: function get() {\n return MODIFIERS.META & this.modifierMask;\n }\n }, {\n key: 'shiftKey',\n get: function get() {\n return MODIFIERS.SHIFT & this.modifierMask;\n }\n }, {\n key: 'altKey',\n get: function get() {\n return MODIFIERS.ALT & this.modifierMask;\n }\n }], [{\n key: 'fromEvent',\n value: function fromEvent(event) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass a Key event to Key.fromEvent', event && isKeyEvent(event));\n return new Key(event);\n }\n }]);\n\n return Key;\n })();\n\n exports['default'] = Key;\n});","define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n BACKSPACE: 8,\n SPACE: 32,\n ENTER: 13,\n SHIFT: 16,\n ESC: 27,\n DELETE: 46,\n '0': 48,\n '9': 57,\n A: 65,\n Z: 90,\n a: 97,\n z: 122,\n 'NUMPAD_0': 186,\n 'NUMPAD_9': 111,\n ';': 186,\n '.': 190,\n '`': 192,\n '[': 219,\n '\"': 222,\n\n // Input Method Editor uses multiple keystrokes to display characters.\n // Example on mac: press option-i then i. This fires 2 key events in Chrome\n // with keyCode 229 and displays ˆ and then î.\n // See http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html#fixed-virtual-key-codes\n IME: 229,\n\n TAB: 9,\n PAGEUP: 33,\n PAGEDOWN: 34,\n END: 35,\n HOME: 36,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n INS: 45,\n META: 91,\n ALT: 18,\n CTRL: 17\n };\n});","define(\"mobiledoc-kit/utils/linked-item\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var LinkedItem = function LinkedItem() {\n _classCallCheck(this, LinkedItem);\n\n this.next = null;\n this.prev = null;\n };\n\n exports[\"default\"] = LinkedItem;\n});","define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var PARENT_PROP = '__parent';\n\n var LinkedList = (function () {\n function LinkedList(options) {\n _classCallCheck(this, LinkedList);\n\n this.head = null;\n this.tail = null;\n this.length = 0;\n\n if (options) {\n var adoptItem = options.adoptItem;\n var freeItem = options.freeItem;\n\n this._adoptItem = adoptItem;\n this._freeItem = freeItem;\n }\n }\n\n _createClass(LinkedList, [{\n key: 'adoptItem',\n value: function adoptItem(item) {\n item[PARENT_PROP] = this;\n this.length++;\n if (this._adoptItem) {\n this._adoptItem(item);\n }\n }\n }, {\n key: 'freeItem',\n value: function freeItem(item) {\n item[PARENT_PROP] = null;\n this.length--;\n if (this._freeItem) {\n this._freeItem(item);\n }\n }\n }, {\n key: 'prepend',\n value: function prepend(item) {\n this.insertBefore(item, this.head);\n }\n }, {\n key: 'append',\n value: function append(item) {\n this.insertBefore(item, null);\n }\n }, {\n key: 'insertAfter',\n value: function insertAfter(item, prevItem) {\n var nextItem = prevItem ? prevItem.next : this.head;\n this.insertBefore(item, nextItem);\n }\n }, {\n key: '_ensureItemIsNotAlreadyInList',\n value: function _ensureItemIsNotAlreadyInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item.next && !item.prev && this.head !== item);\n }\n }, {\n key: 'insertBefore',\n value: function insertBefore(item, nextItem) {\n this._ensureItemIsNotInList(item);\n this.adoptItem(item);\n\n var insertPos = undefined;\n if (nextItem && nextItem.prev) {\n insertPos = 'middle';\n } else if (nextItem) {\n insertPos = 'start';\n } else {\n insertPos = 'end';\n }\n\n switch (insertPos) {\n case 'start':\n if (this.head) {\n item.next = this.head;\n this.head.prev = item;\n }\n this.head = item;\n\n break;\n case 'middle':\n var prevItem = nextItem.prev;\n item.next = nextItem;\n item.prev = prevItem;\n nextItem.prev = item;\n prevItem.next = item;\n\n break;\n case 'end':\n var tail = this.tail;\n item.prev = tail;\n\n if (tail) {\n tail.next = item;\n } else {\n this.head = item;\n }\n this.tail = item;\n\n break;\n }\n }\n }, {\n key: 'remove',\n value: function remove(item) {\n if (!item[PARENT_PROP]) {\n return;\n }\n this._ensureItemIsInThisList(item);\n this.freeItem(item);\n\n var prev = item.prev;\n var next = item.next;\n\n item.prev = null;\n item.next = null;\n\n if (prev) {\n prev.next = next;\n } else {\n this.head = next;\n }\n\n if (next) {\n next.prev = prev;\n } else {\n this.tail = prev;\n }\n }\n }, {\n key: 'forEach',\n value: function forEach(callback) {\n var item = this.head;\n var index = 0;\n while (item) {\n callback(item, index++);\n item = item.next;\n }\n }\n }, {\n key: 'map',\n value: function map(callback) {\n var result = [];\n this.forEach(function (i) {\n return result.push(callback(i));\n });\n return result;\n }\n }, {\n key: 'walk',\n value: function walk(startItem, endItem, callback) {\n var item = startItem || this.head;\n while (item) {\n callback(item);\n if (item === endItem) {\n break;\n }\n item = item.next;\n }\n }\n }, {\n key: 'readRange',\n value: function readRange(startItem, endItem) {\n var items = [];\n this.walk(startItem, endItem, function (item) {\n items.push(item);\n });\n return items;\n }\n }, {\n key: 'toArray',\n value: function toArray() {\n return this.readRange();\n }\n }, {\n key: 'detect',\n value: function detect(callback) {\n var item = arguments.length <= 1 || arguments[1] === undefined ? this.head : arguments[1];\n var reverse = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n while (item) {\n if (callback(item)) {\n return item;\n }\n item = reverse ? item.prev : item.next;\n }\n }\n }, {\n key: 'any',\n value: function any(callback) {\n return !!this.detect(callback);\n }\n }, {\n key: 'every',\n value: function every(callback) {\n var item = this.head;\n while (item) {\n if (!callback(item)) {\n return false;\n }\n item = item.next;\n }\n return true;\n }\n }, {\n key: 'objectAt',\n value: function objectAt(targetIndex) {\n var index = -1;\n return this.detect(function () {\n index++;\n return targetIndex === index;\n });\n }\n }, {\n key: 'splice',\n value: function splice(targetItem, removalCount, newItems) {\n var _this = this;\n\n var item = targetItem;\n var nextItem = item.next;\n var count = 0;\n while (item && count < removalCount) {\n count++;\n nextItem = item.next;\n this.remove(item);\n item = nextItem;\n }\n newItems.forEach(function (newItem) {\n _this.insertBefore(newItem, nextItem);\n });\n }\n }, {\n key: 'removeBy',\n value: function removeBy(conditionFn) {\n var item = this.head;\n while (item) {\n var nextItem = item.next;\n\n if (conditionFn(item)) {\n this.remove(item);\n }\n\n item = nextItem;\n }\n }\n }, {\n key: '_ensureItemIsNotInList',\n value: function _ensureItemIsNotInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item[PARENT_PROP]);\n }\n }, {\n key: '_ensureItemIsInThisList',\n value: function _ensureItemIsInThisList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot remove item that is in another list', item[PARENT_PROP] === this);\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.length === 0;\n }\n }]);\n\n return LinkedList;\n })();\n\n exports['default'] = LinkedList;\n});","define(\"mobiledoc-kit/utils/log-manager\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Logger = (function () {\n function Logger(type, manager) {\n _classCallCheck(this, Logger);\n\n this.type = type;\n this.manager = manager;\n }\n\n _createClass(Logger, [{\n key: \"isEnabled\",\n value: function isEnabled() {\n return this.manager.isEnabled(this.type);\n }\n }, {\n key: \"log\",\n value: function log() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n args.unshift(\"[\" + this.type + \"]\");\n if (this.isEnabled()) {\n var _window$console;\n\n (_window$console = window.console).log.apply(_window$console, args);\n }\n }\n }]);\n\n return Logger;\n })();\n\n var LogManager = (function () {\n function LogManager() {\n _classCallCheck(this, LogManager);\n\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n\n _createClass(LogManager, [{\n key: \"for\",\n value: function _for(type) {\n return new Logger(type, this);\n }\n }, {\n key: \"enableAll\",\n value: function enableAll() {\n this.allEnabled = true;\n }\n }, {\n key: \"enableTypes\",\n value: function enableTypes(types) {\n this.enabledTypes = this.enabledTypes.concat(types);\n }\n }, {\n key: \"disable\",\n value: function disable() {\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n }, {\n key: \"isEnabled\",\n value: function isEnabled(type) {\n return this.allEnabled || this.enabledTypes.indexOf(type) !== -1;\n }\n }]);\n\n return LogManager;\n })();\n\n exports[\"default\"] = LogManager;\n});","define('mobiledoc-kit/utils/markuperable', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var Markerupable = (function () {\n function Markerupable() {\n _classCallCheck(this, Markerupable);\n }\n\n _createClass(Markerupable, [{\n key: 'clearMarkups',\n value: function clearMarkups() {\n this.markups = [];\n }\n }, {\n key: 'addMarkup',\n value: function addMarkup(markup) {\n this.markups.push(markup);\n }\n }, {\n key: 'addMarkupAtIndex',\n value: function addMarkupAtIndex(markup, index) {\n this.markups.splice(index, 0, markup);\n }\n }, {\n key: 'removeMarkup',\n value: function removeMarkup(markupOrMarkupCallback) {\n var _this = this;\n\n var callback = undefined;\n if (typeof markupOrMarkupCallback === 'function') {\n callback = markupOrMarkupCallback;\n } else {\n (function () {\n var markup = markupOrMarkupCallback;\n callback = function (_markup) {\n return _markup === markup;\n };\n })();\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.markups, callback), function (m) {\n return _this._removeMarkup(m);\n });\n }\n }, {\n key: '_removeMarkup',\n value: function _removeMarkup(markup) {\n var index = this.markups.indexOf(markup);\n if (index !== -1) {\n this.markups.splice(index, 1);\n }\n }\n }, {\n key: 'hasMarkup',\n value: function hasMarkup(tagNameOrMarkup) {\n return !!this.getMarkup(tagNameOrMarkup);\n }\n }, {\n key: 'getMarkup',\n value: function getMarkup(tagNameOrMarkup) {\n var _this2 = this;\n\n if (typeof tagNameOrMarkup === 'string') {\n var _ret2 = (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagNameOrMarkup);\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup.tagName === tagName;\n })\n };\n })();\n\n if (typeof _ret2 === 'object') return _ret2.v;\n } else {\n var _ret3 = (function () {\n var targetMarkup = tagNameOrMarkup;\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup === targetMarkup;\n })\n };\n })();\n\n if (typeof _ret3 === 'object') return _ret3.v;\n }\n }\n }, {\n key: 'openedMarkups',\n get: function get() {\n var count = 0;\n if (this.prev) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.prev.markups);\n }\n\n return this.markups.slice(count);\n }\n }, {\n key: 'closedMarkups',\n get: function get() {\n var count = 0;\n if (this.next) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.next.markups);\n }\n\n return this.markups.slice(count);\n }\n }]);\n\n return Markerupable;\n })();\n\n exports['default'] = Markerupable;\n});","define(\"mobiledoc-kit/utils/merge\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function mergeWithOptions(original, updates, options) {\n options = options || {};\n for (var prop in updates) {\n if (options.hasOwnProperty(prop)) {\n original[prop] = options[prop];\n } else if (updates.hasOwnProperty(prop)) {\n original[prop] = updates[prop];\n }\n }\n return original;\n }\n\n /**\n * Merges properties of one object into another\n * @private\n */\n function merge(original, updates) {\n return mergeWithOptions(original, updates);\n }\n\n exports.mergeWithOptions = mergeWithOptions;\n exports.merge = merge;\n});","define('mobiledoc-kit/utils/mixin', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = mixin;\n var CONSTRUCTOR_FN_NAME = 'constructor';\n\n function mixin(target, source) {\n target = target.prototype;\n // Fallback to just `source` to allow mixing in a plain object (pojo)\n source = source.prototype || source;\n\n Object.getOwnPropertyNames(source).forEach(function (name) {\n if (name !== CONSTRUCTOR_FN_NAME) {\n var descriptor = Object.getOwnPropertyDescriptor(source, name);\n\n Object.defineProperty(target, name, descriptor);\n }\n });\n }\n});","define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) {\n 'use strict';\n\n var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];\n\n function MobiledocError() {\n var tmp = Error.apply(this, arguments);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.\n for (var idx = 0; idx < errorProps.length; idx++) {\n this[errorProps[idx]] = tmp[errorProps[idx]];\n }\n }\n\n MobiledocError.prototype = Object.create(Error.prototype);\n\n exports['default'] = MobiledocError;\n});","define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) {\n /* global JSON */\n 'use strict';\n\n exports.getContentFromPasteEvent = getContentFromPasteEvent;\n exports.setClipboardData = setClipboardData;\n exports.parsePostFromPaste = parsePostFromPaste;\n exports.parsePostFromDrop = parsePostFromDrop;\n var MIME_TEXT_PLAIN = 'text/plain';\n exports.MIME_TEXT_PLAIN = MIME_TEXT_PLAIN;\n var MIME_TEXT_HTML = 'text/html';\n exports.MIME_TEXT_HTML = MIME_TEXT_HTML;\n var NONSTANDARD_IE_TEXT_TYPE = 'Text';\n\n exports.NONSTANDARD_IE_TEXT_TYPE = NONSTANDARD_IE_TEXT_TYPE;\n var MOBILEDOC_REGEX = new RegExp(/data\\-mobiledoc='(.*?)'>/);\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromHTML(html, builder, plugins) {\n var post = undefined;\n\n if (MOBILEDOC_REGEX.test(html)) {\n var mobiledocString = html.match(MOBILEDOC_REGEX)[1];\n var mobiledoc = JSON.parse(mobiledocString);\n post = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n } else {\n post = new _mobiledocKitParsersHtml['default'](builder, { plugins: plugins }).parse(html);\n }\n\n return post;\n }\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromText(text, builder, plugins) {\n var parser = new _mobiledocKitParsersText['default'](builder, { plugins: plugins });\n var post = parser.parse(text);\n return post;\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n\n function getContentFromPasteEvent(event, window) {\n var html = '',\n text = '';\n\n var clipboardData = event.clipboardData;\n\n if (clipboardData && clipboardData.getData) {\n html = clipboardData.getData(MIME_TEXT_HTML);\n text = clipboardData.getData(MIME_TEXT_PLAIN);\n } else if (window.clipboardData && window.clipboardData.getData) {\n // IE\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n html = window.clipboardData.getData(NONSTANDARD_IE_TEXT_TYPE);\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n function getContentFromDropEvent(event, logger) {\n var html = '',\n text = '';\n\n try {\n html = event.dataTransfer.getData(MIME_TEXT_HTML);\n text = event.dataTransfer.getData(MIME_TEXT_PLAIN);\n } catch (e) {\n // FIXME IE11 does not include any data in the 'text/html' or 'text/plain'\n // mimetypes. It throws an error 'Invalid argument' when attempting to read\n // these properties.\n if (logger) {\n logger.log('Error getting drop data: ', e);\n }\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @param {CopyEvent|CutEvent}\n * @param {Editor}\n * @param {Window}\n * @private\n */\n\n function setClipboardData(event, _ref, window) {\n var mobiledoc = _ref.mobiledoc;\n var html = _ref.html;\n var text = _ref.text;\n\n if (mobiledoc && html) {\n html = '
    ' + html + '
    ';\n }\n\n var clipboardData = event.clipboardData;\n var nonstandardClipboardData = window.clipboardData;\n\n if (clipboardData && clipboardData.setData) {\n clipboardData.setData(MIME_TEXT_HTML, html);\n clipboardData.setData(MIME_TEXT_PLAIN, text);\n } else if (nonstandardClipboardData && nonstandardClipboardData.setData) {\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n nonstandardClipboardData.setData(NONSTANDARD_IE_TEXT_TYPE, html);\n }\n }\n\n /**\n * @param {PasteEvent}\n * @param {{builder: Builder, _parserPlugins: Array}} options\n * @return {Post}\n * @private\n */\n\n function parsePostFromPaste(pasteEvent, _ref2) {\n var builder = _ref2.builder;\n var plugins = _ref2._parserPlugins;\n\n var _ref3 = arguments.length <= 2 || arguments[2] === undefined ? { targetFormat: 'html' } : arguments[2];\n\n var targetFormat = _ref3.targetFormat;\n\n var _getContentFromPasteEvent = getContentFromPasteEvent(pasteEvent, window);\n\n var html = _getContentFromPasteEvent.html;\n var text = _getContentFromPasteEvent.text;\n\n if (targetFormat === 'html' && html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n\n /**\n * @param {DropEvent}\n * @param {Editor} editor\n * @param {Object} [options={}] Can pass a logger\n * @return {Post}\n * @private\n */\n\n function parsePostFromDrop(dropEvent, editor) {\n var _ref4 = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var logger = _ref4.logger;\n var builder = editor.builder;\n var plugins = editor._parserPlugins;\n\n var _getContentFromDropEvent = getContentFromDropEvent(dropEvent, logger);\n\n var html = _getContentFromDropEvent.html;\n var text = _getContentFromDropEvent.text;\n\n if (html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n});","define(\"mobiledoc-kit/utils/placeholder-image-src\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var placeholderImageSrc = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAMFBMVEXp7vG6vsHm6+63u77Hy868wMPe4+bO09bh5unr8fTR1djAxMfM0NPX3N/c4eTBxcjXRf5TAAACh0lEQVR4nO3b6ZKqMBSFUSQMYZL3f9tbBq/NEEDiqUqOfusn1ZXKbjcQlGQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC6RkbsGHuabChEtHmiGYfS3EQYM+Sxw/gMQvmcNnYaj6oTDHi73WPn2eqnj9B8zo3TJXcq5uNjXmVff86VwSR3JtryMa1BYqi7S1hJDCVpSigyLcGhJJEwzlCSNtPKrbVhVwsdCfOhH7uuaG3ARV9DwsaOzxt3N1yPqCHhvXytTUz92VDpmE/LLhZwl++R6Sds6sUa/PL6K/2E2fIhw1xdRKefsFolrPc+xNx/N0k/4fpBsdhL2HfeiN+TsDCms8dDpeRyS3P3QDl6Iqaf8L0rTf+80m6Lmn7Ct+4Wxf+/2RY1/YRv3PHz/u+fsCmqgoTnq7Z+8SGviqoh4dnKu1ieqauiakh4/PQ0r6ivqDoSHj0B97eNRVG1JNxV+L4bnxdVecJtRTdFVZ7QU9F1UXUn9FZ0VVRlCav5ob2KLouqKmFjy676u2HsVnRRVFUJq3J+8KCi86IqSthMvyl209Hjijqm3RsqAZ5pNfa5PJ2KelJRjQmr1/r7cfy0ouoSNvOfvbvhvKLaEr4qOin9kTQnrN7LpDZhE/Zmhp6Eq4p+YcKgiipKGFhRRQkDK6ooYfgLbiSMioQkJGF8P5XwHv4O+7AaKiXzaeXh1kMl5AffTUxiKEm/krD94BR8Gdxl1fceSlR58ZhXKbEpyD2amNiBtmrJLTMHL1LF8/rpXkSZXEmz8K8uvAFFNm6Iq0aBLUFOmeCuJ6exrcCmoLpN7kYx891bSAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgh/wDdr8peyRHLogAAAAASUVORK5CYII=\";\n\n exports[\"default\"] = placeholderImageSrc;\n});","define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function clearSelection() {\n window.getSelection().removeAllRanges();\n }\n\n function textNodeRects(node) {\n var range = document.createRange();\n range.setEnd(node, node.nodeValue.length);\n range.setStart(node, 0);\n return range.getClientRects();\n }\n\n function findOffsetInTextNode(node, coords) {\n var len = node.nodeValue.length;\n var range = document.createRange();\n for (var i = 0; i < len; i++) {\n range.setEnd(node, i + 1);\n range.setStart(node, i);\n var rect = range.getBoundingClientRect();\n if (rect.top === rect.bottom) {\n continue;\n }\n if (rect.left <= coords.left && rect.right >= coords.left && rect.top <= coords.top && rect.bottom >= coords.top) {\n return { node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };\n }\n }\n return { node: node, offset: 0 };\n }\n\n /*\n * @param {Object} coords with `top` and `left`\n * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js\n * @return {Object} {node, offset}\n */\n function findOffsetInNode(_x, _x2) {\n var _again = true;\n\n _function: while (_again) {\n var node = _x,\n coords = _x2;\n _again = false;\n\n var closest = undefined,\n dyClosest = 1e8,\n coordsClosest = undefined,\n offset = 0;\n for (var child = node.firstChild; child; child = child.nextSibling) {\n var rects = undefined;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child)) {\n rects = child.getClientRects();\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(child)) {\n rects = textNodeRects(child);\n } else {\n continue;\n }\n\n for (var i = 0; i < rects.length; i++) {\n var rect = rects[i];\n if (rect.left <= coords.left && rect.right >= coords.left) {\n var dy = rect.top > coords.top ? rect.top - coords.top : rect.bottom < coords.top ? coords.top - rect.bottom : 0;\n if (dy < dyClosest) {\n closest = child;\n dyClosest = dy;\n coordsClosest = dy ? { left: coords.left, top: rect.top } : coords;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child) && !child.firstChild) {\n offset = i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);\n }\n continue;\n }\n }\n if (!closest && (coords.top >= rect.bottom || coords.top >= rect.top && coords.left >= rect.right)) {\n offset = i + 1;\n }\n }\n }\n if (!closest) {\n return { node: node, offset: offset };\n }\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(closest)) {\n return findOffsetInTextNode(closest, coordsClosest);\n }\n if (closest.firstChild) {\n _x = closest;\n _x2 = coordsClosest;\n _again = true;\n closest = dyClosest = coordsClosest = offset = child = rects = i = rect = dy = undefined;\n continue _function;\n }\n return { node: node, offset: offset };\n }\n }\n\n function constrainNodeTo(node, parentNode, existingOffset) {\n var compare = parentNode.compareDocumentPosition(node);\n if (compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n // the node is inside parentNode, do nothing\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_CONTAINS) {\n // the node contains parentNode. This shouldn't happen.\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_PRECEDING) {\n // node is before parentNode. return start of deepest first child\n var child = parentNode.firstChild;\n while (child.firstChild) {\n child = child.firstChild;\n }\n return { node: child, offset: 0 };\n } else if (compare & Node.DOCUMENT_POSITION_FOLLOWING) {\n // node is after parentNode. return end of deepest last child\n var child = parentNode.lastChild;\n while (child.lastChild) {\n child = child.lastChild;\n }\n\n var offset = (0, _mobiledocKitUtilsDomUtils.isTextNode)(child) ? child.textContent.length : 1;\n return { node: child, offset: offset };\n } else {\n return { node: node, offset: existingOffset };\n }\n }\n\n /*\n * Returns a new selection that is constrained within parentNode.\n * If the anchorNode or focusNode are outside the parentNode, they are replaced with the beginning\n * or end of the parentNode's children\n */\n function constrainSelectionTo(selection, parentNode) {\n var _constrainNodeTo = constrainNodeTo(selection.anchorNode, parentNode, selection.anchorOffset);\n\n var anchorNode = _constrainNodeTo.node;\n var anchorOffset = _constrainNodeTo.offset;\n\n var _constrainNodeTo2 = constrainNodeTo(selection.focusNode, parentNode, selection.focusOffset);\n\n var focusNode = _constrainNodeTo2.node;\n var focusOffset = _constrainNodeTo2.offset;\n\n return { anchorNode: anchorNode, anchorOffset: anchorOffset, focusNode: focusNode, focusOffset: focusOffset };\n }\n\n function comparePosition(_x3) {\n var _again2 = true;\n\n _function2: while (_again2) {\n var selection = _x3;\n _again2 = false;\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n var headNode = undefined,\n tailNode = undefined,\n headOffset = undefined,\n tailOffset = undefined,\n direction = undefined;\n\n var position = anchorNode.compareDocumentPosition(focusNode);\n\n // IE may select return focus and anchor nodes far up the DOM tree instead of\n // picking the deepest, most specific possible node. For example in\n //\n //
    abcdef
    \n //\n // with a cursor between c and d, IE might say the focusNode is
    with\n // an offset of 1. However the anchorNode for a selection might still be\n // 2 if there was a selection.\n //\n // This code walks down the DOM tree until a good comparison of position can be\n // made.\n //\n if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n if (focusOffset < focusNode.childNodes.length) {\n focusNode = focusNode.childNodes[focusOffset];\n focusOffset = 0;\n } else {\n // This situation happens on IE when triple-clicking to select.\n // Set the focus to the very last character inside the node.\n while (focusNode.lastChild) {\n focusNode = focusNode.lastChild;\n }\n focusOffset = focusNode.textContent.length;\n }\n\n _x3 = {\n focusNode: focusNode,\n focusOffset: focusOffset,\n anchorNode: anchorNode, anchorOffset: anchorOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = undefined;\n continue _function2;\n } else if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n var offset = anchorOffset - 1;\n if (offset < 0) {\n offset = 0;\n }\n _x3 = {\n anchorNode: anchorNode.childNodes[offset],\n anchorOffset: 0,\n focusNode: focusNode, focusOffset: focusOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = offset = undefined;\n continue _function2;\n\n // The meat of translating anchor and focus nodes to head and tail nodes\n } else if (position & Node.DOCUMENT_POSITION_FOLLOWING) {\n headNode = anchorNode;tailNode = focusNode;\n headOffset = anchorOffset;tailOffset = focusOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n headNode = focusNode;tailNode = anchorNode;\n headOffset = focusOffset;tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else {\n // same node\n headNode = tailNode = anchorNode;\n headOffset = anchorOffset;\n tailOffset = focusOffset;\n if (tailOffset < headOffset) {\n // Swap the offset order\n headOffset = focusOffset;\n tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else if (headOffset < tailOffset) {\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else {\n direction = null;\n }\n }\n\n return { headNode: headNode, headOffset: headOffset, tailNode: tailNode, tailOffset: tailOffset, direction: direction };\n }\n }\n\n exports.clearSelection = clearSelection;\n exports.comparePosition = comparePosition;\n exports.findOffsetInNode = findOffsetInNode;\n exports.constrainSelectionTo = constrainSelectionTo;\n});","define(\"mobiledoc-kit/utils/set\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Set = (function () {\n function Set() {\n var _this = this;\n\n var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, Set);\n\n this.items = [];\n items.forEach(function (i) {\n return _this.add(i);\n });\n }\n\n _createClass(Set, [{\n key: \"add\",\n value: function add(item) {\n if (!this.has(item)) {\n this.items.push(item);\n }\n }\n }, {\n key: \"has\",\n value: function has(item) {\n return this.items.indexOf(item) !== -1;\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this.items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this.items.length;\n }\n }]);\n\n return Set;\n })();\n\n exports[\"default\"] = Set;\n});","define('mobiledoc-kit/utils/string-utils', ['exports'], function (exports) {\n /*\n * @param {String} string\n * @return {String} a dasherized string. 'modelIndex' -> 'model-index', etc\n */\n 'use strict';\n\n exports.dasherize = dasherize;\n exports.capitalize = capitalize;\n exports.startsWith = startsWith;\n exports.endsWith = endsWith;\n\n function dasherize(string) {\n return string.replace(/[A-Z]/g, function (match, offset) {\n var lower = match.toLowerCase();\n\n return offset === 0 ? lower : '-' + lower;\n });\n }\n\n function capitalize(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n }\n\n function startsWith(string, character) {\n return string.charAt(0) === character;\n }\n\n function endsWith(string, endString) {\n var index = string.lastIndexOf(endString);\n return index !== -1 && index === string.length - endString.length;\n }\n});","define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports['default'] = toRange;\n\n function toRange(rangeLike) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass non-blank object to \"toRange\"', !!rangeLike);\n\n if (rangeLike instanceof _mobiledocKitUtilsCursorRange['default']) {\n return rangeLike;\n } else if (rangeLike instanceof _mobiledocKitUtilsCursorPosition['default']) {\n return rangeLike.toRange();\n }\n\n (0, _mobiledocKitUtilsAssert['default'])('Incorrect structure for rangeLike: ' + rangeLike, false);\n }\n});","define('mobiledoc-kit/version', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = '##VERSION##';\n});","define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var DELAY = 200;\n\n var Tooltip = (function (_View) {\n _inherits(Tooltip, _View);\n\n function Tooltip(options) {\n var _this = this;\n\n _classCallCheck(this, Tooltip);\n\n var rootElement = options.rootElement;\n\n var timeout = undefined;\n options.classNames = ['__mobiledoc-tooltip'];\n _get(Object.getPrototypeOf(Tooltip.prototype), 'constructor', this).call(this, options);\n\n this.addEventListener(rootElement, 'mouseover', function (e) {\n var target = (0, _mobiledocKitUtilsElementUtils.getEventTargetMatchingTag)(options.showForTag, e.target, rootElement);\n if (target && target.isContentEditable) {\n timeout = setTimeout(function () {\n _this.showLink(target.href, target);\n }, DELAY);\n }\n });\n\n this.addEventListener(rootElement, 'mouseout', function (e) {\n clearTimeout(timeout);\n var toElement = e.toElement || e.relatedTarget;\n if (toElement && toElement.className !== _this.element.className) {\n _this.hide();\n }\n });\n }\n\n _createClass(Tooltip, [{\n key: 'showMessage',\n value: function showMessage(message, element) {\n var tooltipElement = this.element;\n tooltipElement.innerHTML = message;\n this.show();\n (0, _mobiledocKitUtilsElementUtils.positionElementCenteredBelow)(tooltipElement, element);\n }\n }, {\n key: 'showLink',\n value: function showLink(link, element) {\n var message = '' + link + '';\n this.showMessage(message, element);\n }\n }]);\n\n return Tooltip;\n })(_mobiledocKitViewsView['default']);\n\n exports['default'] = Tooltip;\n});","define('mobiledoc-kit/views/view', ['exports', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var View = (function () {\n function View() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, View);\n\n options.tagName = options.tagName || 'div';\n options.container = options.container || document.body;\n\n this.element = document.createElement(options.tagName);\n this.container = options.container;\n this.isShowing = false;\n\n var classNames = options.classNames || [];\n classNames.forEach(function (name) {\n return (0, _mobiledocKitUtilsDomUtils.addClassName)(_this.element, name);\n });\n this._eventListeners = [];\n }\n\n _createClass(View, [{\n key: 'addEventListener',\n value: function addEventListener(element, type, listener) {\n element.addEventListener(type, listener);\n this._eventListeners.push([element, type, listener]);\n }\n }, {\n key: 'removeAllEventListeners',\n value: function removeAllEventListeners() {\n this._eventListeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var element = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n element.removeEventListener(type, listener);\n });\n }\n }, {\n key: 'show',\n value: function show() {\n if (!this.isShowing) {\n this.container.appendChild(this.element);\n this.isShowing = true;\n return true;\n }\n }\n }, {\n key: 'hide',\n value: function hide() {\n if (this.isShowing) {\n this.container.removeChild(this.element);\n this.isShowing = false;\n return true;\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.removeAllEventListeners();\n this.hide();\n this.isDestroyed = true;\n }\n }]);\n\n return View;\n })();\n\n exports['default'] = View;\n});","define('mobiledoc-text-renderer/cards/image', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n name: 'image-card',\n type: 'text',\n render: function render() {}\n };\n});","define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n function registerGlobal(window) {\n window.MobiledocTextRenderer = _mobiledocTextRendererRendererFactory['default'];\n }\n\n exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default'];\n exports['default'] = _mobiledocTextRendererRendererFactory['default'];\n});","define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var cards = _ref.cards;\n var atoms = _ref.atoms;\n var cardOptions = _ref.cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n\n _classCallCheck(this, RendererFactory);\n\n cards = cards || [];\n validateCards(cards);\n atoms = atoms || [];\n validateAtoms(atoms);\n cardOptions = cardOptions || {};\n\n this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION:\n return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render();\n case undefined:\n case null:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var sections = _sectionData[1];\n\n this.root = [];\n this.sections = sections;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n\n // for the text renderer, a missing card is a no-op\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var type = _ref32[0];\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 3);\n\n var text = _m[2];\n\n str += text;\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {};\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION_0_3 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION = MOBILEDOC_VERSION_0_3_1;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n\n validateVersion(version);\n\n this.root = [];\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var index = _ref32[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this4 = this;\n\n var env = {\n name: atom.name,\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || '';\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var _this5 = this;\n\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 4);\n\n var type = _m[0];\n var value = _m[3];\n\n switch (type) {\n case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n str += value;\n break;\n case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n str += _this5._renderAtom(value);\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {\n // for the text renderer, a missing card is a no-op\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref5) {\n var value = _ref5.value;\n\n return value || '';\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-text-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'text';\n});","define(\"mobiledoc-text-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACreA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5wCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACh3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1TA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/TA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9nBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5WA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;","file":"mobiledoc-kit.js"} \ No newline at end of file +{"version":3,"sources":["loader.js/loader.js","mobiledoc-dom-renderer/cards/image.js","mobiledoc-dom-renderer/index.js","mobiledoc-dom-renderer/renderer-factory.js","mobiledoc-dom-renderer/renderers/0-2.js","mobiledoc-dom-renderer/renderers/0-3.js","mobiledoc-dom-renderer/utils/array-utils.js","mobiledoc-dom-renderer/utils/dom.js","mobiledoc-dom-renderer/utils/marker-types.js","mobiledoc-dom-renderer/utils/render-type.js","mobiledoc-dom-renderer/utils/render-utils.js","mobiledoc-dom-renderer/utils/sanitization-utils.js","mobiledoc-dom-renderer/utils/section-types.js","mobiledoc-dom-renderer/utils/tag-names.js","mobiledoc-kit/cards/image.js","mobiledoc-kit/editor/edit-history.js","mobiledoc-kit/editor/edit-state.js","mobiledoc-kit/editor/editor.js","mobiledoc-kit/editor/event-manager.js","mobiledoc-kit/editor/key-commands.js","mobiledoc-kit/editor/mutation-handler.js","mobiledoc-kit/editor/post.js","mobiledoc-kit/editor/post/post-inserter.js","mobiledoc-kit/editor/selection-change-observer.js","mobiledoc-kit/editor/selection-manager.js","mobiledoc-kit/editor/text-input-handler.js","mobiledoc-kit/editor/text-input-handlers.js","mobiledoc-kit/editor/ui.js","mobiledoc-kit/index.js","mobiledoc-kit/models/_attributable.js","mobiledoc-kit/models/_markerable.js","mobiledoc-kit/models/_section.js","mobiledoc-kit/models/atom-node.js","mobiledoc-kit/models/atom.js","mobiledoc-kit/models/card-node.js","mobiledoc-kit/models/card.js","mobiledoc-kit/models/image.js","mobiledoc-kit/models/lifecycle-callbacks.js","mobiledoc-kit/models/list-item.js","mobiledoc-kit/models/list-section.js","mobiledoc-kit/models/marker.js","mobiledoc-kit/models/markup-section.js","mobiledoc-kit/models/markup.js","mobiledoc-kit/models/post-node-builder.js","mobiledoc-kit/models/post.js","mobiledoc-kit/models/render-node.js","mobiledoc-kit/models/render-tree.js","mobiledoc-kit/models/types.js","mobiledoc-kit/parsers/dom.js","mobiledoc-kit/parsers/html.js","mobiledoc-kit/parsers/mobiledoc/0-2.js","mobiledoc-kit/parsers/mobiledoc/0-3-1.js","mobiledoc-kit/parsers/mobiledoc/0-3-2.js","mobiledoc-kit/parsers/mobiledoc/0-3.js","mobiledoc-kit/parsers/mobiledoc/index.js","mobiledoc-kit/parsers/section.js","mobiledoc-kit/parsers/text.js","mobiledoc-kit/renderers/editor-dom.js","mobiledoc-kit/renderers/mobiledoc/0-2.js","mobiledoc-kit/renderers/mobiledoc/0-3-1.js","mobiledoc-kit/renderers/mobiledoc/0-3-2.js","mobiledoc-kit/renderers/mobiledoc/0-3.js","mobiledoc-kit/renderers/mobiledoc/index.js","mobiledoc-kit/utils/array-utils.js","mobiledoc-kit/utils/assert.js","mobiledoc-kit/utils/browser.js","mobiledoc-kit/utils/characters.js","mobiledoc-kit/utils/compiler.js","mobiledoc-kit/utils/copy.js","mobiledoc-kit/utils/cursor.js","mobiledoc-kit/utils/cursor/position.js","mobiledoc-kit/utils/cursor/range.js","mobiledoc-kit/utils/deprecate.js","mobiledoc-kit/utils/dom-utils.js","mobiledoc-kit/utils/element-map.js","mobiledoc-kit/utils/element-utils.js","mobiledoc-kit/utils/environment.js","mobiledoc-kit/utils/fixed-queue.js","mobiledoc-kit/utils/key.js","mobiledoc-kit/utils/keycodes.js","mobiledoc-kit/utils/keys.js","mobiledoc-kit/utils/linked-item.js","mobiledoc-kit/utils/linked-list.js","mobiledoc-kit/utils/log-manager.js","mobiledoc-kit/utils/markuperable.js","mobiledoc-kit/utils/merge.js","mobiledoc-kit/utils/mixin.js","mobiledoc-kit/utils/mobiledoc-error.js","mobiledoc-kit/utils/object-utils.js","mobiledoc-kit/utils/parse-utils.js","mobiledoc-kit/utils/placeholder-image-src.js","mobiledoc-kit/utils/selection-utils.js","mobiledoc-kit/utils/set.js","mobiledoc-kit/utils/string-utils.js","mobiledoc-kit/utils/to-range.js","mobiledoc-kit/version.js","mobiledoc-kit/views/tooltip.js","mobiledoc-kit/views/view.js","mobiledoc-text-renderer/cards/image.js","mobiledoc-text-renderer/index.js","mobiledoc-text-renderer/renderer-factory.js","mobiledoc-text-renderer/renderers/0-2.js","mobiledoc-text-renderer/renderers/0-3.js","mobiledoc-text-renderer/utils/marker-types.js","mobiledoc-text-renderer/utils/render-type.js","mobiledoc-text-renderer/utils/section-types.js"],"sourcesContent":["var loader, define, requireModule, require, requirejs;\n\n(function (global) {\n 'use strict';\n\n function dict() {\n var obj = Object.create(null);\n obj['__'] = undefined;\n delete obj['__'];\n return obj;\n }\n\n // Save off the original values of these globals, so we can restore them if someone asks us to\n var oldGlobals = {\n loader: loader,\n define: define,\n requireModule: requireModule,\n require: require,\n requirejs: requirejs\n };\n\n requirejs = require = requireModule = function (id) {\n var pending = [];\n var mod = findModule(id, '(require)', pending);\n\n for (var i = pending.length - 1; i >= 0; i--) {\n pending[i].exports();\n }\n\n return mod.module.exports;\n };\n\n loader = {\n noConflict: function (aliases) {\n var oldName, newName;\n\n for (oldName in aliases) {\n if (aliases.hasOwnProperty(oldName)) {\n if (oldGlobals.hasOwnProperty(oldName)) {\n newName = aliases[oldName];\n\n global[newName] = global[oldName];\n global[oldName] = oldGlobals[oldName];\n }\n }\n }\n },\n // Option to enable or disable the generation of default exports\n makeDefaultExport: true\n };\n\n var registry = dict();\n var seen = dict();\n\n var uuid = 0;\n\n function unsupportedModule(length) {\n throw new Error('an unsupported module was defined, expected `define(id, deps, module)` instead got: `' + length + '` arguments to define`');\n }\n\n var defaultDeps = ['require', 'exports', 'module'];\n\n function Module(id, deps, callback, alias) {\n this.uuid = uuid++;\n this.id = id;\n this.deps = !deps.length && callback.length ? defaultDeps : deps;\n this.module = { exports: {} };\n this.callback = callback;\n this.hasExportsAsDep = false;\n this.isAlias = alias;\n this.reified = new Array(deps.length);\n\n /*\n Each module normally passes through these states, in order:\n new : initial state\n pending : this module is scheduled to be executed\n reifying : this module's dependencies are being executed\n reified : this module's dependencies finished executing successfully\n errored : this module's dependencies failed to execute\n finalized : this module executed successfully\n */\n this.state = 'new';\n }\n\n Module.prototype.makeDefaultExport = function () {\n var exports = this.module.exports;\n if (exports !== null && (typeof exports === 'object' || typeof exports === 'function') && exports['default'] === undefined && Object.isExtensible(exports)) {\n exports['default'] = exports;\n }\n };\n\n Module.prototype.exports = function () {\n // if finalized, there is no work to do. If reifying, there is a\n // circular dependency so we must return our (partial) exports.\n if (this.state === 'finalized' || this.state === 'reifying') {\n return this.module.exports;\n }\n\n\n if (loader.wrapModules) {\n this.callback = loader.wrapModules(this.id, this.callback);\n }\n\n this.reify();\n\n var result = this.callback.apply(this, this.reified);\n this.reified.length = 0;\n this.state = 'finalized';\n\n if (!(this.hasExportsAsDep && result === undefined)) {\n this.module.exports = result;\n }\n if (loader.makeDefaultExport) {\n this.makeDefaultExport();\n }\n return this.module.exports;\n };\n\n Module.prototype.unsee = function () {\n this.state = 'new';\n this.module = { exports: {} };\n };\n\n Module.prototype.reify = function () {\n if (this.state === 'reified') {\n return;\n }\n this.state = 'reifying';\n try {\n this.reified = this._reify();\n this.state = 'reified';\n } finally {\n if (this.state === 'reifying') {\n this.state = 'errored';\n }\n }\n };\n\n Module.prototype._reify = function () {\n var reified = this.reified.slice();\n for (var i = 0; i < reified.length; i++) {\n var mod = reified[i];\n reified[i] = mod.exports ? mod.exports : mod.module.exports();\n }\n return reified;\n };\n\n Module.prototype.findDeps = function (pending) {\n if (this.state !== 'new') {\n return;\n }\n\n this.state = 'pending';\n\n var deps = this.deps;\n\n for (var i = 0; i < deps.length; i++) {\n var dep = deps[i];\n var entry = this.reified[i] = { exports: undefined, module: undefined };\n if (dep === 'exports') {\n this.hasExportsAsDep = true;\n entry.exports = this.module.exports;\n } else if (dep === 'require') {\n entry.exports = this.makeRequire();\n } else if (dep === 'module') {\n entry.exports = this.module;\n } else {\n entry.module = findModule(resolve(dep, this.id), this.id, pending);\n }\n }\n };\n\n Module.prototype.makeRequire = function () {\n var id = this.id;\n var r = function (dep) {\n return require(resolve(dep, id));\n };\n r['default'] = r;\n r.moduleId = id;\n r.has = function (dep) {\n return has(resolve(dep, id));\n };\n return r;\n };\n\n define = function (id, deps, callback) {\n var module = registry[id];\n\n // If a module for this id has already been defined and is in any state\n // other than `new` (meaning it has been or is currently being required),\n // then we return early to avoid redefinition.\n if (module && module.state !== 'new') {\n return;\n }\n\n if (arguments.length < 2) {\n unsupportedModule(arguments.length);\n }\n\n if (!Array.isArray(deps)) {\n callback = deps;\n deps = [];\n }\n\n if (callback instanceof Alias) {\n registry[id] = new Module(callback.id, deps, callback, true);\n } else {\n registry[id] = new Module(id, deps, callback, false);\n }\n };\n\n define.exports = function (name, defaultExport) {\n var module = registry[name];\n\n // If a module for this name has already been defined and is in any state\n // other than `new` (meaning it has been or is currently being required),\n // then we return early to avoid redefinition.\n if (module && module.state !== 'new') {\n return;\n }\n\n module = new Module(name, [], noop, null);\n module.module.exports = defaultExport;\n module.state = 'finalized';\n registry[name] = module;\n\n return module;\n };\n\n function noop() {}\n // we don't support all of AMD\n // define.amd = {};\n\n function Alias(id) {\n this.id = id;\n }\n\n define.alias = function (id, target) {\n if (arguments.length === 2) {\n return define(target, new Alias(id));\n }\n\n return new Alias(id);\n };\n\n function missingModule(id, referrer) {\n throw new Error('Could not find module `' + id + '` imported from `' + referrer + '`');\n }\n\n function findModule(id, referrer, pending) {\n var mod = registry[id] || registry[id + '/index'];\n\n while (mod && mod.isAlias) {\n mod = registry[mod.id] || registry[mod.id + '/index'];\n }\n\n if (!mod) {\n missingModule(id, referrer);\n }\n\n if (pending && mod.state !== 'pending' && mod.state !== 'finalized') {\n mod.findDeps(pending);\n pending.push(mod);\n }\n return mod;\n }\n\n function resolve(child, id) {\n if (child.charAt(0) !== '.') {\n return child;\n }\n\n\n var parts = child.split('/');\n var nameParts = id.split('/');\n var parentBase = nameParts.slice(0, -1);\n\n for (var i = 0, l = parts.length; i < l; i++) {\n var part = parts[i];\n\n if (part === '..') {\n if (parentBase.length === 0) {\n throw new Error('Cannot access parent module of root');\n }\n parentBase.pop();\n } else if (part === '.') {\n continue;\n } else {\n parentBase.push(part);\n }\n }\n\n return parentBase.join('/');\n }\n\n function has(id) {\n return !!(registry[id] || registry[id + '/index']);\n }\n\n requirejs.entries = requirejs._eak_seen = registry;\n requirejs.has = has;\n requirejs.unsee = function (id) {\n findModule(id, '(unsee)', false).unsee();\n };\n\n requirejs.clear = function () {\n requirejs.entries = requirejs._eak_seen = registry = dict();\n seen = dict();\n };\n\n // This code primes the JS engine for good performance by warming the\n // JIT compiler for these functions.\n define('foo', function () {});\n define('foo/bar', [], function () {});\n define('foo/asdf', ['module', 'exports', 'require'], function (module, exports, require) {\n if (require.has('foo/bar')) {\n require('foo/bar');\n }\n });\n define('foo/baz', [], define.alias('foo'));\n define('foo/quz', define.alias('foo'));\n define.alias('foo', 'foo/qux');\n define('foo/bar', ['foo', './quz', './baz', './asdf', './bar', '../foo'], function () {});\n define('foo/main', ['foo/bar'], function () {});\n define.exports('foo/exports', {});\n\n require('foo/exports');\n require('foo/main');\n require.unsee('foo/bar');\n\n requirejs.clear();\n\n if (typeof exports === 'object' && typeof module === 'object' && module.exports) {\n module.exports = { require: require, define: define };\n }\n})(this);","define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: function render(_ref) {\n var payload = _ref.payload;\n var dom = _ref.env.dom;\n\n var img = dom.createElement('img');\n img.src = payload.src;\n return img;\n }\n };\n});","define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];\n\n function registerGlobal(window) {\n window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];\n }\n\n exports['default'] = _mobiledocDomRendererRendererFactory['default'];\n});","define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderers/0-2', 'mobiledoc-dom-renderer/renderers/0-3', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderers02, _mobiledocDomRendererRenderers03, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime DOM renderer\n * renders a mobiledoc to DOM\n *\n * input: mobiledoc\n * output: DOM\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be of type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var _ref$cards = _ref.cards;\n var cards = _ref$cards === undefined ? [] : _ref$cards;\n var _ref$atoms = _ref.atoms;\n var atoms = _ref$atoms === undefined ? [] : _ref$atoms;\n var _ref$cardOptions = _ref.cardOptions;\n var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n var _ref$markupElementRenderer = _ref.markupElementRenderer;\n var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer;\n var _ref$sectionElementRenderer = _ref.sectionElementRenderer;\n var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer;\n var dom = _ref.dom;\n var _ref$markupSanitizer = _ref.markupSanitizer;\n var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer;\n\n _classCallCheck(this, RendererFactory);\n\n validateCards(cards);\n validateAtoms(atoms);\n\n if (!dom) {\n if (typeof window === 'undefined') {\n throw new Error('A `dom` option must be provided to the renderer when running without window.document');\n }\n dom = window.document;\n }\n\n this.options = {\n cards: cards,\n atoms: atoms,\n cardOptions: cardOptions,\n unknownCardHandler: unknownCardHandler,\n unknownAtomHandler: unknownAtomHandler,\n markupElementRenderer: markupElementRenderer,\n sectionElementRenderer: sectionElementRenderer,\n dom: dom,\n markupSanitizer: markupSanitizer\n };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocDomRendererRenderers02.MOBILEDOC_VERSION:\n case undefined:\n case null:\n return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render();\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-dom-renderer/renderers/0-2', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, options) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = options.cards;\n var cardOptions = options.cardOptions;\n var unknownCardHandler = options.unknownCardHandler;\n var markupElementRenderer = options.markupElementRenderer;\n var sectionElementRenderer = options.sectionElementRenderer;\n var dom = options.dom;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var markerTypes = _sectionData[0];\n var sections = _sectionData[1];\n\n this.dom = dom;\n this.root = dom.createDocumentFragment();\n this.markerTypes = markerTypes;\n this.sections = sections;\n this.cards = cards;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n this._renderedChildNodes = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = [];\n var node = this.root.firstChild;\n while (node) {\n this._renderedChildNodes.push(node);\n node = node.nextSibling;\n }\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 3);\n\n var openTypes = _marker[0];\n var closeCount = _marker[1];\n var text = _marker[2];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, text));\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var name = _ref42[1];\n var payload = _ref42[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils', 'mobiledoc-dom-renderer/utils/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils, _mobiledocDomRendererUtilsMarkerTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION_0_3_0 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n switch (version) {\n case MOBILEDOC_VERSION_0_3_0:\n case MOBILEDOC_VERSION_0_3_1:\n case MOBILEDOC_VERSION_0_3_2:\n return;\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var markupElementRenderer = state.markupElementRenderer;\n var sectionElementRenderer = state.sectionElementRenderer;\n var dom = state.dom;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n var markerTypes = mobiledoc.markups;\n\n validateVersion(version);\n\n this.dom = dom;\n this.root = this.dom.createDocumentFragment();\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.markerTypes = markerTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 4);\n\n var type = _marker[0];\n var openTypes = _marker[1];\n var closeCount = _marker[2];\n var value = _marker[3];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n switch (type) {\n case _mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, value));\n break;\n case _mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n currentElement.appendChild(this._renderAtom(value));\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var index = _ref42[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this5 = this;\n\n var env = {\n name: atom.name,\n isInEditor: false,\n dom: this.dom,\n onTeardown: function onTeardown(callback) {\n return _this5._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || (0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, '');\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 4);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n var _ref52$3 = _ref52[3];\n var attributes = _ref52$3 === undefined ? [] : _ref52$3;\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var attrsObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attributes);\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom, attrsObj);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref7) {\n var name = _ref7.env.name;\n\n throw new Error('Atom \"' + name + '\" not found but no unknownAtomHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-dom-renderer/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.includes = includes;\n exports.kvArrayToObject = kvArrayToObject;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n\n function includes(array, detectValue) {\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n if (value === detectValue) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n\n function kvArrayToObject(array) {\n if (!Array.isArray(array)) {\n return {};\n }\n\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n /**\n * @param {Object} {key1:value1, key2:value2, ...}\n * @return {Array} array of key1,value1,key2,value2,...\n * @private\n */\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n});","define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) {\n 'use strict';\n\n exports.createTextNode = createTextNode;\n exports.normalizeTagName = normalizeTagName;\n function addHTMLSpaces(text) {\n var nbsp = ' ';\n return text.replace(/ /g, ' ' + nbsp);\n }\n\n function createTextNode(dom, text) {\n return dom.createTextNode(addHTMLSpaces(text));\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n});","define(\"mobiledoc-dom-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'dom';\n});","define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) {\n 'use strict';\n\n exports.defaultSectionElementRenderer = defaultSectionElementRenderer;\n exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer;\n var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n function _isValidAttribute(attr) {\n return VALID_ATTRIBUTES.indexOf(attr) !== -1;\n }\n\n function handleMarkupSectionAttribute(element, attributeKey, attributeValue) {\n if (!_isValidAttribute(attributeKey)) {\n throw new Error('Cannot use attribute: ' + attributeKey);\n }\n\n element.setAttribute(attributeKey, attributeValue);\n }\n\n function defaultSectionElementRenderer(tagName, dom) {\n var attrsObj = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var element = undefined;\n if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) {\n element = dom.createElement(tagName);\n\n Object.keys(attrsObj).forEach(function (k) {\n handleMarkupSectionAttribute(element, k, attrsObj[k]);\n });\n } else {\n element = dom.createElement('div');\n element.setAttribute('class', tagName);\n }\n\n return element;\n }\n\n function sanitizeAttribute(tagName, attrName, attrValue) {\n if (tagName === 'a' && attrName === 'href') {\n return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attrValue);\n } else {\n return attrValue;\n }\n }\n\n function defaultMarkupElementRenderer(tagName, dom, attrsObj) {\n var element = dom.createElement(tagName);\n Object.keys(attrsObj).forEach(function (attrName) {\n var attrValue = attrsObj[attrName];\n attrValue = sanitizeAttribute(tagName, attrName, attrValue);\n element.setAttribute(attrName, attrValue);\n });\n return element;\n }\n});","define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {\n 'use strict';\n\n exports.sanitizeHref = sanitizeHref;\n exports.reduceAttributes = reduceAttributes;\n\n var PROTOCOL_REGEXP = /^([a-z0-9.+-]+:)/i;\n\n var badProtocols = ['javascript:', // jshint ignore:line\n 'vbscript:' // jshint ignore:line\n ];\n\n function getProtocol(url) {\n var matches = url && url.match(PROTOCOL_REGEXP);\n var protocol = matches && matches[0] || ':';\n return protocol;\n }\n\n function sanitizeHref(url) {\n var protocol = getProtocol(url).toLowerCase();\n if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) {\n return 'unsafe:' + url;\n }\n return url;\n }\n\n /**\n * @param attributes array\n * @return obj with normalized attribute names (lowercased)\n */\n\n function reduceAttributes(attributes) {\n var obj = {};\n for (var i = 0; i < attributes.length; i += 2) {\n var key = attributes[i];\n var val = attributes[i + 1];\n obj[key.toLowerCase()] = val;\n }\n return obj;\n }\n});","define(\"mobiledoc-dom-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});","define('mobiledoc-dom-renderer/utils/tag-names', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsDom) {\n 'use strict';\n\n exports.isValidSectionTagName = isValidSectionTagName;\n exports.isMarkupSectionElementName = isMarkupSectionElementName;\n exports.isValidMarkerType = isValidMarkerType;\n\n var MARKUP_SECTION_TAG_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pull-quote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_SECTION_ELEMENT_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var LIST_SECTION_TAG_NAMES = ['ul', 'ol'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_TYPES = ['b', 'i', 'strong', 'em', 'a', 'u', 'sub', 'sup', 's', 'code'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function isValidSectionTagName(tagName, sectionType) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n\n switch (sectionType) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return contains(MARKUP_SECTION_TAG_NAMES, tagName);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return contains(LIST_SECTION_TAG_NAMES, tagName);\n default:\n throw new Error('Cannot validate tagName for unknown section type \"' + sectionType + '\"');\n }\n }\n\n function isMarkupSectionElementName(tagName) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n return contains(MARKUP_SECTION_ELEMENT_NAMES, tagName);\n }\n\n function isValidMarkerType(type) {\n type = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(type);\n return contains(MARKUP_TYPES, type);\n }\n});","define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder-image-src'], function (exports, _mobiledocKitUtilsPlaceholderImageSrc) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: 'dom',\n\n render: function render(_ref) {\n var payload = _ref.payload;\n\n var img = document.createElement('img');\n img.src = payload.src || _mobiledocKitUtilsPlaceholderImageSrc['default'];\n return img;\n }\n };\n});","define('mobiledoc-kit/editor/edit-history', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/utils/fixed-queue'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitUtilsFixedQueue) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function findLeafSectionAtIndex(post, index) {\n var section = undefined;\n post.walkAllLeafSections(function (_section, _index) {\n if (index === _index) {\n section = _section;\n }\n });\n return section;\n }\n\n var Snapshot = (function () {\n function Snapshot(takenAt, editor) {\n var editAction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n _classCallCheck(this, Snapshot);\n\n this.mobiledoc = editor.serialize();\n this.editor = editor;\n this.editAction = editAction;\n this.takenAt = takenAt;\n\n this.snapshotRange();\n }\n\n _createClass(Snapshot, [{\n key: 'snapshotRange',\n value: function snapshotRange() {\n var _editor = this.editor;\n var range = _editor.range;\n var cursor = _editor.cursor;\n\n if (cursor.hasCursor() && !range.isBlank) {\n var head = range.head;\n var tail = range.tail;\n\n this.range = {\n head: [head.leafSectionIndex, head.offset],\n tail: [tail.leafSectionIndex, tail.offset]\n };\n }\n }\n }, {\n key: 'getRange',\n value: function getRange(post) {\n if (this.range) {\n var _range = this.range;\n var head = _range.head;\n var tail = _range.tail;\n var _head = head;\n\n var _head2 = _slicedToArray(_head, 2);\n\n var headLeafSectionIndex = _head2[0];\n var headOffset = _head2[1];\n var _tail = tail;\n\n var _tail2 = _slicedToArray(_tail, 2);\n\n var tailLeafSectionIndex = _tail2[0];\n var tailOffset = _tail2[1];\n\n var headSection = findLeafSectionAtIndex(post, headLeafSectionIndex);\n var tailSection = findLeafSectionAtIndex(post, tailLeafSectionIndex);\n\n head = headSection.toPosition(headOffset);\n tail = tailSection.toPosition(tailOffset);\n\n return head.toRange(tail);\n }\n }\n }, {\n key: 'groupsWith',\n value: function groupsWith(groupingTimeout, editAction, takenAt) {\n return editAction !== null && this.editAction === editAction && this.takenAt + groupingTimeout > takenAt;\n }\n }]);\n\n return Snapshot;\n })();\n\n exports.Snapshot = Snapshot;\n\n var EditHistory = (function () {\n function EditHistory(editor, queueLength, groupingTimeout) {\n _classCallCheck(this, EditHistory);\n\n this.editor = editor;\n this._undoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n this._redoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n\n this._pendingSnapshot = null;\n this._groupingTimeout = groupingTimeout;\n }\n\n _createClass(EditHistory, [{\n key: 'snapshot',\n value: function snapshot() {\n // update the current snapshot with the range read from DOM\n if (this._pendingSnapshot) {\n this._pendingSnapshot.snapshotRange();\n }\n }\n }, {\n key: 'storeSnapshot',\n value: function storeSnapshot() {\n var editAction = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];\n\n var now = Date.now();\n // store pending snapshot\n var pendingSnapshot = this._pendingSnapshot;\n if (pendingSnapshot) {\n if (!pendingSnapshot.groupsWith(this._groupingTimeout, editAction, now)) {\n this._undoStack.push(pendingSnapshot);\n }\n this._redoStack.clear();\n }\n\n // take new pending snapshot to store next time `storeSnapshot` is called\n this._pendingSnapshot = new Snapshot(now, this.editor, editAction);\n }\n }, {\n key: 'stepBackward',\n value: function stepBackward(postEditor) {\n // Throw away the pending snapshot\n this._pendingSnapshot = null;\n\n var snapshot = this._undoStack.pop();\n if (snapshot) {\n this._redoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n }\n }, {\n key: 'stepForward',\n value: function stepForward(postEditor) {\n var snapshot = this._redoStack.pop();\n if (snapshot) {\n this._undoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n postEditor.cancelSnapshot();\n }\n }, {\n key: '_restoreFromSnapshot',\n value: function _restoreFromSnapshot(snapshot, postEditor) {\n var mobiledoc = snapshot.mobiledoc;\n var editor = this.editor;\n var builder = editor.builder;\n var post = editor.post;\n\n var restoredPost = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(restoredPost);\n\n // resurrect snapshotted range if it exists\n var newRange = snapshot.getRange(post);\n if (newRange) {\n postEditor.setRange(newRange);\n }\n }\n }]);\n\n return EditHistory;\n })();\n\n exports['default'] = EditHistory;\n});","define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * Used by {@link Editor} to manage its current state (cursor, active markups\n * and active sections).\n * @private\n */\n\n var EditState = (function () {\n function EditState(editor) {\n _classCallCheck(this, EditState);\n\n this.editor = editor;\n\n var defaultState = {\n range: _mobiledocKitUtilsCursorRange['default'].blankRange(),\n activeMarkups: [],\n activeSections: [],\n activeSectionTagNames: [],\n activeSectionAttributes: {}\n };\n\n this.prevState = this.state = defaultState;\n }\n\n _createClass(EditState, [{\n key: 'updateRange',\n value: function updateRange(newRange) {\n this.prevState = this.state;\n this.state = this._readState(newRange);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.editor = null;\n this.prevState = this.state = null;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'rangeDidChange',\n value: function rangeDidChange() {\n var range = this.state.range;\n var prevRange = this.prevState.range;\n\n return !prevRange.isEqual(range);\n }\n\n /**\n * @return {Boolean} Whether the input mode (active markups or active section tag names)\n * has changed.\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange() {\n var state = this.state;\n var prevState = this.prevState;\n\n return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)((0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes));\n }\n\n /**\n * @return {Range}\n */\n }, {\n key: 'toggleMarkupState',\n\n /**\n * Update the editor's markup state. This is used when, e.g.,\n * a user types meta+B when the editor has a cursor but no selected text;\n * in this case the editor needs to track that it has an active \"b\" markup\n * and apply it to the next text the user types.\n */\n value: function toggleMarkupState(markup) {\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(this.activeMarkups, markup)) {\n this._removeActiveMarkup(markup);\n } else {\n this._addActiveMarkup(markup);\n }\n }\n }, {\n key: '_readState',\n value: function _readState(range) {\n var state = {\n range: range,\n activeMarkups: this._readActiveMarkups(range),\n activeSections: this._readActiveSections(range)\n };\n // Section objects are 'live', so to check that they changed, we\n // need to map their tagNames now (and compare to mapped tagNames later).\n // In addition, to catch changes from ul -> ol, we keep track of the\n // un-nested tag names (otherwise we'd only see li -> li change)\n state.activeSectionTagNames = state.activeSections.map(function (s) {\n return s.isNested ? s.parent.tagName : s.tagName;\n });\n state.activeSectionAttributes = this._readSectionAttributes(state.activeSections);\n return state;\n }\n }, {\n key: '_readActiveSections',\n value: function _readActiveSections(range) {\n var head = range.head;\n var tail = range.tail;\n var post = this.editor.post;\n\n if (range.isBlank) {\n return [];\n } else {\n return post.sections.readRange(head.section, tail.section);\n }\n }\n }, {\n key: '_readActiveMarkups',\n value: function _readActiveMarkups(range) {\n var post = this.editor.post;\n\n return post.markupsInRange(range);\n }\n }, {\n key: '_readSectionAttributes',\n value: function _readSectionAttributes(sections) {\n return sections.reduce(function (sectionAttributes, s) {\n var attributes = s.isNested ? s.parent.attributes : s.attributes;\n Object.keys(attributes || {}).forEach(function (attrName) {\n var camelizedAttrName = attrName.replace(/^data-md-/, '');\n var attrValue = attributes[attrName];\n sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || [];\n if (!(0, _mobiledocKitUtilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) {\n sectionAttributes[camelizedAttrName].push(attrValue);\n }\n });\n return sectionAttributes;\n }, {});\n }\n }, {\n key: '_removeActiveMarkup',\n value: function _removeActiveMarkup(markup) {\n var index = this.state.activeMarkups.indexOf(markup);\n this.state.activeMarkups.splice(index, 1);\n }\n }, {\n key: '_addActiveMarkup',\n value: function _addActiveMarkup(markup) {\n this.state.activeMarkups.push(markup);\n }\n }, {\n key: 'range',\n get: function get() {\n return this.state.range;\n }\n\n /**\n * @return {Section[]}\n */\n }, {\n key: 'activeSections',\n get: function get() {\n return this.state.activeSections;\n }\n\n /**\n * @return {Object}\n */\n }, {\n key: 'activeSectionAttributes',\n get: function get() {\n return this.state.activeSectionAttributes;\n }\n\n /**\n * @return {Markup[]}\n */\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this.state.activeMarkups;\n }\n }]);\n\n return EditState;\n })();\n\n exports['default'] = EditState;\n});","define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/element-utils', 'mobiledoc-kit/utils/cursor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/environment', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/text-input-handlers', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/editor/mutation-handler', 'mobiledoc-kit/editor/edit-history', 'mobiledoc-kit/editor/event-manager', 'mobiledoc-kit/editor/edit-state', 'mobiledoc-dom-renderer', 'mobiledoc-text-renderer', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/log-manager', 'mobiledoc-kit/utils/to-range', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitViewsTooltip, _mobiledocKitEditorPost, _mobiledocKitCardsImage, _mobiledocKitUtilsKey, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersDom, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree, _mobiledocKitRenderersMobiledoc, _mobiledocKitUtilsMerge, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsElementUtils, _mobiledocKitUtilsCursor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsEnvironment, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorTextInputHandlers, _mobiledocKitEditorKeyCommands, _mobiledocKitModelsCard, _mobiledocKitUtilsAssert, _mobiledocKitEditorMutationHandler, _mobiledocKitEditorEditHistory, _mobiledocKitEditorEventManager, _mobiledocKitEditorEditState, _mobiledocDomRenderer, _mobiledocTextRenderer, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsLogManager, _mobiledocKitUtilsToRange, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // This export may later be deprecated, but re-export it from the renderer here\n // for consumers that may depend on it.\n Object.defineProperty(exports, 'EDITOR_ELEMENT_CLASS_NAME', {\n enumerable: true,\n get: function get() {\n return _mobiledocKitRenderersEditorDom.EDITOR_ELEMENT_CLASS_NAME;\n }\n });\n\n var defaults = {\n placeholder: 'Write here...',\n spellcheck: true,\n autofocus: true,\n showLinkTooltips: true,\n undoDepth: 5,\n undoBlockTimeout: 5000, // ms for an undo event\n cards: [],\n atoms: [],\n cardOptions: {},\n unknownCardHandler: function unknownCardHandler(_ref) {\n var env = _ref.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown card encountered: ' + env.name);\n },\n unknownAtomHandler: function unknownAtomHandler(_ref2) {\n var env = _ref2.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown atom encountered: ' + env.name);\n },\n mobiledoc: null,\n html: null\n };\n\n var CALLBACK_QUEUES = {\n DID_UPDATE: 'didUpdate',\n WILL_RENDER: 'willRender',\n DID_RENDER: 'didRender',\n WILL_DELETE: 'willDelete',\n DID_DELETE: 'didDelete',\n WILL_HANDLE_NEWLINE: 'willHandleNewline',\n CURSOR_DID_CHANGE: 'cursorDidChange',\n DID_REPARSE: 'didReparse',\n POST_DID_CHANGE: 'postDidChange',\n INPUT_MODE_DID_CHANGE: 'inputModeDidChange'\n };\n\n /**\n * The Editor is a core component of mobiledoc-kit. After instantiating\n * an editor, use {@link Editor#render} to display the editor on the web page.\n *\n * An editor uses a {@link Post} internally to represent the displayed document.\n * The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc\n * is the transportable \"over-the-wire\" format (JSON) that is suited for persisting\n * and sharing between editors and renderers (for display, e.g.), whereas the Post\n * model is better suited for programmatic editing.\n *\n * The editor will call registered callbacks for certain state changes. These are:\n * * {@link Editor#cursorDidChange} -- The cursor position or selection changed.\n * * {@link Editor#postDidChange} -- The contents of the post changed due to user input or\n * programmatic editing. This hook can be used with {@link Editor#serialize}\n * to auto-save a post as it is being edited.\n * * {@link Editor#inputModeDidChange} -- The active section(s) or markup(s) at the current cursor\n * position or selection have changed. This hook can be used with\n * {@link Editor#activeMarkups} and {@link Editor#activeSections} to implement\n * a custom toolbar.\n * * {@link Editor#onTextInput} -- Register callbacks when the user enters text\n * that matches a given string or regex.\n * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before\n * applying changes from {@link Editor#toggleMarkup}\n */\n\n var Editor = (function () {\n /**\n * @param {Object} [options]\n * @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.\n * Supersedes `options.html`.\n * @param {String|DOM} [options.html] The html (as a string or DOM fragment)\n * to parse and load into the editor.\n * Will be ignored if `options.mobiledoc` is also passed.\n * @param {Array} [options.parserPlugins=[]]\n * @param {Array} [options.cards=[]] The cards that the editor may render.\n * @param {Array} [options.atoms=[]] The atoms that the editor may render.\n * @param {Function} [options.unknownCardHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown card.\n * @param {Function} [options.unknownAtomHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown atom.\n * @param {String} [options.placeholder] Default text to show before user starts typing.\n * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck\n * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered.\n * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links\n * @param {number} [options.undoDepth=5] How many undo levels will be available.\n * Set to 0 to disable undo/redo functionality.\n * @return {Editor}\n * @public\n */\n\n function Editor() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, Editor);\n\n (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType);\n this._views = [];\n this.isEditable = true;\n this._parserPlugins = options.parserPlugins || [];\n\n // FIXME: This should merge onto this.options\n (0, _mobiledocKitUtilsMerge.mergeWithOptions)(this, defaults, options);\n this.cards.push(_mobiledocKitCardsImage['default']);\n\n _mobiledocKitEditorKeyCommands.DEFAULT_KEY_COMMANDS.forEach(function (kc) {\n return _this.registerKeyCommand(kc);\n });\n\n this._logManager = new _mobiledocKitUtilsLogManager['default']();\n this._parser = new _mobiledocKitParsersDom['default'](this.builder);\n var cards = this.cards;\n var atoms = this.atoms;\n var unknownCardHandler = this.unknownCardHandler;\n var unknownAtomHandler = this.unknownAtomHandler;\n var cardOptions = this.cardOptions;\n\n this._renderer = new _mobiledocKitRenderersEditorDom['default'](this, cards, atoms, unknownCardHandler, unknownAtomHandler, cardOptions);\n\n this.post = this.loadPost();\n this._renderTree = new _mobiledocKitModelsRenderTree['default'](this.post);\n\n this._editHistory = new _mobiledocKitEditorEditHistory['default'](this, this.undoDepth, this.undoBlockTimeout);\n this._eventManager = new _mobiledocKitEditorEventManager['default'](this);\n this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this);\n this._editState = new _mobiledocKitEditorEditState['default'](this);\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n this._beforeHooks = { toggleMarkup: [] };\n\n _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) {\n return _this.onTextInput(handler);\n });\n\n this.hasRendered = false;\n }\n\n /**\n * Turns on verbose logging for the editor.\n * @param {Array} [logTypes=[]] If present, only the given log types will be logged.\n * @public\n */\n\n _createClass(Editor, [{\n key: 'enableLogging',\n value: function enableLogging() {\n var logTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n if (logTypes.length === 0) {\n this._logManager.enableAll();\n } else {\n this._logManager.enableTypes(logTypes);\n }\n }\n\n /**\n * Disable all logging\n * @public\n */\n }, {\n key: 'disableLogging',\n value: function disableLogging() {\n this._logManager.disable();\n }\n\n /**\n * @private\n */\n }, {\n key: 'loggerFor',\n value: function loggerFor(type) {\n return this._logManager['for'](type);\n }\n\n /**\n * The editor's instance of a post node builder.\n * @type {PostNodeBuilder}\n */\n }, {\n key: 'loadPost',\n value: function loadPost() {\n var mobiledoc = this.mobiledoc;\n var html = this.html;\n\n if (mobiledoc) {\n return _mobiledocKitParsersMobiledoc['default'].parse(this.builder, mobiledoc);\n } else if (html) {\n if (typeof html === 'string') {\n var options = { plugins: this._parserPlugins };\n return new _mobiledocKitParsersHtml['default'](this.builder, options).parse(this.html);\n } else {\n var dom = html;\n return this._parser.parse(dom);\n }\n } else {\n return this.builder.createPost();\n }\n }\n }, {\n key: 'rerender',\n value: function rerender() {\n var _this2 = this;\n\n var postRenderNode = this.post.renderNode;\n\n // if we haven't rendered this post's renderNode before, mark it dirty\n if (!postRenderNode.element) {\n (0, _mobiledocKitUtilsAssert['default'])('Must call `render` before `rerender` can be called', this.hasRendered);\n postRenderNode.element = this.element;\n postRenderNode.markDirty();\n }\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_RENDER);\n this._mutationHandler.suspendObservation(function () {\n _this2._renderer.render(_this2._renderTree);\n });\n this.runCallbacks(CALLBACK_QUEUES.DID_RENDER);\n }\n\n /**\n * @param {Element} element The DOM element to render into.\n * Its contents will be replaced by the editor's rendered post.\n * @public\n */\n }, {\n key: 'render',\n value: function render(element) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot render an editor twice. Use `rerender` to update the ' + 'rendering of an existing editor instance.', !this.hasRendered);\n\n element.spellcheck = this.spellcheck;\n\n (0, _mobiledocKitUtilsDomUtils.clearChildNodes)(element);\n\n this.element = element;\n\n if (this.showLinkTooltips) {\n this._addTooltip();\n }\n\n // A call to `run` will trigger the didUpdatePostCallbacks hooks with a\n // postEditor.\n this.run(function () {});\n\n // Only set `hasRendered` to true after calling `run` to ensure that\n // no cursorDidChange or other callbacks get fired before the editor is\n // done rendering\n this.hasRendered = true;\n this.rerender();\n\n this._mutationHandler.init();\n this._eventManager.init();\n\n if (this.isEditable === false) {\n this.disableEditing();\n } else {\n this.enableEditing();\n }\n\n if (this.autofocus) {\n this.selectRange(this.post.headPosition());\n }\n }\n }, {\n key: '_addTooltip',\n value: function _addTooltip() {\n this.addView(new _mobiledocKitViewsTooltip['default']({\n rootElement: this.element,\n showForTag: 'a'\n }));\n }\n }, {\n key: 'registerKeyCommand',\n\n /**\n * @param {Object} keyCommand The key command to register. It must specify a\n * modifier key (meta, ctrl, etc), a string representing the ascii key, and\n * a `run` method that will be passed the editor instance when the key command\n * is invoked\n * @public\n */\n value: function registerKeyCommand(rawKeyCommand) {\n var keyCommand = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)(rawKeyCommand);\n (0, _mobiledocKitUtilsAssert['default'])('Key Command is not valid', (0, _mobiledocKitEditorKeyCommands.validateKeyCommand)(keyCommand));\n this.keyCommands.unshift(keyCommand);\n }\n\n /**\n * @param {String} name If the keyCommand event has a name attribute it can be removed.\n * @public\n */\n }, {\n key: 'unregisterKeyCommands',\n value: function unregisterKeyCommands(name) {\n for (var i = this.keyCommands.length - 1; i > -1; i--) {\n var keyCommand = this.keyCommands[i];\n\n if (keyCommand.name === name) {\n this.keyCommands.splice(i, 1);\n }\n }\n }\n\n /**\n * Convenience for {@link PostEditor#deleteAtPosition}. Deletes and puts the\n * cursor in the new position.\n * @public\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position, direction, _ref3) {\n var unit = _ref3.unit;\n\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteAtPosition(position, direction, { unit: unit });\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * Convenience for {@link PostEditor#deleteRange}. Deletes and puts the\n * cursor in the new position.\n * @param {Range} range\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * @private\n */\n }, {\n key: 'performDelete',\n value: function performDelete() {\n var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? { direction: _mobiledocKitUtilsKey.DIRECTION.BACKWARD, unit: 'char' } : arguments[0];\n\n var direction = _ref4.direction;\n var unit = _ref4.unit;\n var range = this.range;\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_DELETE, [range, direction, unit]);\n if (range.isCollapsed) {\n this.deleteAtPosition(range.head, direction, { unit: unit });\n } else {\n this.deleteRange(range);\n }\n this.runCallbacks(CALLBACK_QUEUES.DID_DELETE, [range, direction, unit]);\n }\n }, {\n key: 'handleNewline',\n value: function handleNewline(event) {\n var _this3 = this;\n\n if (!this.hasCursor()) {\n return;\n }\n\n event.preventDefault();\n\n var range = this.range;\n\n this.run(function (postEditor) {\n var cursorSection = undefined;\n if (!range.isCollapsed) {\n var nextPosition = postEditor.deleteRange(range);\n cursorSection = nextPosition.section;\n if (cursorSection && cursorSection.isBlank) {\n postEditor.setRange(cursorSection.headPosition());\n return;\n }\n }\n\n // Above logic might delete redundant range, so callback must run after it.\n var defaultPrevented = false;\n var event = { preventDefault: function preventDefault() {\n defaultPrevented = true;\n } };\n _this3.runCallbacks(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, [event]);\n if (defaultPrevented) {\n return;\n }\n\n cursorSection = postEditor.splitSection(range.head)[1];\n postEditor.setRange(cursorSection.headPosition());\n });\n }\n\n /**\n * Notify the editor that the post did change, and run associated\n * callbacks.\n * @private\n */\n }, {\n key: '_postDidChange',\n value: function _postDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.POST_DID_CHANGE);\n }\n\n /**\n * Selects the given range or position. If given a collapsed range or a position, this positions the cursor\n * at the range's position. Otherwise a selection is created in the editor\n * surface encompassing the range.\n * @param {Range|Position} range\n */\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n this.cursor.selectRange(range);\n this.range = range;\n }\n }, {\n key: '_readRangeFromDOM',\n value: function _readRangeFromDOM() {\n this.range = this.cursor.offsets;\n }\n }, {\n key: 'setPlaceholder',\n value: function setPlaceholder(placeholder) {\n (0, _mobiledocKitUtilsElementUtils.setData)(this.element, 'placeholder', placeholder);\n }\n }, {\n key: '_reparsePost',\n value: function _reparsePost() {\n var post = this._parser.parse(this.element);\n this.run(function (postEditor) {\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(post);\n postEditor.setRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n });\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n }, {\n key: '_reparseSections',\n value: function _reparseSections() {\n var _this4 = this;\n\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var currentRange = undefined;\n sections.forEach(function (section) {\n _this4._parser.reparseSection(section, _this4._renderTree);\n });\n this._removeDetachedSections();\n\n if (this._renderTree.isDirty) {\n currentRange = this.range;\n }\n\n // force the current snapshot's range to remain the same rather than\n // rereading it from DOM after the new character is applied and the browser\n // updates the cursor position\n var range = this._editHistory._pendingSnapshot.range;\n this.run(function () {\n _this4._editHistory._pendingSnapshot.range = range;\n });\n this.rerender();\n if (currentRange) {\n this.selectRange(currentRange);\n }\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n\n // FIXME this should be able to be removed now -- if any sections are detached,\n // it's due to a bug in the code.\n }, {\n key: '_removeDetachedSections',\n value: function _removeDetachedSections() {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.post.sections, function (s) {\n return !s.renderNode.isAttached();\n }), function (s) {\n return s.renderNode.scheduleForRemoval();\n });\n }\n\n /**\n * The sections from the cursor's selection start to the selection end\n * @type {Section[]}\n */\n }, {\n key: 'detectMarkupInRange',\n value: function detectMarkupInRange(range, markupTagName) {\n var markups = this.post.markupsInRange(range);\n return (0, _mobiledocKitUtilsArrayUtils.detect)(markups, function (markup) {\n return markup.hasTag(markupTagName);\n });\n }\n\n /**\n * @type {Markup[]}\n * @public\n */\n }, {\n key: 'hasActiveMarkup',\n\n /**\n * @param {Markup|String} markup A markup instance, or a string (e.g. \"b\")\n * @return {boolean}\n */\n value: function hasActiveMarkup(markup) {\n var matchesFn = undefined;\n if (typeof markup === 'string') {\n (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(markup);\n matchesFn = function (m) {\n return m.tagName === tagName;\n };\n })();\n } else {\n matchesFn = function (m) {\n return m === markup;\n };\n }\n\n return !!(0, _mobiledocKitUtilsArrayUtils.detect)(this.activeMarkups, matchesFn);\n }\n\n /**\n * @param {String} version The mobiledoc version to serialize to.\n * @return {Mobiledoc} Serialized mobiledoc\n * @public\n */\n }, {\n key: 'serialize',\n value: function serialize() {\n var version = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION : arguments[0];\n\n return this.serializePost(this.post, 'mobiledoc', { version: version });\n }\n\n /**\n * Serialize the editor's post to the requested format.\n * Note that only mobiledoc format is lossless. If cards or atoms are present\n * in the post, the html and text formats will omit them in output because\n * the editor does not have access to the html and text versions of the\n * cards/atoms.\n * @param {string} format The format to serialize ('mobiledoc', 'text', 'html')\n * @return {Object|String} The editor's post, serialized to {format}\n * @public\n */\n }, {\n key: 'serializeTo',\n value: function serializeTo(format) {\n var post = this.post;\n return this.serializePost(post, format);\n }\n\n /**\n * @param {Post}\n * @param {String} format Same as {serializeTo}\n * @param {Object} [options]\n * @param {String} [options.version=MOBILEDOC_VERSION] version to serialize to\n * @return {Object|String}\n * @private\n */\n }, {\n key: 'serializePost',\n value: function serializePost(post, format) {\n var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var validFormats = ['mobiledoc', 'html', 'text'];\n (0, _mobiledocKitUtilsAssert['default'])('Unrecognized serialization format ' + format, (0, _mobiledocKitUtilsArrayUtils.contains)(validFormats, format));\n\n if (format === 'mobiledoc') {\n var version = options.version || _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n return _mobiledocKitRenderersMobiledoc['default'].render(post, version);\n } else {\n var rendered = undefined;\n var mobiledoc = this.serializePost(post, 'mobiledoc');\n var unknownCardHandler = function unknownCardHandler() {};\n var unknownAtomHandler = function unknownAtomHandler() {};\n var rendererOptions = { unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n\n switch (format) {\n case 'html':\n {\n var result = undefined;\n if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) {\n rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc);\n result = '
    ' + (0, _mobiledocKitUtilsDomUtils.serializeHTML)(rendered.result) + '
    ';\n } else {\n // Fallback to text serialization\n result = this.serializePost(post, 'text', options);\n }\n return result;\n }\n case 'text':\n rendered = new _mobiledocTextRenderer['default'](rendererOptions).render(mobiledoc);\n return rendered.result;\n }\n }\n }\n }, {\n key: 'addView',\n value: function addView(view) {\n this._views.push(view);\n }\n }, {\n key: 'removeAllViews',\n value: function removeAllViews() {\n this._views.forEach(function (v) {\n return v.destroy();\n });\n this._views = [];\n }\n\n /**\n * Whether the editor has a cursor (or a selected range).\n * It is possible for the editor to be focused but not have a selection.\n * In this case, key events will fire but the editor will not be able to\n * determine a cursor position, so they will be ignored.\n * @return {boolean}\n * @public\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.cursor.hasCursor();\n }\n\n /**\n * Tears down the editor's attached event listeners and views.\n * @public\n */\n }, {\n key: 'destroy',\n value: function destroy() {\n this.isDestroyed = true;\n if (this._hasSelection()) {\n this.cursor.clearSelection();\n }\n if (this._hasFocus()) {\n this.element.blur(); // FIXME This doesn't blur the element on IE11\n }\n this._mutationHandler.destroy();\n this._eventManager.destroy();\n this.removeAllViews();\n this._renderer.destroy();\n this._editState.destroy();\n }\n\n /**\n * Keep the user from directly editing the post using the keyboard and mouse.\n * Modification via the programmatic API is still permitted.\n * @see Editor#enableEditing\n * @public\n */\n }, {\n key: 'disableEditing',\n value: function disableEditing() {\n this.isEditable = false;\n if (this.hasRendered) {\n this._eventManager.stop();\n this.element.setAttribute('contentEditable', false);\n this.setPlaceholder('');\n this.selectRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n }\n }\n\n /**\n * Allow the user to directly interact with editing a post via keyboard and mouse input.\n * Editor instances are editable by default. Use this method to re-enable\n * editing after disabling it.\n * @see Editor#disableEditing\n * @public\n */\n }, {\n key: 'enableEditing',\n value: function enableEditing() {\n this.isEditable = true;\n if (this.hasRendered) {\n this._eventManager.start();\n this.element.setAttribute('contentEditable', true);\n this.setPlaceholder(this.placeholder);\n }\n }\n\n /**\n * Change a cardSection into edit mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in edit mode when it gets rendered.\n * @param {CardSection} cardSection\n * @public\n */\n }, {\n key: 'editCard',\n value: function editCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.EDIT);\n }\n\n /**\n * Change a cardSection into display mode\n * If called before the card has been rendered, it will be marked so that\n * it is rendered in display mode when it gets rendered.\n * @param {CardSection} cardSection\n * @return undefined\n * @public\n */\n }, {\n key: 'displayCard',\n value: function displayCard(cardSection) {\n this._setCardMode(cardSection, _mobiledocKitModelsCard.CARD_MODES.DISPLAY);\n }\n\n /**\n * Run a new post editing session. Yields a block with a new {@link PostEditor}\n * instance. This instance can be used to interact with the post abstract.\n * Rendering will be deferred until after the callback is completed.\n *\n * Usage:\n * ```\n * let markerRange = this.range;\n * editor.run((postEditor) => {\n * postEditor.deleteRange(markerRange);\n * // editing surface not updated yet\n * postEditor.schedule(() => {\n * console.log('logs during rerender flush');\n * });\n * // logging not yet flushed\n * });\n * // editing surface now updated.\n * // logging now flushed\n * ```\n *\n * @param {Function} callback Called with an instance of\n * {@link PostEditor} as its argument.\n * @return {Mixed} The return value of `callback`.\n * @public\n */\n }, {\n key: 'run',\n value: function run(callback) {\n var postEditor = new _mobiledocKitEditorPost['default'](this);\n postEditor.begin();\n this._editHistory.snapshot();\n var result = callback(postEditor);\n this.runCallbacks(CALLBACK_QUEUES.DID_UPDATE, [postEditor]);\n postEditor.complete();\n this._readRangeFromDOM();\n\n if (postEditor._shouldCancelSnapshot) {\n this._editHistory._pendingSnapshot = null;\n }\n this._editHistory.storeSnapshot(postEditor.editActionTaken);\n\n return result;\n }\n\n /**\n * @param {Function} callback Called with `postEditor` as its argument.\n * @public\n */\n }, {\n key: 'didUpdatePost',\n value: function didUpdatePost(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_UPDATE, callback);\n }\n\n /**\n * @param {Function} callback Called when the post has changed, either via\n * user input or programmatically. Use with {@link Editor#serialize} to\n * retrieve the post in portable mobiledoc format.\n */\n }, {\n key: 'postDidChange',\n value: function postDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.POST_DID_CHANGE, callback);\n }\n\n /**\n * Register a handler that will be invoked by the editor after the user enters\n * matching text.\n * @param {Object} inputHandler\n * @param {String} inputHandler.name Required. Used by identifying handlers.\n * @param {String} [inputHandler.text] Required if `match` is not provided\n * @param {RegExp} [inputHandler.match] Required if `text` is not provided\n * @param {Function} inputHandler.run This callback is invoked with the {@link Editor}\n * instance and an array of matches. If `text` was provided,\n * the matches array will equal [`text`], and if a `match`\n * regex was provided the matches array will be the result of\n * `match.exec` on the matching text. The callback is called\n * after the matching text has been inserted.\n * @public\n */\n }, {\n key: 'onTextInput',\n value: function onTextInput(inputHandler) {\n this._eventManager.registerInputHandler(inputHandler);\n }\n\n /**\n * Unregister all text input handlers\n *\n * @public\n */\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._eventManager.unregisterAllTextInputHandlers();\n }\n\n /**\n * Unregister text input handler by name\n * @param {String} name The name of handler to be removed\n *\n * @public\n */\n }, {\n key: 'unregisterTextInputHandler',\n value: function unregisterTextInputHandler(name) {\n this._eventManager.unregisterInputHandler(name);\n }\n\n /**\n * @param {Function} callback Called when the editor's state (active markups or\n * active sections) has changed, either via user input or programmatically\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'willRender',\n value: function willRender(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after the editor\n * is rendered.\n * @public\n */\n }, {\n key: 'didRender',\n value: function didRender(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_RENDER, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before deleting.\n * @public\n */\n }, {\n key: 'willDelete',\n value: function willDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called after deleting.\n * @public\n */\n }, {\n key: 'didDelete',\n value: function didDelete(callback) {\n this.addCallback(CALLBACK_QUEUES.DID_DELETE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called before handling new line.\n * @public\n */\n }, {\n key: 'willHandleNewline',\n value: function willHandleNewline(callback) {\n this.addCallback(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, callback);\n }\n\n /**\n * @param {Function} callback This callback will be called every time the cursor\n * position (or selection) changes.\n * @public\n */\n }, {\n key: 'cursorDidChange',\n value: function cursorDidChange(callback) {\n this.addCallback(CALLBACK_QUEUES.CURSOR_DID_CHANGE, callback);\n }\n }, {\n key: '_rangeDidChange',\n value: function _rangeDidChange() {\n if (this.hasRendered) {\n this.runCallbacks(CALLBACK_QUEUES.CURSOR_DID_CHANGE);\n }\n }\n }, {\n key: '_inputModeDidChange',\n value: function _inputModeDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.INPUT_MODE_DID_CHANGE);\n }\n }, {\n key: '_insertEmptyMarkupSectionAtCursor',\n value: function _insertEmptyMarkupSectionAtCursor() {\n var _this5 = this;\n\n this.run(function (postEditor) {\n var section = postEditor.builder.createMarkupSection('p');\n postEditor.insertSectionBefore(_this5.post.sections, section);\n postEditor.setRange(section.toRange());\n });\n }\n\n /**\n * @callback editorBeforeCallback\n * @param { Object } details\n * @param { Markup } details.markup\n * @param { Range } details.range\n * @param { boolean } details.willAdd Whether the markup will be applied\n */\n\n /**\n * Register a callback that will be run before {@link Editor#toggleMarkup} is applied.\n * If any callback returns literal `false`, the toggling of markup will be canceled.\n * Note this only applies to calling `editor#toggleMarkup`. Using `editor.run` and\n * modifying markup with the `postEditor` will skip any `beforeToggleMarkup` callbacks.\n * @param {editorBeforeCallback}\n */\n }, {\n key: 'beforeToggleMarkup',\n value: function beforeToggleMarkup(callback) {\n this._beforeHooks.toggleMarkup.push(callback);\n }\n\n /**\n * Toggles the given markup at the editor's current {@link Range}.\n * If the range is collapsed this changes the editor's state so that the\n * next characters typed will be affected. If there is text selected\n * (aka a non-collapsed range), the selections' markup will be toggled.\n * If the editor is not focused and has no active range, nothing happens.\n * Hooks added using #beforeToggleMarkup will be run before toggling,\n * and if any of them returns literal false, toggling the markup will be canceled\n * and no change will be applied.\n * @param {String} markup E.g. \"b\", \"em\", \"a\"\n * @param {Object} [attributes={}] E.g. {href: \"http://bustle.com\"}\n * @public\n * @see PostEditor#toggleMarkup\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markup) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n markup = this.builder.createMarkup(markup, attributes);\n var range = this.range;\n\n var willAdd = !this.detectMarkupInRange(range, markup.tagName);\n var shouldCancel = this._runBeforeHooks('toggleMarkup', { markup: markup, range: range, willAdd: willAdd });\n if (shouldCancel) {\n return;\n }\n\n if (range.isCollapsed) {\n this._editState.toggleMarkupState(markup);\n this._inputModeDidChange();\n\n // when clicking a button to toggle markup, the button can end up being focused,\n // so ensure the editor is focused\n this._ensureFocus();\n } else {\n this.run(function (postEditor) {\n return postEditor.toggleMarkup(markup, range);\n });\n }\n }\n\n // If the editor has a selection but is not focused, focus it\n }, {\n key: '_ensureFocus',\n value: function _ensureFocus() {\n if (this._hasSelection() && !this._hasFocus()) {\n this.focus();\n }\n }\n }, {\n key: 'focus',\n value: function focus() {\n this.element.focus();\n }\n\n /**\n * Whether there is a selection inside the editor's element.\n * It's possible to have a selection but not have focus.\n * @see #_hasFocus\n * @return {Boolean}\n */\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var cursor = this.cursor;\n\n return this.hasRendered && (cursor._hasCollapsedSelection() || cursor._hasSelection());\n }\n\n /**\n * Whether the editor's element is focused\n * It's possible to be focused but have no selection\n * @see #_hasSelection\n * @return {Boolean}\n */\n }, {\n key: '_hasFocus',\n value: function _hasFocus() {\n return document.activeElement === this.element;\n }\n\n /**\n * Toggles the tagName for the current active section(s). This will skip\n * non-markerable sections. E.g. if the editor's range includes a \"P\" MarkupSection\n * and a CardSection, only the MarkupSection will be toggled.\n * @param {String} tagName The new tagname to change to.\n * @public\n * @see PostEditor#toggleSection\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(tagName) {\n var _this6 = this;\n\n this.run(function (postEditor) {\n return postEditor.toggleSection(tagName, _this6.range);\n });\n }\n\n /**\n * Sets an attribute for the current active section(s).\n *\n * @param {String} key The attribute. The only valid attribute is 'text-align'.\n * @param {String} value The value of the attribute.\n * @public\n * @see PostEditor#setAttribute\n */\n }, {\n key: 'setAttribute',\n value: function setAttribute(key, value) {\n var _this7 = this;\n\n this.run(function (postEditor) {\n return postEditor.setAttribute(key, value, _this7.range);\n });\n }\n\n /**\n * Removes an attribute from the current active section(s).\n *\n * @param {String} key The attribute. The only valid attribute is 'text-align'.\n * @public\n * @see PostEditor#removeAttribute\n */\n }, {\n key: 'removeAttribute',\n value: function removeAttribute(key) {\n var _this8 = this;\n\n this.run(function (postEditor) {\n return postEditor.removeAttribute(key, _this8.range);\n });\n }\n\n /**\n * Finds and runs the first matching key command for the event\n *\n * If multiple commands are bound to a key combination, the\n * first matching one is run.\n *\n * If a command returns `false` then the next matching command\n * is run instead.\n *\n * @param {Event} event The keyboard event triggered by the user\n * @return {Boolean} true when a command was successfully run\n * @private\n */\n }, {\n key: 'handleKeyCommand',\n value: function handleKeyCommand(event) {\n var keyCommands = (0, _mobiledocKitEditorKeyCommands.findKeyCommands)(this.keyCommands, event);\n for (var i = 0; i < keyCommands.length; i++) {\n var keyCommand = keyCommands[i];\n if (keyCommand.run(this) !== false) {\n event.preventDefault();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Inserts the text at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n *\n * @param {String} text\n * @public\n */\n }, {\n key: 'insertText',\n value: function insertText(text) {\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n var activeMarkups = this.activeMarkups;\n var range = this.range;\n var position = this.range.head;\n\n this.run(function (postEditor) {\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertTextWithMarkup(position, text, activeMarkups);\n });\n }\n\n /**\n * Inserts an atom at the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion.\n * @param {String} atomName\n * @param {String} [atomText='']\n * @param {Object} [atomPayload={}]\n * @return {Atom} The inserted atom.\n * @public\n */\n }, {\n key: 'insertAtom',\n value: function insertAtom(atomName) {\n var atomText = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var atomPayload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var atom = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.head;\n\n atom = postEditor.builder.createAtom(atomName, atomText, atomPayload);\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n postEditor.insertMarkers(position, [atom]);\n });\n return atom;\n }\n\n /**\n * Inserts a card at the section after the current cursor position. If the editor has\n * no current cursor position, nothing will be inserted. If the editor's\n * range is not collapsed, it will be deleted before insertion. If the cursor is in\n * a blank section, it will be replaced with a card section.\n * The editor's cursor will be placed at the end of the inserted card.\n * @param {String} cardName\n * @param {Object} [cardPayload={}]\n * @param {Boolean} [inEditMode=false] Whether the card should be inserted in edit mode.\n * @return {Card} The inserted Card section.\n * @public\n */\n }, {\n key: 'insertCard',\n value: function insertCard(cardName) {\n var _this9 = this;\n\n var cardPayload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n var inEditMode = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n if (!this.hasCursor()) {\n return;\n }\n if (this.post.isBlank) {\n this._insertEmptyMarkupSectionAtCursor();\n }\n\n var card = undefined;\n var range = this.range;\n\n this.run(function (postEditor) {\n var position = range.tail;\n card = postEditor.builder.createCardSection(cardName, cardPayload);\n if (inEditMode) {\n _this9.editCard(card);\n }\n\n if (!range.isCollapsed) {\n position = postEditor.deleteRange(range);\n }\n\n var section = position.section;\n if (section.isNested) {\n section = section.parent;\n }\n\n if (section.isBlank) {\n postEditor.replaceSection(section, card);\n } else {\n var collection = _this9.post.sections;\n postEditor.insertSectionBefore(collection, card, section.next);\n }\n\n // It is important to explicitly set the range to the end of the card.\n // Otherwise it is possible to create an inconsistent state in the\n // browser. For instance, if the user clicked a button that\n // called `editor.insertCard`, the editor surface may retain\n // the selection but lose focus, and the next keystroke by the user\n // will cause an unexpected DOM mutation (which can wipe out the\n // card).\n // See: https://github.com/bustle/mobiledoc-kit/issues/286\n postEditor.setRange(card.tailPosition());\n });\n return card;\n }\n\n /**\n * @param {integer} x x-position in viewport\n * @param {integer} y y-position in viewport\n * @return {Position|null}\n */\n }, {\n key: 'positionAtPoint',\n value: function positionAtPoint(x, y) {\n return _mobiledocKitUtilsCursorPosition['default'].atPoint(x, y, this);\n }\n\n /**\n * @private\n */\n }, {\n key: '_setCardMode',\n value: function _setCardMode(cardSection, mode) {\n var renderNode = cardSection.renderNode;\n if (renderNode && renderNode.isRendered) {\n var cardNode = renderNode.cardNode;\n cardNode[mode]();\n } else {\n cardSection.setInitialMode(mode);\n }\n }\n }, {\n key: 'triggerEvent',\n value: function triggerEvent(context, eventName, event) {\n this._eventManager._trigger(context, eventName, event);\n }\n }, {\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n if (this.isDestroyed) {\n // TODO warn that callback attempted after editor was destroyed\n return;\n }\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n\n /**\n * Runs each callback for the given hookName.\n * Only the hookName 'toggleMarkup' is currently supported\n * @return {Boolean} shouldCancel Whether the action in `hookName` should be canceled\n * @private\n */\n }, {\n key: '_runBeforeHooks',\n value: function _runBeforeHooks(hookName) {\n var hooks = this._beforeHooks[hookName] || [];\n\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n for (var i = 0; i < hooks.length; i++) {\n if (hooks[i].apply(hooks, args) === false) {\n return true;\n }\n }\n }\n }, {\n key: 'builder',\n get: function get() {\n if (!this._builder) {\n this._builder = new _mobiledocKitModelsPostNodeBuilder['default']();\n }\n return this._builder;\n }\n }, {\n key: 'keyCommands',\n get: function get() {\n if (!this._keyCommands) {\n this._keyCommands = [];\n }\n return this._keyCommands;\n }\n }, {\n key: 'cursor',\n get: function get() {\n return new _mobiledocKitUtilsCursor['default'](this);\n }\n\n /**\n * Return the current range for the editor (may be cached).\n * @return {Range}\n */\n }, {\n key: 'range',\n get: function get() {\n return this._editState.range;\n },\n set: function set(newRange) {\n this._editState.updateRange(newRange);\n\n if (this._editState.rangeDidChange()) {\n this._rangeDidChange();\n }\n\n if (this._editState.inputModeDidChange()) {\n this._inputModeDidChange();\n }\n }\n }, {\n key: 'activeSections',\n get: function get() {\n return this._editState.activeSections;\n }\n }, {\n key: 'activeSection',\n get: function get() {\n var activeSections = this.activeSections;\n\n return activeSections[activeSections.length - 1];\n }\n }, {\n key: 'activeSectionAttributes',\n get: function get() {\n return this._editState.activeSectionAttributes;\n }\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this._editState.activeMarkups;\n }\n }]);\n\n return Editor;\n })();\n\n exports['default'] = Editor;\n});","define('mobiledoc-kit/editor/event-manager', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/parse-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/editor/text-input-handler', 'mobiledoc-kit/editor/selection-manager', 'mobiledoc-kit/utils/browser'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitUtilsParseUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitEditorTextInputHandler, _mobiledocKitEditorSelectionManager, _mobiledocKitUtilsBrowser) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var ELEMENT_EVENT_TYPES = ['keydown', 'keyup', 'cut', 'copy', 'paste', 'keypress', 'drop'];\n\n var EventManager = (function () {\n function EventManager(editor) {\n _classCallCheck(this, EventManager);\n\n this.editor = editor;\n this.logger = editor.loggerFor('event-manager');\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](editor);\n this._listeners = [];\n this.modifierKeys = {\n shift: false\n };\n\n this._selectionManager = new _mobiledocKitEditorSelectionManager['default'](this.editor, this.selectionDidChange.bind(this));\n this.started = true;\n }\n\n _createClass(EventManager, [{\n key: 'init',\n value: function init() {\n var _this = this;\n\n var element = this.editor.element;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot init EventManager without element', !!element);\n\n ELEMENT_EVENT_TYPES.forEach(function (type) {\n _this._addListener(element, type);\n });\n\n this._selectionManager.start();\n }\n }, {\n key: 'start',\n value: function start() {\n this.started = true;\n }\n }, {\n key: 'stop',\n value: function stop() {\n this.started = false;\n }\n }, {\n key: 'registerInputHandler',\n value: function registerInputHandler(inputHandler) {\n this._textInputHandler.register(inputHandler);\n }\n }, {\n key: 'unregisterInputHandler',\n value: function unregisterInputHandler(name) {\n this._textInputHandler.unregister(name);\n }\n }, {\n key: 'unregisterAllTextInputHandlers',\n value: function unregisterAllTextInputHandlers() {\n this._textInputHandler.destroy();\n this._textInputHandler = new _mobiledocKitEditorTextInputHandler['default'](this.editor);\n }\n }, {\n key: '_addListener',\n value: function _addListener(context, type) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Missing listener for ' + type, !!this[type]);\n\n var listener = function listener(event) {\n return _this2._handleEvent(type, event);\n };\n context.addEventListener(type, listener);\n this._listeners.push([context, type, listener]);\n }\n }, {\n key: '_removeListeners',\n value: function _removeListeners() {\n this._listeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var context = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n context.removeEventListener(type, listener);\n });\n this._listeners = [];\n }\n\n // This is primarily useful for programmatically simulating events on the\n // editor from the tests.\n }, {\n key: '_trigger',\n value: function _trigger(context, type, event) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this._listeners, function (_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var _context = _ref32[0];\n var _type = _ref32[1];\n\n return _context === context && _type === type;\n }), function (_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var context = _ref42[0];\n var listener = _ref42[2];\n\n listener.call(context, event);\n });\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._textInputHandler.destroy();\n this._selectionManager.destroy();\n this._removeListeners();\n }\n }, {\n key: '_handleEvent',\n value: function _handleEvent(type, event) {\n var element = event.target;\n\n if (!this.started) {\n // abort handling this event\n return true;\n }\n\n if (!this.isElementAddressable(element)) {\n // abort handling this event\n return true;\n }\n\n this[type](event);\n }\n }, {\n key: 'isElementAddressable',\n value: function isElementAddressable(element) {\n return this.editor.cursor.isAddressable(element);\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange(selection /*, prevSelection */) {\n var shouldNotify = true;\n var anchorNode = selection.anchorNode;\n\n if (!this.isElementAddressable(anchorNode)) {\n if (!this.editor.range.isBlank) {\n // Selection changed from something addressable to something\n // not-addressable -- e.g., blur event, user clicked outside editor,\n // etc\n shouldNotify = true;\n } else {\n // selection changes wholly outside the editor should not trigger\n // change notifications\n shouldNotify = false;\n }\n }\n\n if (shouldNotify) {\n this.editor._readRangeFromDOM();\n }\n }\n }, {\n key: 'keypress',\n value: function keypress(event) {\n var editor = this.editor;\n var _textInputHandler = this._textInputHandler;\n\n if (!editor.hasCursor()) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n if (!key.isPrintable()) {\n return;\n } else {\n event.preventDefault();\n }\n\n _textInputHandler.handle(key.toString());\n }\n }, {\n key: 'keydown',\n value: function keydown(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n if (!editor.isEditable) {\n return;\n }\n\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: true });\n\n if (editor.handleKeyCommand(event)) {\n return;\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var range = editor.range;\n\n switch (true) {\n // FIXME This should be restricted to only card/atom boundaries\n case key.isHorizontalArrowWithoutModifiersOtherThanShift():\n {\n var newRange = undefined;\n if (key.isShift()) {\n newRange = range.extend(key.direction * 1);\n } else {\n newRange = range.move(key.direction);\n }\n\n editor.selectRange(newRange);\n event.preventDefault();\n break;\n }\n case key.isDelete():\n {\n var direction = key.direction;\n\n var unit = 'char';\n if (key.altKey && _mobiledocKitUtilsBrowser['default'].isMac()) {\n unit = 'word';\n } else if (key.ctrlKey && !_mobiledocKitUtilsBrowser['default'].isMac()) {\n unit = 'word';\n }\n editor.performDelete({ direction: direction, unit: unit });\n event.preventDefault();\n break;\n }\n case key.isEnter():\n this._textInputHandler.handleNewLine();\n editor.handleNewline(event);\n break;\n case key.isTab():\n // Handle tab here because it does not fire a `keypress` event\n event.preventDefault();\n this._textInputHandler.handle(key.toString());\n break;\n }\n }\n }, {\n key: 'keyup',\n value: function keyup(event) {\n var editor = this.editor;\n\n if (!editor.hasCursor()) {\n return;\n }\n var key = _mobiledocKitUtilsKey['default'].fromEvent(event);\n this._updateModifiersFromKey(key, { isDown: false });\n }\n }, {\n key: 'cut',\n value: function cut(event) {\n event.preventDefault();\n\n this.copy(event);\n this.editor.performDelete();\n }\n }, {\n key: 'copy',\n value: function copy(event) {\n event.preventDefault();\n\n var editor = this.editor;\n var _editor = this.editor;\n var range = _editor.range;\n var post = _editor.post;\n\n post = post.trimTo(range);\n\n var data = {\n html: editor.serializePost(post, 'html'),\n text: editor.serializePost(post, 'text'),\n mobiledoc: editor.serializePost(post, 'mobiledoc')\n };\n\n (0, _mobiledocKitUtilsParseUtils.setClipboardData)(event, data, window);\n }\n }, {\n key: 'paste',\n value: function paste(event) {\n event.preventDefault();\n\n var editor = this.editor;\n\n var range = editor.range;\n\n if (!range.isCollapsed) {\n editor.performDelete();\n }\n\n if (editor.post.isBlank) {\n editor._insertEmptyMarkupSectionAtCursor();\n }\n\n var position = editor.range.head;\n var targetFormat = this.modifierKeys.shift ? 'text' : 'html';\n var pastedPost = (0, _mobiledocKitUtilsParseUtils.parsePostFromPaste)(event, editor, { targetFormat: targetFormat });\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, pastedPost);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: 'drop',\n value: function drop(event) {\n event.preventDefault();\n\n var x = event.clientX;\n var y = event.clientY;\n var editor = this.editor;\n\n var position = editor.positionAtPoint(x, y);\n if (!position) {\n this.logger.log('Could not find drop position');\n return;\n }\n\n var post = (0, _mobiledocKitUtilsParseUtils.parsePostFromDrop)(event, editor, { logger: this.logger });\n if (!post) {\n this.logger.log('Could not determine post from drop event');\n return;\n }\n\n editor.run(function (postEditor) {\n var nextPosition = postEditor.insertPost(position, post);\n postEditor.setRange(nextPosition);\n });\n }\n }, {\n key: '_updateModifiersFromKey',\n value: function _updateModifiersFromKey(key, _ref5) {\n var isDown = _ref5.isDown;\n\n if (key.isShiftKey()) {\n this.modifierKeys.shift = isDown;\n }\n }\n }]);\n\n return EventManager;\n })();\n\n exports['default'] = EventManager;\n});","define('mobiledoc-kit/editor/key-commands', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/browser', 'mobiledoc-kit/editor/ui'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsBrowser, _mobiledocKitEditorUi) {\n 'use strict';\n\n exports.buildKeyCommand = buildKeyCommand;\n exports.validateKeyCommand = validateKeyCommand;\n exports.findKeyCommands = findKeyCommands;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function selectAll(editor) {\n var post = editor.post;\n\n editor.selectRange(post.toRange());\n }\n\n function gotoStartOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.headPosition());\n });\n }\n\n function gotoEndOfLine(editor) {\n var range = editor.range;\n var section = range.tail.section;\n\n editor.run(function (postEditor) {\n postEditor.setRange(section.tailPosition());\n });\n }\n\n function deleteToEndOfSection(editor) {\n var range = editor.range;\n\n if (range.isCollapsed) {\n var _range = range;\n var head = _range.head;\n var section = _range.head.section;\n\n range = head.toRange(section.tailPosition());\n }\n editor.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n var DEFAULT_KEY_COMMANDS = [{\n str: 'META+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'CTRL+B',\n run: function run(editor) {\n editor.toggleMarkup('strong');\n }\n }, {\n str: 'META+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'CTRL+I',\n run: function run(editor) {\n editor.toggleMarkup('em');\n }\n }, {\n str: 'META+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+U',\n run: function run(editor) {\n editor.toggleMarkup('u');\n }\n }, {\n str: 'CTRL+K',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return deleteToEndOfSection(editor);\n } else if (_mobiledocKitUtilsBrowser['default'].isWin()) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n }\n }, {\n str: 'CTRL+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoStartOfLine(editor);\n } else {\n selectAll(editor);\n }\n }\n }, {\n str: 'META+A',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n selectAll(editor);\n }\n }\n }, {\n str: 'CTRL+E',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n gotoEndOfLine(editor);\n }\n }\n }, {\n str: 'META+K',\n run: function run(editor) {\n return (0, _mobiledocKitEditorUi.toggleLink)(editor);\n }\n\n }, {\n str: 'META+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.undoLastChange();\n });\n }\n }, {\n str: 'META+SHIFT+Z',\n run: function run(editor) {\n editor.run(function (postEditor) {\n postEditor.redoLastChange();\n });\n }\n }, {\n str: 'CTRL+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.undoLastChange();\n });\n }\n }, {\n str: 'CTRL+SHIFT+Z',\n run: function run(editor) {\n if (_mobiledocKitUtilsBrowser['default'].isMac()) {\n return false;\n }\n editor.run(function (postEditor) {\n return postEditor.redoLastChange();\n });\n }\n }];\n\n exports.DEFAULT_KEY_COMMANDS = DEFAULT_KEY_COMMANDS;\n function modifierNamesToMask(modiferNames) {\n var defaultVal = 0;\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(modiferNames, function (sum, name) {\n var modifier = _mobiledocKitUtilsKey.MODIFIERS[name.toUpperCase()];\n (0, _mobiledocKitUtilsAssert['default'])('No modifier named \"' + name + '\" found', !!modifier);\n return sum + modifier;\n }, defaultVal);\n }\n\n function characterToCode(character) {\n var upperCharacter = character.toUpperCase();\n var special = (0, _mobiledocKitUtilsKey.specialCharacterToCode)(upperCharacter);\n if (special) {\n return special;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Only 1 character can be used in a key command str (got \"' + character + '\")', character.length === 1);\n return upperCharacter.charCodeAt(0);\n }\n }\n\n function buildKeyCommand(keyCommand) {\n var str = keyCommand.str;\n\n if (!str) {\n return keyCommand;\n }\n (0, _mobiledocKitUtilsAssert['default'])('[deprecation] Key commands no longer use the `modifier` property', !keyCommand.modifier);\n\n var _str$split$reverse = str.split('+').reverse();\n\n var _str$split$reverse2 = _toArray(_str$split$reverse);\n\n var character = _str$split$reverse2[0];\n\n var modifierNames = _str$split$reverse2.slice(1);\n\n keyCommand.modifierMask = modifierNamesToMask(modifierNames);\n keyCommand.code = characterToCode(character);\n\n return keyCommand;\n }\n\n function validateKeyCommand(keyCommand) {\n return !!keyCommand.code && !!keyCommand.run;\n }\n\n function findKeyCommands(keyCommands, keyEvent) {\n var key = _mobiledocKitUtilsKey['default'].fromEvent(keyEvent);\n\n return (0, _mobiledocKitUtilsArrayUtils.filter)(keyCommands, function (_ref) {\n var modifierMask = _ref.modifierMask;\n var code = _ref.code;\n\n return key.keyCode === code && key.modifierMask === modifierMask;\n });\n }\n});","define('mobiledoc-kit/editor/mutation-handler', ['exports', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsSet, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MUTATION = {\n NODES_CHANGED: 'childList',\n CHARACTER_DATA: 'characterData'\n };\n\n var MutationHandler = (function () {\n function MutationHandler(editor) {\n var _this = this;\n\n _classCallCheck(this, MutationHandler);\n\n this.editor = editor;\n this.logger = editor.loggerFor('mutation-handler');\n this.renderTree = null;\n this._isObserving = false;\n\n this._observer = new MutationObserver(function (mutations) {\n _this._handleMutations(mutations);\n });\n }\n\n _createClass(MutationHandler, [{\n key: 'init',\n value: function init() {\n this.startObserving();\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stopObserving();\n this._observer = null;\n }\n }, {\n key: 'suspendObservation',\n value: function suspendObservation(callback) {\n this.stopObserving();\n callback();\n this.startObserving();\n }\n }, {\n key: 'stopObserving',\n value: function stopObserving() {\n if (this._isObserving) {\n this._isObserving = false;\n this._observer.disconnect();\n }\n }\n }, {\n key: 'startObserving',\n value: function startObserving() {\n if (!this._isObserving) {\n var editor = this.editor;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot observe un-rendered editor', editor.hasRendered);\n\n this._isObserving = true;\n this.renderTree = editor._renderTree;\n\n this._observer.observe(editor.element, {\n characterData: true,\n childList: true,\n subtree: true\n });\n }\n }\n }, {\n key: 'reparsePost',\n value: function reparsePost() {\n this.editor._reparsePost();\n }\n }, {\n key: 'reparseSections',\n value: function reparseSections(sections) {\n this.editor._reparseSections(sections);\n }\n\n /**\n * for each mutation:\n * * find the target nodes:\n * * if nodes changed, target nodes are:\n * * added nodes\n * * the target from which removed nodes were removed\n * * if character data changed\n * * target node is the mutation event's target (text node)\n * * filter out nodes that are no longer attached (parentNode is null)\n * * for each remaining node:\n * * find its section, add to sections-to-reparse\n * * if no section, reparse all (and break)\n */\n }, {\n key: '_handleMutations',\n value: function _handleMutations(mutations) {\n var reparsePost = false;\n var sections = new _mobiledocKitUtilsSet['default']();\n\n for (var i = 0; i < mutations.length; i++) {\n if (reparsePost) {\n break;\n }\n\n var nodes = this._findTargetNodes(mutations[i]);\n\n for (var j = 0; j < nodes.length; j++) {\n var node = nodes[j];\n var renderNode = this._findRenderNodeFromNode(node);\n if (renderNode) {\n if (renderNode.reparsesMutationOfChildNode(node)) {\n var section = this._findSectionFromRenderNode(renderNode);\n if (section) {\n sections.add(section);\n } else {\n reparsePost = true;\n }\n }\n } else {\n reparsePost = true;\n break;\n }\n }\n }\n\n if (reparsePost) {\n this.logger.log('reparsePost (' + mutations.length + ' mutations)');\n this.reparsePost();\n } else if (sections.length) {\n this.logger.log('reparse ' + sections.length + ' sections (' + mutations.length + ' mutations)');\n this.reparseSections(sections.toArray());\n }\n }\n }, {\n key: '_findTargetNodes',\n value: function _findTargetNodes(mutation) {\n var nodes = [];\n\n switch (mutation.type) {\n case MUTATION.CHARACTER_DATA:\n nodes.push(mutation.target);\n break;\n case MUTATION.NODES_CHANGED:\n (0, _mobiledocKitUtilsArrayUtils.forEach)(mutation.addedNodes, function (n) {\n return nodes.push(n);\n });\n if (mutation.removedNodes.length) {\n nodes.push(mutation.target);\n }\n break;\n }\n\n var element = this.editor.element;\n var attachedNodes = (0, _mobiledocKitUtilsArrayUtils.filter)(nodes, function (node) {\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, node);\n });\n return attachedNodes;\n }\n }, {\n key: '_findSectionRenderNodeFromNode',\n value: function _findSectionRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node, function (rn) {\n return rn.postNode.isSection;\n });\n }\n }, {\n key: '_findRenderNodeFromNode',\n value: function _findRenderNodeFromNode(node) {\n return this.renderTree.findRenderNodeFromElement(node);\n }\n }, {\n key: '_findSectionFromRenderNode',\n value: function _findSectionFromRenderNode(renderNode) {\n var sectionRenderNode = this._findSectionRenderNodeFromNode(renderNode.element);\n return sectionRenderNode && sectionRenderNode.postNode;\n }\n }]);\n\n return MutationHandler;\n })();\n\n exports['default'] = MutationHandler;\n});","define('mobiledoc-kit/editor/post', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/editor/post/post-inserter', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/to-range'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKey, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDomUtils, _mobiledocKitEditorPostPostInserter, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsToRange) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n function isListSectionTagName(tagName) {\n return tagName === 'ul' || tagName === 'ol';\n }\n\n var CALLBACK_QUEUES = {\n BEFORE_COMPLETE: 'beforeComplete',\n COMPLETE: 'complete',\n AFTER_COMPLETE: 'afterComplete'\n };\n\n // There are only two events that we're concerned about for Undo, that is inserting text and deleting content.\n // These are the only two states that go on a \"run\" and create a combined undo, everything else has it's own\n // deadicated undo.\n var EDIT_ACTIONS = {\n INSERT_TEXT: 1,\n DELETE: 2\n };\n\n /**\n * The PostEditor is used to modify a post. It should not be instantiated directly.\n * Instead, a new instance of a PostEditor is created by the editor and passed\n * as the argument to the callback in {@link Editor#run}.\n *\n * Usage:\n * ```\n * editor.run((postEditor) => {\n * // postEditor is an instance of PostEditor that can operate on the\n * // editor's post\n * });\n * ```\n */\n\n var PostEditor = (function () {\n /**\n * @private\n */\n\n function PostEditor(editor) {\n var _this = this;\n\n _classCallCheck(this, PostEditor);\n\n this.editor = editor;\n this.builder = this.editor.builder;\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n\n this._didComplete = false;\n this.editActionTaken = null;\n\n this._renderRange = function () {\n return _this.editor.selectRange(_this._range);\n };\n this._postDidChange = function () {\n return _this.editor._postDidChange();\n };\n this._rerender = function () {\n return _this.editor.rerender();\n };\n }\n\n _createClass(PostEditor, [{\n key: 'addCallback',\n value: function addCallback() {\n var _callbacks;\n\n (_callbacks = this._callbacks).addCallback.apply(_callbacks, arguments);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce() {\n var _callbacks2;\n\n (_callbacks2 = this._callbacks).addCallbackOnce.apply(_callbacks2, arguments);\n }\n }, {\n key: 'runCallbacks',\n value: function runCallbacks() {\n var _callbacks3;\n\n (_callbacks3 = this._callbacks).runCallbacks.apply(_callbacks3, arguments);\n }\n }, {\n key: 'begin',\n value: function begin() {\n // cache the editor's range\n this._range = this.editor.range;\n }\n\n /**\n * Schedules to select the given range on the editor after the postEditor\n * has completed its work. This also updates the postEditor's active range\n * (so that multiple calls to range-changing methods on the postEditor will\n * update the correct range).\n *\n * Usage:\n * let range = editor.range;\n * editor.run(postEditor => {\n * let nextPosition = postEditor.deleteRange(range);\n *\n * // Will position the editor's cursor at `nextPosition` after\n * // the postEditor finishes work and the editor rerenders.\n * postEditor.setRange(nextPosition);\n * });\n * @param {Range|Position} range\n * @public\n */\n }, {\n key: 'setRange',\n value: function setRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n // TODO validate that the range is valid\n // (does not contain marked-for-removal head or tail sections?)\n this._range = range;\n this.scheduleAfterRender(this._renderRange, true);\n }\n\n /**\n * Delete a range from the post\n *\n * Usage:\n * ```\n * let { range } = editor;\n * editor.run((postEditor) => {\n * let nextPosition = postEditor.deleteRange(range);\n * postEditor.setRange(nextPosition);\n * });\n * ```\n * @param {Range} range Cursor Range object with head and tail Positions\n * @return {Position} The position where the cursor would go after deletion\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass MobiledocKit Range to `deleteRange`\", range instanceof _mobiledocKitUtilsCursorRange['default']);\n\n this.editActionTaken = EDIT_ACTIONS.DELETE;\n\n var head = range.head;\n var headSection = range.head.section;\n var tail = range.tail;\n var tailSection = range.tail.section;\n var post = this.editor.post;\n\n if (headSection === tailSection) {\n return this.cutSection(headSection, head, tail);\n }\n\n var nextSection = headSection.nextLeafSection();\n\n var nextPos = this.cutSection(headSection, head, headSection.tailPosition());\n // cutSection can replace the section, so re-read headSection here\n headSection = nextPos.section;\n\n // Remove sections in the middle of the range\n while (nextSection !== tailSection) {\n var tmp = nextSection;\n nextSection = nextSection.nextLeafSection();\n this.removeSection(tmp);\n }\n\n var tailPos = this.cutSection(tailSection, tailSection.headPosition(), tail);\n // cutSection can replace the section, so re-read tailSection here\n tailSection = tailPos.section;\n\n if (tailSection.isBlank) {\n this.removeSection(tailSection);\n } else {\n // If head and tail sections are markerable, join them\n // Note: They may not be the same section type. E.g. this may join\n // a tail section that was a list item onto a markup section, or vice versa.\n // (This is the desired behavior.)\n if (headSection.isMarkerable && tailSection.isMarkerable) {\n headSection.join(tailSection);\n this._markDirty(headSection);\n this.removeSection(tailSection);\n } else if (headSection.isBlank) {\n this.removeSection(headSection);\n nextPos = tailPos;\n }\n }\n\n if (post.isBlank) {\n post.sections.append(this.builder.createMarkupSection('p'));\n nextPos = post.headPosition();\n }\n\n return nextPos;\n }\n\n /**\n * Note: This method may replace `section` with a different section.\n *\n * \"Cut\" out the part of the section inside `headOffset` and `tailOffset`.\n * If section is markerable this splits markers that straddle the head or tail (if necessary),\n * and removes markers that are wholly inside the offsets.\n * If section is a card, this may replace it with a blank markup section if the\n * positions contain the entire card.\n *\n * @param {Section} section\n * @param {Position} head\n * @param {Position} tail\n * @return {Position}\n * @private\n */\n }, {\n key: 'cutSection',\n value: function cutSection(section, head, tail) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass head position and tail position to `cutSection`', head instanceof _mobiledocKitUtilsCursorPosition['default'] && tail instanceof _mobiledocKitUtilsCursorPosition['default']);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass positions within same section to `cutSection`', head.section === tail.section);\n\n if (section.isBlank || head.isEqual(tail)) {\n return head;\n }\n if (section.isCardSection) {\n if (head.isHead() && tail.isTail()) {\n var newSection = this.builder.createMarkupSection();\n this.replaceSection(section, newSection);\n return newSection.headPosition();\n } else {\n return tail;\n }\n }\n\n var range = head.toRange(tail);\n this.splitMarkers(range).forEach(function (m) {\n return _this2.removeMarker(m);\n });\n\n return head;\n }\n }, {\n key: '_coalesceMarkers',\n value: function _coalesceMarkers(section) {\n if (section.isMarkerable) {\n this._removeBlankMarkers(section);\n this._joinSimilarMarkers(section);\n }\n }\n }, {\n key: '_removeBlankMarkers',\n value: function _removeBlankMarkers(section) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }), function (m) {\n return _this3.removeMarker(m);\n });\n }\n\n // joins markers that have identical markups\n }, {\n key: '_joinSimilarMarkers',\n value: function _joinSimilarMarkers(section) {\n var marker = section.markers.head;\n var nextMarker = undefined;\n while (marker && marker.next) {\n nextMarker = marker.next;\n\n if (marker.canJoin(nextMarker)) {\n nextMarker.value = marker.value + nextMarker.value;\n this._markDirty(nextMarker);\n this.removeMarker(marker);\n }\n\n marker = nextMarker;\n }\n }\n }, {\n key: 'removeMarker',\n value: function removeMarker(marker) {\n this._scheduleForRemoval(marker);\n if (marker.section) {\n this._markDirty(marker.section);\n marker.section.markers.remove(marker);\n }\n }\n }, {\n key: '_scheduleForRemoval',\n value: function _scheduleForRemoval(postNode) {\n var _this4 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.scheduleForRemoval();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n var removedAdjacentToList = postNode.prev && postNode.prev.isListSection || postNode.next && postNode.next.isListSection;\n if (removedAdjacentToList) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this4._joinContiguousListSections();\n });\n }\n }\n }, {\n key: '_joinContiguousListSections',\n value: function _joinContiguousListSections() {\n var _this5 = this;\n\n var post = this.editor.post;\n\n var range = this._range;\n var prev = undefined;\n var groups = [];\n var currentGroup = undefined;\n\n // FIXME do we need to force a re-render of the range if changed sections\n // are contained within the range?\n var updatedHead = null;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n if (prev && prev.isListSection && section.isListSection && prev.tagName === section.tagName) {\n\n currentGroup = currentGroup || [prev];\n currentGroup.push(section);\n } else {\n if (currentGroup) {\n groups.push(currentGroup);\n }\n currentGroup = null;\n }\n prev = section;\n });\n\n if (currentGroup) {\n groups.push(currentGroup);\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(groups, function (group) {\n var list = group[0];\n (0, _mobiledocKitUtilsArrayUtils.forEach)(group, function (listSection) {\n if (listSection === list) {\n return;\n }\n\n var currentHead = range.head;\n var prevPosition = undefined;\n\n // FIXME is there a currentHead if there is no range?\n // is the current head a list item in the section\n if (!range.isBlank && currentHead.section.isListItem && currentHead.section.parent === listSection) {\n prevPosition = list.tailPosition();\n }\n _this5._joinListSections(list, listSection);\n if (prevPosition) {\n updatedHead = prevPosition.move(FORWARD);\n }\n });\n });\n\n if (updatedHead) {\n this.setRange(updatedHead);\n }\n }\n }, {\n key: '_joinListSections',\n value: function _joinListSections(baseList, nextList) {\n baseList.join(nextList);\n this._markDirty(baseList);\n this.removeSection(nextList);\n }\n }, {\n key: '_markDirty',\n value: function _markDirty(postNode) {\n var _this6 = this;\n\n if (postNode.renderNode) {\n postNode.renderNode.markDirty();\n\n this.scheduleRerender();\n this.scheduleDidUpdate();\n }\n if (postNode.section) {\n this._markDirty(postNode.section);\n }\n if (postNode.isMarkerable) {\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n return _this6._coalesceMarkers(postNode);\n });\n }\n }\n\n /**\n * @param {Position} position object with {section, offset} the marker and offset to delete from\n * @param {Number} direction The direction to delete in (default is BACKWARD)\n * @return {Position} for positioning the cursor\n * @public\n * @deprecated after v0.10.3\n */\n }, {\n key: 'deleteFrom',\n value: function deleteFrom(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n (0, _mobiledocKitUtilsDeprecate['default'])(\"`postEditor#deleteFrom is deprecated. Use `deleteAtPosition(position, direction=BACKWARD, {unit}={unit: 'char'})` instead\");\n return this.deleteAtPosition(position, direction, { unit: 'char' });\n }\n\n /**\n * Delete 1 `unit` (can be 'char' or 'word') in the given `direction` at the given\n * `position`. In almost all cases this will be equivalent to deleting the range formed\n * by expanding the position 1 unit in the given direction. The exception is when deleting\n * backward from the beginning of a list item, which reverts the list item into a markup section\n * instead of joining it with its previous list item (if any).\n *\n * Usage:\n *\n * let position = section.tailPosition();\n * // Section has text of \"Howdy!\"\n * editor.run((postEditor) => {\n * postEditor.deleteAtPosition(position);\n * });\n * // section has text of \"Howdy\"\n *\n * @param {Position} position The position to delete at\n * @param {Direction} [direction=DIRECTION.BACKWARD] direction The direction to delete in\n * @param {Object} [options]\n * @param {String} [options.unit=\"char\"] The unit of deletion (\"word\" or \"char\")\n * @return {Position}\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position) {\n var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1];\n\n var _ref = arguments.length <= 2 || arguments[2] === undefined ? { unit: 'char' } : arguments[2];\n\n var unit = _ref.unit;\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n return this._deleteAtPositionBackward(position, unit);\n } else {\n return this._deleteAtPositionForward(position, unit);\n }\n }\n }, {\n key: '_deleteAtPositionBackward',\n value: function _deleteAtPositionBackward(position, unit) {\n if (position.isHead() && position.section.isListItem) {\n this.toggleSection('p', position);\n return this._range.head;\n } else {\n var prevPosition = unit === 'word' ? position.moveWord(BACKWARD) : position.move(BACKWARD);\n var range = prevPosition.toRange(position);\n return this.deleteRange(range);\n }\n }\n }, {\n key: '_deleteAtPositionForward',\n value: function _deleteAtPositionForward(position, unit) {\n var nextPosition = unit === 'word' ? position.moveWord(FORWARD) : position.move(FORWARD);\n var range = position.toRange(nextPosition);\n return this.deleteRange(range);\n }\n\n /**\n * Split markers at two positions, once at the head, and if necessary once\n * at the tail.\n *\n * Usage:\n * ```\n * let range = editor.range;\n * editor.run((postEditor) => {\n * postEditor.splitMarkers(range);\n * });\n * ```\n * The return value will be marker object completely inside the offsets\n * provided. Markers outside of the split may also have been modified.\n *\n * @param {Range} markerRange\n * @return {Array} of markers that are inside the split\n * @private\n */\n }, {\n key: 'splitMarkers',\n value: function splitMarkers(range) {\n var post = this.editor.post;\n var head = range.head;\n var tail = range.tail;\n\n this.splitSectionMarkerAtOffset(head.section, head.offset);\n this.splitSectionMarkerAtOffset(tail.section, tail.offset);\n\n return post.markersContainedByRange(range);\n }\n }, {\n key: 'splitSectionMarkerAtOffset',\n value: function splitSectionMarkerAtOffset(section, offset) {\n var _this7 = this;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (m) {\n return _this7.removeMarker(m);\n });\n }\n\n /**\n * Split the section at the position.\n *\n * Usage:\n * ```\n * let position = editor.cursor.offsets.head;\n * editor.run((postEditor) => {\n * postEditor.splitSection(position);\n * });\n * // Will result in the creation of two new sections\n * // replacing the old one at the cursor position\n * ```\n * The return value will be the two new sections. One or both of these\n * sections can be blank (contain only a blank marker), for example if the\n * headMarkerOffset is 0.\n *\n * @param {Position} position\n * @return {Array} new sections, one for the first half and one for the second (either one can be null)\n * @public\n */\n }, {\n key: 'splitSection',\n value: function splitSection(position) {\n var _this8 = this;\n\n var section = position.section;\n\n if (section.isCardSection) {\n return this._splitCardSection(section, position);\n } else if (section.isListItem) {\n var isLastAndBlank = section.isBlank && !section.next;\n if (isLastAndBlank) {\n // if is last, replace the item with a blank markup section\n var _parent = section.parent;\n var collection = this.editor.post.sections;\n var blank = this.builder.createMarkupSection();\n this.removeSection(section);\n this.insertSectionBefore(collection, blank, _parent.next);\n\n return [null, blank];\n } else {\n var _splitListItem2 = this._splitListItem(section, position);\n\n var _splitListItem22 = _slicedToArray(_splitListItem2, 2);\n\n var pre = _splitListItem22[0];\n var post = _splitListItem22[1];\n\n return [pre, post];\n }\n } else {\n var splitSections = section.splitAtPosition(position);\n splitSections.forEach(function (s) {\n return _this8._coalesceMarkers(s);\n });\n this._replaceSection(section, splitSections);\n\n return splitSections;\n }\n }\n\n /**\n * @param {Section} cardSection\n * @param {Position} position to split at\n * @return {Section[]} 2-item array of pre and post-split sections\n * @private\n */\n }, {\n key: '_splitCardSection',\n value: function _splitCardSection(cardSection, position) {\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cards section must be split at offset 0 or 1', offset === 0 || offset === 1);\n\n var newSection = this.builder.createMarkupSection();\n var nextSection = undefined;\n var surroundingSections = undefined;\n\n if (offset === 0) {\n nextSection = cardSection;\n surroundingSections = [newSection, cardSection];\n } else {\n nextSection = cardSection.next;\n surroundingSections = [cardSection, newSection];\n }\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, newSection, nextSection);\n\n return surroundingSections;\n }\n\n /**\n * @param {Section} section\n * @param {Section} newSection\n * @return null\n * @public\n */\n }, {\n key: 'replaceSection',\n value: function replaceSection(section, newSection) {\n if (!section) {\n // FIXME should a falsy section be a valid argument?\n this.insertSectionBefore(this.editor.post.sections, newSection, null);\n } else {\n this._replaceSection(section, [newSection]);\n }\n }\n }, {\n key: 'moveSectionBefore',\n value: function moveSectionBefore(collection, renderedSection, beforeSection) {\n var newSection = renderedSection.clone();\n this.removeSection(renderedSection);\n this.insertSectionBefore(collection, newSection, beforeSection);\n return newSection;\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionUp',\n value: function moveSectionUp(renderedSection) {\n var isFirst = !renderedSection.prev;\n if (isFirst) {\n return renderedSection;\n }\n\n var collection = renderedSection.parent.sections;\n var beforeSection = renderedSection.prev;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * @param {Section} section A section that is already in DOM\n * @public\n */\n }, {\n key: 'moveSectionDown',\n value: function moveSectionDown(renderedSection) {\n var isLast = !renderedSection.next;\n if (isLast) {\n return renderedSection;\n }\n\n var beforeSection = renderedSection.next.next;\n var collection = renderedSection.parent.sections;\n return this.moveSectionBefore(collection, renderedSection, beforeSection);\n }\n\n /**\n * Insert an array of markers at the given position. If the position is in\n * a non-markerable section (like a card section), this method throws an error.\n *\n * @param {Position} position\n * @param {Marker[]} markers\n * @return {Position} The position that represents the end of the inserted markers.\n * @public\n */\n }, {\n key: 'insertMarkers',\n value: function insertMarkers(position, markers) {\n var _this9 = this;\n\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert markers at non-markerable position', section.isMarkerable);\n\n this.editActionTaken = EDIT_ACTIONS.INSERT_TEXT;\n\n var edit = section.splitMarkerAtOffset(offset);\n edit.removed.forEach(function (marker) {\n return _this9._scheduleForRemoval(marker);\n });\n\n var prevMarker = section.markerBeforeOffset(offset);\n markers.forEach(function (marker) {\n section.markers.insertAfter(marker, prevMarker);\n offset += marker.length;\n prevMarker = marker;\n });\n\n this._coalesceMarkers(section);\n this._markDirty(section);\n\n var nextPosition = section.toPosition(offset);\n this.setRange(nextPosition);\n return nextPosition;\n }\n\n /**\n * Inserts text with the given markups, ignoring the existing markups at\n * the position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @param {Markup[]} markups\n * @return {Position} position at the end of the inserted text\n */\n }, {\n key: 'insertTextWithMarkup',\n value: function insertTextWithMarkup(position, text) {\n var markups = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var marker = this.builder.createMarker(text, markups);\n return this.insertMarkers(position, [marker]);\n }\n\n /**\n * Insert the text at the given position\n * Inherits the markups already at that position, if any.\n *\n * @param {Position} position\n * @param {String} text\n * @return {Position} position at the end of the inserted text.\n */\n }, {\n key: 'insertText',\n value: function insertText(position, text) {\n var section = position.section;\n\n if (!section.isMarkerable) {\n return;\n }\n var markups = position.marker && position.marker.markups;\n markups = markups || [];\n return this.insertTextWithMarkup(position, text, markups);\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this10 = this;\n\n var nextSection = section.next;\n var collection = section.parent.sections;\n\n var nextNewSection = newSections[0];\n if (nextNewSection.isMarkupSection && section.isListItem) {\n // put the new section after the ListSection (section.parent)\n // instead of after the ListItem\n collection = section.parent.parent.sections;\n nextSection = section.parent.next;\n }\n\n newSections.forEach(function (s) {\n return _this10.insertSectionBefore(collection, s, nextSection);\n });\n this.removeSection(section);\n }\n\n /**\n * Given a markerRange (for example `editor.range`) mark all markers\n * inside it as a given markup. The markup must be provided as a post\n * abstract node.\n *\n * Usage:\n *\n * let range = editor.range;\n * let strongMarkup = editor.builder.createMarkup('strong');\n * editor.run((postEditor) => {\n * postEditor.addMarkupToRange(range, strongMarkup);\n * });\n * // Will result some markers possibly being split, and the markup\n * // being applied to all markers between the split.\n *\n * @param {Range} range\n * @param {Markup} markup A markup post abstract node\n * @public\n */\n }, {\n key: 'addMarkupToRange',\n value: function addMarkupToRange(range, markup) {\n var _this11 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n var markers = this.splitMarkers(range);\n if (markers.length) {\n (function () {\n // We insert the new markup at a consistent index across the range.\n // If we just push on the end of the list, it can end up in different positions\n // of the markup stack. This results in unnecessary closing and re-opening of\n // the markup each time it changes position.\n // If we just push it at the beginning of the list, this causes unnecessary closing\n // and re-opening of surrounding tags.\n // So, we look for any tags open across the whole range, and push into the stack\n // at the end of those.\n // Prompted by https://github.com/bustle/mobiledoc-kit/issues/360\n\n var markupsOpenAcrossRange = (0, _mobiledocKitUtilsArrayUtils.reduce)(markers, function (soFar, marker) {\n return (0, _mobiledocKitUtilsArrayUtils.commonItems)(soFar, marker.markups);\n }, markers[0].markups);\n var indexToInsert = markupsOpenAcrossRange.length;\n\n markers.forEach(function (marker) {\n marker.addMarkupAtIndex(markup, indexToInsert);\n _this11._markDirty(marker);\n });\n })();\n }\n }\n\n /**\n * Given a markerRange (for example `editor.range`) remove the given\n * markup from all contained markers.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let markup = markerRange.headMarker.markups[0];\n * editor.run(postEditor => {\n * postEditor.removeMarkupFromRange(range, markup);\n * });\n * // Will result in some markers possibly being split, and the markup\n * // being removed from all markers between the split.\n * ```\n * @param {Range} range Object with offsets\n * @param {Markup|Function} markupOrCallback A markup post abstract node or\n * a function that returns true when passed a markup that should be removed\n * @private\n */\n }, {\n key: 'removeMarkupFromRange',\n value: function removeMarkupFromRange(range, markupOrMarkupCallback) {\n var _this12 = this;\n\n if (range.isCollapsed) {\n return;\n }\n\n this.splitMarkers(range).forEach(function (marker) {\n marker.removeMarkup(markupOrMarkupCallback);\n _this12._markDirty(marker);\n });\n }\n\n /**\n * Toggle the given markup in the given range (or at the position given). If the range/position\n * has the markup, the markup will be removed. If nothing in the range/position\n * has the markup, the markup will be added to everything in the range/position.\n *\n * Usage:\n * ```\n * // Remove any 'strong' markup if it exists in the selection, otherwise\n * // make it all 'strong'\n * editor.run(postEditor => postEditor.toggleMarkup('strong'));\n *\n * // add/remove a link to 'bustle.com' to the selection\n * editor.run(postEditor => {\n * const linkMarkup = postEditor.builder.createMarkup('a', {href: 'http://bustle.com'});\n * postEditor.toggleMarkup(linkMarkup);\n * });\n * ```\n * @param {Markup|String} markupOrString Either a markup object created using\n * the builder (useful when adding a markup with attributes, like an 'a' markup),\n * or, if a string, the tag name of the markup (e.g. 'strong', 'em') to toggle.\n * @param {Range|Position} range in which to toggle. Defaults to current editor range.\n * @public\n */\n }, {\n key: 'toggleMarkup',\n value: function toggleMarkup(markupOrMarkupString) {\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n var markup = typeof markupOrMarkupString === 'string' ? this.builder.createMarkup(markupOrMarkupString) : markupOrMarkupString;\n\n var hasMarkup = this.editor.detectMarkupInRange(range, markup.tagName);\n // FIXME: This implies only a single markup in a range. This may not be\n // true for links (which are not the same object instance like multiple\n // strong tags would be).\n if (hasMarkup) {\n this.removeMarkupFromRange(range, hasMarkup);\n } else {\n this.addMarkupToRange(range, markup);\n }\n\n this.setRange(range);\n }\n\n /**\n * Toggles the tagName of the active section or sections in the given range/position.\n * If every section has the tag name, they will all be reset to default sections.\n * Otherwise, every section will be changed to the requested type\n *\n * @param {String} sectionTagName A valid markup section or\n * list section tag name (e.g. 'blockquote', 'h2', 'ul')\n * @param {Range|Position} range The range over which to toggle.\n * Defaults to the current editor range.\n * @public\n */\n }, {\n key: 'toggleSection',\n value: function toggleSection(sectionTagName) {\n var _this13 = this;\n\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n sectionTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(sectionTagName);\n var post = this.editor.post;\n\n var everySectionHasTagName = true;\n post.walkMarkerableSections(range, function (section) {\n if (!_this13._isSameSectionType(section, sectionTagName)) {\n everySectionHasTagName = false;\n }\n });\n\n var tagName = everySectionHasTagName ? 'p' : sectionTagName;\n var sectionTransformations = [];\n post.walkMarkerableSections(range, function (section) {\n var changedSection = _this13.changeSectionTagName(section, tagName);\n sectionTransformations.push({\n from: section,\n to: changedSection\n });\n });\n\n var nextRange = this._determineNextRangeAfterToggleSection(range, sectionTransformations);\n this.setRange(nextRange);\n }\n }, {\n key: '_determineNextRangeAfterToggleSection',\n value: function _determineNextRangeAfterToggleSection(range, sectionTransformations) {\n if (sectionTransformations.length) {\n var changedHeadSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref2) {\n var from = _ref2.from;\n\n return from === range.headSection;\n }).to;\n var changedTailSection = (0, _mobiledocKitUtilsArrayUtils.detect)(sectionTransformations, function (_ref3) {\n var from = _ref3.from;\n\n return from === range.tailSection;\n }).to;\n\n if (changedHeadSection.isListSection || changedTailSection.isListSection) {\n // We don't know to which ListItem's the original sections point at, so\n // we don't have enough information to reconstruct the range when\n // dealing with lists.\n return sectionTransformations[0].to.headPosition().toRange();\n } else {\n return _mobiledocKitUtilsCursorRange['default'].create(changedHeadSection, range.headSectionOffset, changedTailSection, range.tailSectionOffset, range.direction);\n }\n } else {\n return range;\n }\n }\n }, {\n key: 'setAttribute',\n value: function setAttribute(key, value) {\n var range = arguments.length <= 2 || arguments[2] === undefined ? this._range : arguments[2];\n\n this._mutateAttribute(key, range, function (section, attribute) {\n if (section.getAttribute(attribute) !== value) {\n section.setAttribute(attribute, value);\n return true;\n }\n });\n }\n }, {\n key: 'removeAttribute',\n value: function removeAttribute(key) {\n var range = arguments.length <= 1 || arguments[1] === undefined ? this._range : arguments[1];\n\n this._mutateAttribute(key, range, function (section, attribute) {\n if (section.hasAttribute(attribute)) {\n section.removeAttribute(attribute);\n return true;\n }\n });\n }\n }, {\n key: '_mutateAttribute',\n value: function _mutateAttribute(key, range, cb) {\n var _this14 = this;\n\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n var post = this.editor.post;\n\n var attribute = 'data-md-' + key;\n\n post.walkMarkerableSections(range, function (section) {\n if (section.isListItem) {\n section = section.parent;\n }\n\n if (cb(section, attribute) === true) {\n _this14._markDirty(section);\n }\n });\n\n this.setRange(range);\n }\n }, {\n key: '_isSameSectionType',\n value: function _isSameSectionType(section, sectionTagName) {\n return section.isListItem ? section.parent.tagName === sectionTagName : section.tagName === sectionTagName;\n }\n\n /**\n * @param {Markerable} section\n * @private\n */\n }, {\n key: 'changeSectionTagName',\n value: function changeSectionTagName(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot pass non-markerable section to `changeSectionTagName`', section.isMarkerable);\n\n if (isListSectionTagName(newTagName)) {\n return this._changeSectionToListItem(section, newTagName);\n } else if (section.isListItem) {\n return this._changeSectionFromListItem(section, newTagName);\n } else {\n section.tagName = newTagName;\n this._markDirty(section);\n return section;\n }\n }\n\n /**\n * Splits the item at the position given.\n * If the position is at the start or end of the item, the pre- or post-item\n * will contain a single empty (\"\") marker.\n * @param {ListItem} item\n * @param {Position} position\n * @return {Array} the pre-item and post-item on either side of the split\n * @private\n */\n }, {\n key: '_splitListItem',\n value: function _splitListItem(item, position) {\n var section = position.section;\n var offset = position.offset;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list item at position that does not include item', item === section);\n\n item.splitMarkerAtOffset(offset);\n var prevMarker = item.markerBeforeOffset(offset);\n var preItem = this.builder.createListItem(),\n postItem = this.builder.createListItem();\n\n var currentItem = preItem;\n item.markers.forEach(function (marker) {\n currentItem.markers.append(marker.clone());\n if (marker === prevMarker) {\n currentItem = postItem;\n }\n });\n this._replaceSection(item, [preItem, postItem]);\n return [preItem, postItem];\n }\n\n /**\n * Splits the list at the position given.\n * @return {Array} pre-split list and post-split list, either of which could\n * be blank (0-item list) if the position is at the start or end of the list.\n *\n * Note: Contiguous list sections will be joined in the before_complete queue\n * of the postEditor.\n *\n * @private\n */\n }, {\n key: '_splitListAtPosition',\n value: function _splitListAtPosition(list, position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at position not in list', position.section.parent === list);\n\n var positionIsMiddle = !position.isHead() && !position.isTail();\n if (positionIsMiddle) {\n var item = position.section;\n\n var _splitListItem3 = this._splitListItem(item, position);\n\n var _splitListItem32 = _slicedToArray(_splitListItem3, 1);\n\n var pre = _splitListItem32[0];\n\n position = pre.tailPosition();\n }\n\n var preList = this.builder.createListSection(list.tagName);\n var postList = this.builder.createListSection(list.tagName);\n\n var preItem = position.section;\n var currentList = preList;\n list.items.forEach(function (item) {\n // If this item matches the start item and the position is at its start,\n // it should be appended to the postList instead of the preList\n if (item === preItem && position.isEqual(item.headPosition())) {\n currentList = postList;\n }\n currentList.items.append(item.clone());\n // If we just appended the preItem, append the remaining items to the postList\n if (item === preItem) {\n currentList = postList;\n }\n });\n\n this._replaceSection(list, [preList, postList]);\n return [preList, postList];\n }\n\n /**\n * @return Array of [prev, mid, next] lists. `prev` and `next` can\n * be blank, depending on the position of `item`. `mid` will always\n * be a 1-item list containing `item`. `prev` and `next` will be\n * removed in the before_complete queue if they are blank\n * (and still attached).\n *\n * @private\n */\n }, {\n key: '_splitListAtItem',\n value: function _splitListAtItem(list, item) {\n var _this15 = this;\n\n var next = list;\n var prev = this.builder.createListSection(next.tagName, [], next.attributes);\n var mid = this.builder.createListSection(next.tagName);\n\n var addToPrev = true;\n // must turn the LinkedList into an array so that we can remove items\n // as we iterate through it\n var items = next.items.toArray();\n items.forEach(function (i) {\n var listToAppend = undefined;\n if (i === item) {\n addToPrev = false;\n listToAppend = mid;\n } else if (addToPrev) {\n listToAppend = prev;\n } else {\n return; // break after iterating prev and mid parts of the list\n }\n listToAppend.join(i);\n _this15.removeSection(i);\n });\n var found = !addToPrev;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split list at item that is not present in the list', found);\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, mid, next);\n this.insertSectionBefore(collection, prev, mid);\n\n // Remove possibly blank prev/next lists\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n [prev, next].forEach(function (_list) {\n var isAttached = !!_list.parent;\n if (_list.isBlank && isAttached) {\n _this15.removeSection(_list);\n }\n });\n });\n\n return [prev, mid, next];\n }\n }, {\n key: '_changeSectionFromListItem',\n value: function _changeSectionFromListItem(section, newTagName) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass list item to `_changeSectionFromListItem`', section.isListItem);\n\n var listSection = section.parent;\n var markupSection = this.builder.createMarkupSection(newTagName);\n markupSection.join(section);\n\n var _splitListAtItem2 = this._splitListAtItem(listSection, section);\n\n var _splitListAtItem22 = _slicedToArray(_splitListAtItem2, 2);\n\n var mid = _splitListAtItem22[1];\n\n this.replaceSection(mid, markupSection);\n return markupSection;\n }\n }, {\n key: '_changeSectionToListItem',\n value: function _changeSectionToListItem(section, newTagName) {\n var isAlreadyCorrectListItem = section.isListItem && section.parent.tagName === newTagName;\n\n if (isAlreadyCorrectListItem) {\n return section;\n }\n\n var listSection = this.builder.createListSection(newTagName);\n listSection.join(section);\n\n var sectionToReplace = undefined;\n if (section.isListItem) {\n var _splitListAtItem3 = this._splitListAtItem(section.parent, section);\n\n var _splitListAtItem32 = _slicedToArray(_splitListAtItem3, 2);\n\n var mid = _splitListAtItem32[1];\n\n sectionToReplace = mid;\n } else {\n sectionToReplace = section;\n }\n this.replaceSection(sectionToReplace, listSection);\n return listSection;\n }\n\n /**\n * Insert a given section before another one, updating the post abstract\n * and the rendered UI.\n *\n * Usage:\n * ```\n * let markerRange = editor.range;\n * let sectionWithCursor = markerRange.headMarker.section;\n * let section = editor.builder.createCardSection('my-image');\n * let collection = sectionWithCursor.parent.sections;\n * editor.run((postEditor) => {\n * postEditor.insertSectionBefore(collection, section, sectionWithCursor);\n * });\n * ```\n * @param {LinkedList} collection The list of sections to insert into\n * @param {Object} section The new section\n * @param {Object} beforeSection Optional The section \"before\" is relative to,\n * if falsy the new section will be appended to the collection\n * @public\n */\n }, {\n key: 'insertSectionBefore',\n value: function insertSectionBefore(collection, section, beforeSection) {\n collection.insertBefore(section, beforeSection);\n this._markDirty(section.parent);\n }\n\n /**\n * Insert the given section after the current active section, or, if no\n * section is active, at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSection',\n value: function insertSection(section) {\n var activeSection = this.editor.activeSection;\n var nextSection = activeSection && activeSection.next;\n\n var collection = this.editor.post.sections;\n this.insertSectionBefore(collection, section, nextSection);\n }\n\n /**\n * Insert the given section at the end of the document.\n * @param {Section} section\n * @public\n */\n }, {\n key: 'insertSectionAtEnd',\n value: function insertSectionAtEnd(section) {\n this.insertSectionBefore(this.editor.post.sections, section, null);\n }\n\n /**\n * Insert the `post` at the given position in the editor's post.\n * @param {Position} position\n * @param {Post} post\n * @private\n */\n }, {\n key: 'insertPost',\n value: function insertPost(position, newPost) {\n var post = this.editor.post;\n var inserter = new _mobiledocKitEditorPostPostInserter['default'](this, post);\n var nextPosition = inserter.insert(position, newPost);\n return nextPosition;\n }\n\n /**\n * Remove a given section from the post abstract and the rendered UI.\n *\n * Usage:\n * ```\n * let { range } = editor;\n * let sectionWithCursor = range.head.section;\n * editor.run((postEditor) => {\n * postEditor.removeSection(sectionWithCursor);\n * });\n * ```\n * @param {Object} section The section to remove\n * @public\n */\n }, {\n key: 'removeSection',\n value: function removeSection(section) {\n var parent = section.parent;\n this._scheduleForRemoval(section);\n parent.sections.remove(section);\n\n if (parent.isListSection) {\n this._scheduleListRemovalIfEmpty(parent);\n }\n }\n }, {\n key: 'removeAllSections',\n value: function removeAllSections() {\n var _this16 = this;\n\n this.editor.post.sections.toArray().forEach(function (section) {\n _this16.removeSection(section);\n });\n }\n }, {\n key: 'migrateSectionsFromPost',\n value: function migrateSectionsFromPost(post) {\n var _this17 = this;\n\n post.sections.toArray().forEach(function (section) {\n post.sections.remove(section);\n _this17.insertSectionBefore(_this17.editor.post.sections, section, null);\n });\n }\n }, {\n key: '_scheduleListRemovalIfEmpty',\n value: function _scheduleListRemovalIfEmpty(listSection) {\n var _this18 = this;\n\n this.addCallback(CALLBACK_QUEUES.BEFORE_COMPLETE, function () {\n // if the list is attached and blank after we do other rendering stuff,\n // remove it\n var isAttached = !!listSection.parent;\n if (isAttached && listSection.isBlank) {\n _this18.removeSection(listSection);\n }\n });\n }\n\n /**\n * A method for adding work the deferred queue\n *\n * @param {Function} callback to run during completion\n * @param {Boolean} [once=false] Whether to only schedule the callback once.\n * @public\n */\n }, {\n key: 'schedule',\n value: function schedule(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Work can only be scheduled before a post edit has completed', !this._didComplete);\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.COMPLETE, callback);\n }\n }\n\n /**\n * A method for adding work the deferred queue. The callback will only\n * be added to the queue once, even if `scheduleOnce` is called multiple times.\n * The function cannot be an anonymous function.\n *\n * @param {Function} callback to run during completion\n * @public\n */\n }, {\n key: 'scheduleOnce',\n value: function scheduleOnce(callback) {\n this.schedule(callback, true);\n }\n\n /**\n * Add a rerender job to the queue\n *\n * @public\n */\n }, {\n key: 'scheduleRerender',\n value: function scheduleRerender() {\n this.scheduleOnce(this._rerender);\n }\n\n /**\n * Schedule a notification that the post has been changed.\n * The notification will result in the editor firing its `postDidChange`\n * hook after the postEditor completes its work (at the end of {@link Editor#run}).\n *\n * @public\n */\n }, {\n key: 'scheduleDidUpdate',\n value: function scheduleDidUpdate() {\n this.scheduleOnce(this._postDidChange);\n }\n }, {\n key: 'scheduleAfterRender',\n value: function scheduleAfterRender(callback) {\n var once = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (once) {\n this.addCallbackOnce(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n } else {\n this.addCallback(CALLBACK_QUEUES.AFTER_COMPLETE, callback);\n }\n }\n\n /**\n * Flush any work on the queue. {@link Editor#run} calls this method; it\n * should not be called directly.\n *\n * @private\n */\n }, {\n key: 'complete',\n value: function complete() {\n (0, _mobiledocKitUtilsAssert['default'])('Post editing can only be completed once', !this._didComplete);\n\n this.runCallbacks(CALLBACK_QUEUES.BEFORE_COMPLETE);\n this._didComplete = true;\n this.runCallbacks(CALLBACK_QUEUES.COMPLETE);\n this.runCallbacks(CALLBACK_QUEUES.AFTER_COMPLETE);\n }\n }, {\n key: 'undoLastChange',\n value: function undoLastChange() {\n this.editor._editHistory.stepBackward(this);\n }\n }, {\n key: 'redoLastChange',\n value: function redoLastChange() {\n this.editor._editHistory.stepForward(this);\n }\n }, {\n key: 'cancelSnapshot',\n value: function cancelSnapshot() {\n this._shouldCancelSnapshot = true;\n }\n }]);\n\n return PostEditor;\n })();\n\n exports['default'] = PostEditor;\n});","define('mobiledoc-kit/editor/post/post-inserter', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MARKERABLE = 'markerable',\n NESTED_MARKERABLE = 'nested_markerable',\n NON_MARKERABLE = 'non_markerable';\n\n var Visitor = (function () {\n function Visitor(inserter, cursorPosition) {\n _classCallCheck(this, Visitor);\n\n var postEditor = inserter.postEditor;\n var post = inserter.post;\n\n this.postEditor = postEditor;\n this._post = post;\n this.cursorPosition = cursorPosition;\n this.builder = this.postEditor.builder;\n\n this._hasInsertedFirstLeafSection = false;\n }\n\n _createClass(Visitor, [{\n key: 'visit',\n value: function visit(node) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit node of type ' + node.type, !!this[method]);\n this[method](node);\n }\n }, {\n key: '_canMergeSection',\n value: function _canMergeSection(section) {\n if (this._hasInsertedFirstLeafSection) {\n return false;\n } else {\n return this._isMarkerable && section.isMarkerable;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(node) {\n var _this = this;\n\n if (this.cursorSection.isBlank && !this._isNested) {\n // replace blank section with entire post\n var newSections = node.sections.map(function (s) {\n return s.clone();\n });\n this._replaceSection(this.cursorSection, newSections);\n } else {\n node.sections.forEach(function (section) {\n return _this.visit(section);\n });\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(node) {\n this[MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(node) {\n var _this2 = this;\n\n var hasNext = !!node.next;\n node.items.forEach(function (item) {\n return _this2.visit(item);\n });\n\n if (this._isNested && hasNext) {\n this._breakNestedAtCursor();\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(node) {\n this[NESTED_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(node) {\n this[NON_MARKERABLE](node);\n }\n }, {\n key: NON_MARKERABLE,\n value: function value(section) {\n if (this._isNested) {\n this._breakNestedAtCursor();\n } else if (!this.cursorSection.isBlank) {\n this._breakAtCursor();\n }\n\n this._insertLeafSection(section);\n }\n }, {\n key: MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n } else if (this._isNested && this._isMarkerable) {\n // If we are attaching a markerable section to a list item,\n // insert a linebreak then merge the section onto the resulting blank list item\n this._breakAtCursor();\n\n // Advance the cursor to the head of the blank list item\n var nextPosition = this.cursorSection.next.headPosition();\n this.cursorPosition = nextPosition;\n\n // Merge this section onto the list item\n this._mergeSection(section);\n } else {\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n }\n }, {\n key: NESTED_MARKERABLE,\n value: function value(section) {\n if (this._canMergeSection(section)) {\n this._mergeSection(section);\n return;\n }\n\n section = this._isNested ? section : this._wrapNestedSection(section);\n this._breakAtCursor();\n this._insertLeafSection(section);\n }\n\n // break out of a nested cursor position\n }, {\n key: '_breakNestedAtCursor',\n value: function _breakNestedAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call _breakNestedAtCursor if not nested', this._isNested);\n\n var parent = this.cursorSection.parent;\n var cursorAtEndOfList = this.cursorPosition.isEqual(parent.tailPosition());\n\n if (cursorAtEndOfList) {\n var blank = this.builder.createMarkupSection();\n this._insertSectionAfter(blank, parent);\n } else {\n var _breakListAtCursor2 = this._breakListAtCursor();\n\n var _breakListAtCursor22 = _slicedToArray(_breakListAtCursor2, 2);\n\n var blank = _breakListAtCursor22[1];\n\n this.cursorPosition = blank.tailPosition();\n }\n }\n }, {\n key: '_breakListAtCursor',\n value: function _breakListAtCursor() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _splitParentSection if cursor position is not nested', this._isNested);\n\n var list = this.cursorSection.parent,\n position = this.cursorPosition,\n blank = this.builder.createMarkupSection();\n\n var _postEditor$_splitListAtPosition = this.postEditor._splitListAtPosition(list, position);\n\n var _postEditor$_splitListAtPosition2 = _slicedToArray(_postEditor$_splitListAtPosition, 2);\n\n var pre = _postEditor$_splitListAtPosition2[0];\n var post = _postEditor$_splitListAtPosition2[1];\n\n var collection = this._post.sections,\n reference = post;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n return [pre, blank, post];\n }\n }, {\n key: '_wrapNestedSection',\n value: function _wrapNestedSection(section) {\n var tagName = section.parent.tagName;\n var parent = this.builder.createListSection(tagName);\n parent.items.append(section.clone());\n return parent;\n }\n }, {\n key: '_mergeSection',\n value: function _mergeSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only merge markerable sections', this._isMarkerable && section.isMarkerable);\n this._hasInsertedFirstLeafSection = true;\n\n var markers = section.markers.map(function (m) {\n return m.clone();\n });\n var position = this.postEditor.insertMarkers(this.cursorPosition, markers);\n\n this.cursorPosition = position;\n }\n\n // Can be called to add a line break when in a nested section or a parent\n // section.\n }, {\n key: '_breakAtCursor',\n value: function _breakAtCursor() {\n if (this.cursorSection.isBlank) {\n return;\n } else if (this._isMarkerable) {\n this._breakMarkerableAtCursor();\n } else {\n this._breakNonMarkerableAtCursor();\n }\n }\n\n // Inserts a blank section before/after the cursor,\n // depending on cursor position.\n }, {\n key: '_breakNonMarkerableAtCursor',\n value: function _breakNonMarkerableAtCursor() {\n var collection = this._post.sections,\n blank = this.builder.createMarkupSection(),\n reference = this.cursorPosition.isHead() ? this.cursorSection : this.cursorSection.next;\n this.postEditor.insertSectionBefore(collection, blank, reference);\n this.cursorPosition = blank.tailPosition();\n }\n }, {\n key: '_breakMarkerableAtCursor',\n value: function _breakMarkerableAtCursor() {\n var _postEditor$splitSection = this.postEditor.splitSection(this.cursorPosition);\n\n var _postEditor$splitSection2 = _slicedToArray(_postEditor$splitSection, 1);\n\n var pre = _postEditor$splitSection2[0];\n\n this.cursorPosition = pre.tailPosition();\n }\n }, {\n key: '_replaceSection',\n value: function _replaceSection(section, newSections) {\n var _this3 = this;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot replace section that does not have parent.sections', section.parent && section.parent.sections);\n (0, _mobiledocKitUtilsAssert['default'])('Must pass enumerable to _replaceSection', !!newSections.forEach);\n\n var collection = section.parent.sections;\n var reference = section.next;\n this.postEditor.removeSection(section);\n newSections.forEach(function (section) {\n _this3.postEditor.insertSectionBefore(collection, section, reference);\n });\n var lastSection = newSections[newSections.length - 1];\n\n this.cursorPosition = lastSection.tailPosition();\n }\n }, {\n key: '_insertSectionBefore',\n value: function _insertSectionBefore(section, reference) {\n var collection = this.cursorSection.parent.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n\n this.cursorPosition = section.tailPosition();\n }\n\n // Insert a section after the parent section.\n // E.g., add a markup section after a list section\n }, {\n key: '_insertSectionAfter',\n value: function _insertSectionAfter(section, parent) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot _insertSectionAfter nested section', !parent.isNested);\n var reference = parent.next;\n var collection = this._post.sections;\n this.postEditor.insertSectionBefore(collection, section, reference);\n this.cursorPosition = section.tailPosition();\n }\n }, {\n key: '_insertLeafSection',\n value: function _insertLeafSection(section) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only _insertLeafSection when cursor is at end of section', this.cursorPosition.isTail());\n\n this._hasInsertedFirstLeafSection = true;\n section = section.clone();\n\n if (this.cursorSection.isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert leaf non-markerable section when cursor is nested', !(section.isMarkerable && this._isNested));\n this._replaceSection(this.cursorSection, [section]);\n } else if (this.cursorSection.next && this.cursorSection.next.isBlank) {\n this._replaceSection(this.cursorSection.next, [section]);\n } else {\n var reference = this.cursorSection.next;\n this._insertSectionBefore(section, reference);\n }\n }\n }, {\n key: 'cursorPosition',\n get: function get() {\n return this._cursorPosition;\n },\n set: function set(position) {\n this._cursorPosition = position;\n this.postEditor.setRange(position);\n }\n }, {\n key: '_isMarkerable',\n get: function get() {\n return this.cursorSection.isMarkerable;\n }\n }, {\n key: 'cursorSection',\n get: function get() {\n return this.cursorPosition.section;\n }\n }, {\n key: 'cursorOffset',\n get: function get() {\n return this.cursorPosition.offset;\n }\n }, {\n key: '_isNested',\n get: function get() {\n return this.cursorSection.isNested;\n }\n }]);\n\n return Visitor;\n })();\n\n var Inserter = (function () {\n function Inserter(postEditor, post) {\n _classCallCheck(this, Inserter);\n\n this.postEditor = postEditor;\n this.post = post;\n }\n\n _createClass(Inserter, [{\n key: 'insert',\n value: function insert(cursorPosition, newPost) {\n var visitor = new Visitor(this, cursorPosition);\n if (!newPost.isBlank) {\n visitor.visit(newPost);\n }\n return visitor.cursorPosition;\n }\n }]);\n\n return Inserter;\n })();\n\n exports['default'] = Inserter;\n});","define(\"mobiledoc-kit/editor/selection-change-observer\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var instance = undefined;\n\n var SelectionChangeObserver = (function () {\n function SelectionChangeObserver() {\n _classCallCheck(this, SelectionChangeObserver);\n\n this.started = false;\n this.listeners = [];\n this.selection = {};\n }\n\n _createClass(SelectionChangeObserver, [{\n key: \"addListener\",\n value: function addListener(listener) {\n if (this.listeners.indexOf(listener) === -1) {\n this.listeners.push(listener);\n this.start();\n }\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n var index = this.listeners.indexOf(listener);\n if (index !== -1) {\n this.listeners.splice(index, 1);\n if (this.listeners.length === 0) {\n this.stop();\n }\n }\n }\n }, {\n key: \"start\",\n value: function start() {\n if (this.started) {\n return;\n }\n this.started = true;\n\n this.poll();\n }\n }, {\n key: \"stop\",\n value: function stop() {\n this.started = false;\n this.selection = {};\n }\n }, {\n key: \"notifyListeners\",\n value: function notifyListeners() /* newSelection, prevSelection */{\n var _arguments = arguments;\n\n this.listeners.forEach(function (listener) {\n listener.selectionDidChange.apply(listener, _arguments);\n });\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.stop();\n this.listeners = [];\n }\n }, {\n key: \"getSelection\",\n value: function getSelection() {\n var selection = window.getSelection();\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n return { anchorNode: anchorNode, focusNode: focusNode, anchorOffset: anchorOffset, focusOffset: focusOffset };\n }\n }, {\n key: \"poll\",\n value: function poll() {\n var _this = this;\n\n if (this.started) {\n this.update();\n this.runNext(function () {\n return _this.poll();\n });\n }\n }\n }, {\n key: \"runNext\",\n value: function runNext(fn) {\n window.requestAnimationFrame(fn);\n }\n }, {\n key: \"update\",\n value: function update() {\n var prevSelection = this.selection;\n var curSelection = this.getSelection();\n if (!this.selectionIsEqual(prevSelection, curSelection)) {\n this.selection = curSelection;\n this.notifyListeners(curSelection, prevSelection);\n }\n }\n }, {\n key: \"selectionIsEqual\",\n value: function selectionIsEqual(s1, s2) {\n return s1.anchorNode === s2.anchorNode && s1.anchorOffset === s2.anchorOffset && s1.focusNode === s2.focusNode && s1.focusOffset === s2.focusOffset;\n }\n }], [{\n key: \"getInstance\",\n value: function getInstance() {\n if (!instance) {\n instance = new SelectionChangeObserver();\n }\n return instance;\n }\n }, {\n key: \"addListener\",\n value: function addListener(listener) {\n SelectionChangeObserver.getInstance().addListener(listener);\n }\n }, {\n key: \"removeListener\",\n value: function removeListener(listener) {\n SelectionChangeObserver.getInstance().removeListener(listener);\n }\n }]);\n\n return SelectionChangeObserver;\n })();\n\n exports[\"default\"] = SelectionChangeObserver;\n});","define('mobiledoc-kit/editor/selection-manager', ['exports', 'mobiledoc-kit/editor/selection-change-observer'], function (exports, _mobiledocKitEditorSelectionChangeObserver) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SelectionManager = (function () {\n function SelectionManager(editor, callback) {\n _classCallCheck(this, SelectionManager);\n\n this.editor = editor;\n this.callback = callback;\n this.started = false;\n }\n\n _createClass(SelectionManager, [{\n key: 'start',\n value: function start() {\n if (this.started) {\n return;\n }\n\n _mobiledocKitEditorSelectionChangeObserver['default'].addListener(this);\n this.started = true;\n }\n }, {\n key: 'stop',\n value: function stop() {\n this.started = false;\n _mobiledocKitEditorSelectionChangeObserver['default'].removeListener(this);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.stop();\n }\n }, {\n key: 'selectionDidChange',\n value: function selectionDidChange() {\n if (this.started) {\n this.callback.apply(this, arguments);\n }\n }\n }]);\n\n return SelectionManager;\n })();\n\n exports['default'] = SelectionManager;\n});","define('mobiledoc-kit/editor/text-input-handler', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/deprecate', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsDeprecate, _mobiledocKitUtilsCharacters) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var TextInputHandler = (function () {\n function TextInputHandler(editor) {\n _classCallCheck(this, TextInputHandler);\n\n this.editor = editor;\n this._handlers = [];\n }\n\n _createClass(TextInputHandler, [{\n key: 'register',\n value: function register(handler) {\n (0, _mobiledocKitUtilsAssert['default'])('Input Handler is not valid', this._validateHandler(handler));\n this._handlers.push(handler);\n }\n }, {\n key: 'unregister',\n value: function unregister(name) {\n var handlers = this._handlers;\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i].name === name) {\n handlers.splice(i, 1);\n }\n }\n }\n }, {\n key: 'handle',\n value: function handle(string) {\n var editor = this.editor;\n\n editor.insertText(string);\n\n var matchedHandler = this._findHandler();\n if (matchedHandler) {\n var _matchedHandler = _slicedToArray(matchedHandler, 2);\n\n var handler = _matchedHandler[0];\n var matches = _matchedHandler[1];\n\n handler.run(editor, matches);\n }\n }\n }, {\n key: 'handleNewLine',\n value: function handleNewLine() {\n var editor = this.editor;\n\n var matchedHandler = this._findHandler(_mobiledocKitUtilsCharacters.ENTER);\n if (matchedHandler) {\n var _matchedHandler2 = _slicedToArray(matchedHandler, 2);\n\n var handler = _matchedHandler2[0];\n var matches = _matchedHandler2[1];\n\n handler.run(editor, matches);\n }\n }\n }, {\n key: '_findHandler',\n value: function _findHandler() {\n var string = arguments.length <= 0 || arguments[0] === undefined ? \"\" : arguments[0];\n var _editor$range = this.editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n var preText = section.textUntil(head) + string;\n\n for (var i = 0; i < this._handlers.length; i++) {\n var handler = this._handlers[i];\n var text = handler.text;\n var match = handler.match;\n\n if (text && (0, _mobiledocKitUtilsStringUtils.endsWith)(preText, text)) {\n return [handler, [text]];\n } else if (match && match.test(preText)) {\n return [handler, match.exec(preText)];\n }\n }\n }\n }, {\n key: '_validateHandler',\n value: function _validateHandler(handler) {\n (0, _mobiledocKitUtilsDeprecate['default'])('Registered input handlers require a \"name\" property so that they can be unregistered', !!handler.name);\n return !!handler.run && ( // has `run`\n !!handler.text || !!handler.match) && // and `text` or `match`\n !(!!handler.text && !!handler.match); // not both `text` and `match`\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._handlers = [];\n }\n }]);\n\n return TextInputHandler;\n })();\n\n exports['default'] = TextInputHandler;\n});","define('mobiledoc-kit/editor/text-input-handlers', ['exports'], function (exports) {\n /**\n * Convert section at the editor's cursor position into a list.\n * Does nothing if the cursor position is not at the start of the section,\n * or if the section is already a list item.\n *\n * @param {Editor} editor\n * @param {String} listTagName (\"ul\" or \"ol\")\n * @public\n */\n 'use strict';\n\n exports.replaceWithListSection = replaceWithListSection;\n exports.replaceWithHeaderSection = replaceWithHeaderSection;\n\n function replaceWithListSection(editor, listTagName) {\n var _editor$range = editor.range;\n var head = _editor$range.head;\n var section = _editor$range.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n if (section.isListItem) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var item = builder.createListItem();\n var listSection = builder.createListSection(listTagName, [item]);\n\n postEditor.replaceSection(section, listSection);\n postEditor.setRange(listSection.headPosition());\n });\n }\n\n /**\n * Convert section at the editor's cursor position into a header section.\n * Does nothing if the cursor position is not at the start of the section.\n *\n * @param {Editor} editor\n * @param {String} headingTagName ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')\n * @public\n */\n\n function replaceWithHeaderSection(editor, headingTagName) {\n var _editor$range2 = editor.range;\n var head = _editor$range2.head;\n var section = _editor$range2.head.section;\n\n // Skip if cursor is not at end of section\n if (!head.isTail()) {\n return;\n }\n\n editor.run(function (postEditor) {\n var builder = postEditor.builder;\n\n var newSection = builder.createMarkupSection(headingTagName);\n postEditor.replaceSection(section, newSection);\n postEditor.setRange(newSection.headPosition());\n });\n }\n\n var DEFAULT_TEXT_INPUT_HANDLERS = [{\n name: 'ul',\n // \"* \" -> ul\n match: /^\\* $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ul');\n }\n }, {\n name: 'ol',\n // \"1\" -> ol, \"1.\" -> ol\n match: /^1\\.? $/,\n run: function run(editor) {\n replaceWithListSection(editor, 'ol');\n }\n }, {\n name: 'heading',\n /*\n * \"# \" -> h1\n * \"## \" -> h2\n * \"### \" -> h3\n * \"#### \" -> h4\n * \"##### \" -> h5\n * \"###### \" -> h6\n */\n match: /^(#{1,6}) $/,\n run: function run(editor, matches) {\n var capture = matches[1];\n var headingTag = 'h' + capture.length;\n replaceWithHeaderSection(editor, headingTag);\n }\n }];\n exports.DEFAULT_TEXT_INPUT_HANDLERS = DEFAULT_TEXT_INPUT_HANDLERS;\n});","define('mobiledoc-kit/editor/ui', ['exports'], function (exports) {\n /**\n * @module UI\n */\n\n /**\n * @callback promptCallback\n * @param {String} url The URL to pass back to the editor for linking\n * to the selected text.\n */\n\n /**\n * @callback showPrompt\n * @param {String} message The text of the prompt.\n * @param {String} defaultValue The initial URL to display in the prompt.\n * @param {module:UI~promptCallback} callback Once your handler has accepted a URL,\n * it should pass it to `callback` so that the editor may link the\n * selected text.\n */\n\n /**\n * Exposes the core behavior for linking and unlinking text, and allows for\n * customization of the URL input handler.\n * @param {Editor} editor An editor instance to operate on. If a range is selected,\n * either prompt for a URL and add a link or un-link the\n * currently linked text.\n * @param {module:UI~showPrompt} [showPrompt] An optional custom input handler. Defaults\n * to using `window.prompt`.\n * @example\n * let myPrompt = (message, defaultURL, promptCallback) => {\n * let url = window.prompt(\"Overriding the defaults\", \"http://placekitten.com\");\n * promptCallback(url);\n * };\n *\n * editor.registerKeyCommand({\n * str: \"META+K\",\n * run(editor) {\n * toggleLink(editor, myPrompt);\n * }\n * });\n * @public\n */\n\n 'use strict';\n\n exports.toggleLink = toggleLink;\n var defaultShowPrompt = function defaultShowPrompt(message, defaultValue, callback) {\n return callback(window.prompt(message, defaultValue));\n };\n\n function toggleLink(editor) {\n var showPrompt = arguments.length <= 1 || arguments[1] === undefined ? defaultShowPrompt : arguments[1];\n\n if (editor.range.isCollapsed) {\n return;\n }\n\n var selectedText = editor.cursor.selectedText();\n var defaultUrl = '';\n if (selectedText.indexOf('http') !== -1) {\n defaultUrl = selectedText;\n }\n\n var range = editor.range;\n\n var hasLink = editor.detectMarkupInRange(range, 'a');\n\n if (hasLink) {\n editor.toggleMarkup('a');\n } else {\n showPrompt('Enter a URL', defaultUrl, function (url) {\n if (!url) {\n return;\n }\n\n editor.toggleMarkup('a', { href: url });\n });\n }\n }\n});","define('mobiledoc-kit', ['exports', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/editor/ui', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/mobiledoc-error', 'mobiledoc-kit/version', 'mobiledoc-kit/renderers/mobiledoc'], function (exports, _mobiledocKitEditorEditor, _mobiledocKitEditorUi, _mobiledocKitCardsImage, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsMobiledocError, _mobiledocKitVersion, _mobiledocKitRenderersMobiledoc) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n var Mobiledoc = {\n Editor: _mobiledocKitEditorEditor['default'],\n UI: _mobiledocKitEditorUi,\n ImageCard: _mobiledocKitCardsImage['default'],\n Range: _mobiledocKitUtilsCursorRange['default'],\n Position: _mobiledocKitUtilsCursorPosition['default'],\n Error: _mobiledocKitUtilsMobiledocError['default'],\n VERSION: _mobiledocKitVersion['default'],\n MOBILEDOC_VERSION: _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION\n };\n\n function registerGlobal(global) {\n global.Mobiledoc = Mobiledoc;\n }\n\n exports.Editor = _mobiledocKitEditorEditor['default'];\n exports.UI = _mobiledocKitEditorUi;\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports.MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n exports['default'] = Mobiledoc;\n});","define('mobiledoc-kit/models/_attributable', ['exports', 'mobiledoc-kit/utils/object-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsObjectUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n exports.attributable = attributable;\n var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n /*\n * A \"mixin\" to add section attribute support\n * to markup and list sections.\n */\n\n function attributable(ctx) {\n ctx.attributes = {};\n\n ctx.hasAttribute = function (key) {\n return key in ctx.attributes;\n };\n\n ctx.setAttribute = function (key, value) {\n if (!(0, _mobiledocKitUtilsArrayUtils.contains)(VALID_ATTRIBUTES, key)) {\n throw new Error('Invalid attribute \"' + key + '\" was passed. Constrain attributes to the spec-compliant whitelist.');\n }\n ctx.attributes[key] = value;\n };\n ctx.removeAttribute = function (key) {\n delete ctx.attributes[key];\n };\n ctx.getAttribute = function (key) {\n return ctx.attributes[key];\n };\n ctx.eachAttribute = function (cb) {\n (0, _mobiledocKitUtilsObjectUtils.entries)(ctx.attributes).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var k = _ref2[0];\n var v = _ref2[1];\n return cb(k, v);\n });\n };\n }\n});","define('mobiledoc-kit/models/_markerable', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsLinkedList, _mobiledocKitModels_section, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Markerable = (function (_Section) {\n _inherits(Markerable, _Section);\n\n function Markerable(type, tagName) {\n var _this = this;\n\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n _classCallCheck(this, Markerable);\n\n _get(Object.getPrototypeOf(Markerable.prototype), 'constructor', this).call(this, type);\n this.isMarkerable = true;\n this.tagName = tagName;\n this.markers = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(m) {\n (0, _mobiledocKitUtilsAssert['default'])('Can only insert markers and atoms into markerable (was: ' + m.type + ')', m.isMarker || m.isAtom);\n m.section = m.parent = _this;\n },\n freeItem: function freeItem(m) {\n return m.section = m.parent = null;\n }\n });\n\n markers.forEach(function (m) {\n return _this.markers.append(m);\n });\n }\n\n _createClass(Markerable, [{\n key: 'canJoin',\n value: function canJoin(other) {\n return other.isMarkerable && other.type === this.type && other.tagName === this.tagName;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newMarkers = this.markers.map(function (m) {\n return m.clone();\n });\n return this.builder.createMarkerableSection(this.type, this.tagName, newMarkers);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(position) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get textUntil for a position not in this section', position.section === this);\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n var text = '';\n var currentMarker = this.markers.head;\n while (currentMarker) {\n if (currentMarker === marker) {\n text += currentMarker.textUntil(offsetInMarker);\n break;\n } else {\n text += currentMarker.text;\n currentMarker = currentMarker.next;\n }\n }\n return text;\n }\n\n /**\n * @param {Marker}\n * @param {Number} markerOffset The offset relative to the start of the marker\n *\n * @return {Number} The offset relative to the start of this section\n */\n }, {\n key: 'offsetOfMarker',\n value: function offsetOfMarker(marker) {\n var markerOffset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get offsetOfMarker for marker that is not child of this', marker.section === this);\n\n // FIXME it is possible, when we get a cursor position before having finished reparsing,\n // for markerOffset to be > marker.length. We shouldn't rely on this functionality.\n\n var offset = 0;\n var currentMarker = this.markers.head;\n while (currentMarker && currentMarker !== marker.next) {\n var _length = currentMarker === marker ? markerOffset : currentMarker.length;\n offset += _length;\n currentMarker = currentMarker.next;\n }\n\n return offset;\n }\n\n // puts clones of this.markers into beforeSection and afterSection,\n // all markers before the marker/offset split go in beforeSection, and all\n // after the marker/offset split go in afterSection\n // @return {Array} [beforeSection, afterSection], two new sections\n }, {\n key: '_redistributeMarkers',\n value: function _redistributeMarkers(beforeSection, afterSection, marker) {\n var offset = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3];\n\n var currentSection = beforeSection;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.markers, function (m) {\n if (m === marker) {\n var _marker$split = marker.split(offset);\n\n var _marker$split2 = _toArray(_marker$split);\n\n var beforeMarker = _marker$split2[0];\n\n var afterMarkers = _marker$split2.slice(1);\n\n beforeSection.markers.append(beforeMarker);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(afterMarkers, function (_m) {\n return afterSection.markers.append(_m);\n });\n currentSection = afterSection;\n } else {\n currentSection.markers.append(m.clone());\n }\n });\n\n return [beforeSection, afterSection];\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker() /*marker, offset=0*/{\n (0, _mobiledocKitUtilsAssert['default'])('splitAtMarker must be implemented by sub-class', false);\n }\n\n /**\n * Split this section's marker (if any) at the given offset, so that\n * there is now a marker boundary at that offset (useful for later applying\n * a markup to a range)\n * @param {Number} sectionOffset The offset relative to start of this section\n * @return {EditObject} An edit object with 'removed' and 'added' keys with arrays of Markers. The added markers may be blank.\n * After calling `splitMarkerAtOffset(offset)`, there will always be a valid\n * result returned from `markerBeforeOffset(offset)`.\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset(sectionOffset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot splitMarkerAtOffset when offset is > length', sectionOffset <= this.length);\n var markerOffset = undefined;\n var len = 0;\n var currentMarker = this.markers.head;\n var edit = { added: [], removed: [] };\n\n if (!currentMarker) {\n var blankMarker = this.builder.createMarker();\n this.markers.prepend(blankMarker);\n edit.added.push(blankMarker);\n } else {\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n // nothing to do, there is a gap at the requested offset\n break;\n } else if (len > sectionOffset) {\n var _edit$added;\n\n markerOffset = currentMarker.length - (len - sectionOffset);\n var newMarkers = currentMarker.splitAtOffset(markerOffset);\n (_edit$added = edit.added).push.apply(_edit$added, _toConsumableArray(newMarkers));\n edit.removed.push(currentMarker);\n this.markers.splice(currentMarker, 1, newMarkers);\n break;\n } else {\n currentMarker = currentMarker.next;\n }\n }\n }\n\n return edit;\n }\n }, {\n key: 'splitAtPosition',\n value: function splitAtPosition(position) {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n return this.splitAtMarker(marker, offsetInMarker);\n }\n\n // returns the marker just before this offset.\n // It is an error to call this method with an offset that is in the middle\n // of a marker.\n }, {\n key: 'markerBeforeOffset',\n value: function markerBeforeOffset(sectionOffset) {\n var len = 0;\n var currentMarker = this.markers.head;\n\n while (currentMarker) {\n len += currentMarker.length;\n if (len === sectionOffset) {\n return currentMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('markerBeforeOffset called with sectionOffset not between markers', len < sectionOffset);\n currentMarker = currentMarker.next;\n }\n }\n }\n }, {\n key: 'markerPositionAtOffset',\n value: function markerPositionAtOffset(offset) {\n var currentOffset = 0;\n var currentMarker = undefined;\n var remaining = offset;\n this.markers.detect(function (marker) {\n currentOffset = Math.min(remaining, marker.length);\n remaining -= currentOffset;\n if (remaining === 0) {\n currentMarker = marker;\n return true; // break out of detect\n }\n });\n\n return { marker: currentMarker, offset: currentOffset };\n }\n }, {\n key: 'markersFor',\n\n /**\n * @return {Array} New markers that match the boundaries of the\n * range. Does not change the existing markers in this section.\n */\n value: function markersFor(headOffset, tailOffset) {\n var range = { head: { section: this, offset: headOffset },\n tail: { section: this, offset: tailOffset } };\n\n var markers = [];\n this._markersInRange(range, function (marker, _ref) {\n var markerHead = _ref.markerHead;\n var markerTail = _ref.markerTail;\n var isContained = _ref.isContained;\n\n var cloned = marker.clone();\n if (!isContained) {\n // cannot do marker.value.slice if the marker is an atom -- this breaks the atom's \"atomic\" value\n // If a marker is an atom `isContained` should always be true so\n // we shouldn't hit this code path. FIXME add tests\n cloned.value = marker.value.slice(markerHead, markerTail);\n }\n markers.push(cloned);\n });\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n this._markersInRange(range, function (marker) {\n marker.markups.forEach(function (m) {\n return markups.add(m);\n });\n });\n return markups.toArray();\n }\n\n // calls the callback with (marker, {markerHead, markerTail, isContained})\n // for each marker that is wholly or partially contained in the range.\n }, {\n key: '_markersInRange',\n value: function _markersInRange(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot call #_markersInRange if range expands beyond this section', head.section === this && tail.section === this);\n var headOffset = head.offset;var tailOffset = tail.offset;\n\n var currentHead = 0,\n currentTail = 0,\n currentMarker = this.markers.head;\n\n while (currentMarker) {\n currentTail += currentMarker.length;\n\n if (currentTail > headOffset && currentHead < tailOffset) {\n var markerHead = Math.max(headOffset - currentHead, 0);\n var markerTail = currentMarker.length - Math.max(currentTail - tailOffset, 0);\n var isContained = markerHead === 0 && markerTail === currentMarker.length;\n\n callback(currentMarker, { markerHead: markerHead, markerTail: markerTail, isContained: isContained });\n }\n\n currentHead += currentMarker.length;\n currentMarker = currentMarker.next;\n\n if (currentHead > tailOffset) {\n break;\n }\n }\n }\n\n // mutates this by appending the other section's (cloned) markers to it\n }, {\n key: 'join',\n value: function join(otherSection) {\n var _this2 = this;\n\n var beforeMarker = this.markers.tail;\n var afterMarker = null;\n\n otherSection.markers.forEach(function (m) {\n if (!m.isBlank) {\n m = m.clone();\n _this2.markers.append(m);\n if (!afterMarker) {\n afterMarker = m;\n }\n }\n });\n\n return { beforeMarker: beforeMarker, afterMarker: afterMarker };\n }\n }, {\n key: 'isBlank',\n get: function get() {\n if (!this.markers.length) {\n return true;\n }\n return this.markers.every(function (m) {\n return m.isBlank;\n });\n }\n }, {\n key: 'text',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.value;\n }, '');\n }\n }, {\n key: 'length',\n get: function get() {\n return (0, _mobiledocKitUtilsArrayUtils.reduce)(this.markers, function (prev, m) {\n return prev + m.length;\n }, 0);\n }\n }]);\n\n return Markerable;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Markerable;\n});","define('mobiledoc-kit/models/_section', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/cursor/position'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCursorPosition) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function unimplementedMethod(methodName, me) {\n (0, _mobiledocKitUtilsAssert['default'])('`' + methodName + '()` must be implemented by ' + me.constructor.name, false);\n }\n\n var Section = (function (_LinkedItem) {\n _inherits(Section, _LinkedItem);\n\n function Section(type) {\n _classCallCheck(this, Section);\n\n _get(Object.getPrototypeOf(Section.prototype), 'constructor', this).call(this);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create section without type', !!type);\n this.type = type;\n this.isSection = true;\n this.isMarkerable = false;\n this.isNested = false;\n this.isSection = true;\n this.isLeafSection = true;\n }\n\n _createClass(Section, [{\n key: 'isValidTagName',\n value: function isValidTagName() /* normalizedTagName */{\n unimplementedMethod('isValidTagName', this);\n }\n }, {\n key: 'clone',\n value: function clone() {\n unimplementedMethod('clone', this);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* otherSection */{\n unimplementedMethod('canJoin', this);\n }\n\n /**\n * @return {Position} The position at the start of this section\n * @public\n */\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.toPosition(0);\n }\n\n /**\n * @return {Position} The position at the end of this section\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.toPosition(this.length);\n }\n\n /**\n * @param {Number} offset\n * @return {Position} The position in this section at the given offset\n * @public\n */\n }, {\n key: 'toPosition',\n value: function toPosition(offset) {\n (0, _mobiledocKitUtilsAssert['default'])(\"Must pass number to `toPosition`\", typeof offset === 'number');\n (0, _mobiledocKitUtilsAssert['default'])(\"Cannot call `toPosition` with offset > length\", offset <= this.length);\n\n return new _mobiledocKitUtilsCursorPosition['default'](this, offset);\n }\n\n /**\n * @return {Range} A range from this section's head to tail positions\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'join',\n value: function join() {\n unimplementedMethod('join', this);\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* position */{\n return '';\n }\n\n /**\n * Markerable sections should override this method\n */\n }, {\n key: 'splitMarkerAtOffset',\n value: function splitMarkerAtOffset() {\n var blankEdit = { added: [], removed: [] };\n return blankEdit;\n }\n }, {\n key: 'nextLeafSection',\n value: function nextLeafSection() {\n var next = this.next;\n if (next) {\n if (next.items) {\n return next.items.head;\n } else {\n return next;\n }\n } else {\n if (this.isNested) {\n return this.parent.nextLeafSection();\n }\n }\n }\n }, {\n key: 'immediatelyNextMarkerableSection',\n value: function immediatelyNextMarkerableSection() {\n var next = this.nextLeafSection();\n while (next && !next.isMarkerable) {\n next = next.nextLeafSection();\n }\n return next;\n }\n }, {\n key: 'previousLeafSection',\n value: function previousLeafSection() {\n var prev = this.prev;\n\n if (prev) {\n if (prev.items) {\n return prev.items.tail;\n } else {\n return prev;\n }\n } else {\n if (this.isNested) {\n return this.parent.previousLeafSection();\n }\n }\n }\n }, {\n key: 'tagName',\n set: function set(val) {\n var normalizedTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(val);\n (0, _mobiledocKitUtilsAssert['default'])('Cannot set section tagName to ' + val, this.isValidTagName(normalizedTagName));\n this._tagName = normalizedTagName;\n },\n get: function get() {\n return this._tagName;\n }\n }, {\n key: 'length',\n get: function get() {\n return 0;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n unimplementedMethod('isBlank', this);\n }\n }]);\n\n return Section;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = Section;\n});","define('mobiledoc-kit/models/atom-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var AtomNode = (function () {\n function AtomNode(editor, atom, model, element, atomOptions) {\n _classCallCheck(this, AtomNode);\n\n this.editor = editor;\n this.atom = atom;\n this.model = model;\n this.atomOptions = atomOptions;\n this.element = element;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(AtomNode, [{\n key: 'render',\n value: function render() {\n if (!this._rendered) {\n var options = this.atomOptions;\n var env = this.env;\n var _model = this.model;\n var value = _model.value;\n var payload = _model.payload;\n\n // cache initial render\n this._rendered = this.atom.render({ options: options, env: env, value: value, payload: payload });\n }\n\n this._validateAndAppendRenderResult(this._rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.atom.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + name + '\" must return a DOM node (returned value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n }\n }, {\n key: 'env',\n get: function get() {\n var _this = this;\n\n return {\n name: this.atom.name,\n onTeardown: function onTeardown(callback) {\n return _this._teardownCallback = callback;\n },\n save: function save(value) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _this.model.value = value;\n _this.model.payload = payload;\n\n _this.editor._postDidChange();\n _this.teardown();\n _this.render();\n }\n };\n }\n }]);\n\n return AtomNode;\n })();\n\n exports['default'] = AtomNode;\n});","define('mobiledoc-kit/models/atom', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var ATOM_LENGTH = 1;\n\n var Atom = (function (_LinkedItem) {\n _inherits(Atom, _LinkedItem);\n\n function Atom(name, value, payload) {\n var _this = this;\n\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n _classCallCheck(this, Atom);\n\n _get(Object.getPrototypeOf(Atom.prototype), 'constructor', this).call(this);\n this.name = name;\n this.value = value;\n this.text = ''; // An atom never has text, but it does have a value\n (0, _mobiledocKitUtilsAssert['default'])('Atom must have value', value !== undefined && value !== null);\n this.payload = payload;\n this.type = _mobiledocKitModelsTypes.ATOM_TYPE;\n this.isMarker = false;\n this.isAtom = true;\n\n this.markups = [];\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Atom, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createAtom(this.name, this.value, this.payload, clonedMarkups);\n }\n }, {\n key: 'canJoin',\n value: function canJoin() /* other */{\n return false;\n }\n }, {\n key: 'textUntil',\n value: function textUntil() /* offset */{\n return '';\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? offset : arguments[1];\n return (function () {\n var markers = [];\n\n if (endOffset === 0) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n markers.push(this.clone());\n\n if (offset === ATOM_LENGTH) {\n markers.push(this.builder.createMarker('', this.markups.slice()));\n }\n\n return markers;\n }).apply(this, arguments);\n }\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n\n var builder = this.builder;\n\n var clone = this.clone();\n var blankMarker = builder.createMarker('');\n var pre = undefined,\n post = undefined;\n\n if (offset === 0) {\n pre = blankMarker;\n post = clone;\n } else if (offset === ATOM_LENGTH) {\n pre = clone;\n post = blankMarker;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Invalid offset given to Atom#splitAtOffset: \"' + offset + '\"', false);\n }\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n return [pre, post];\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return ATOM_LENGTH;\n }\n }]);\n\n return Atom;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Atom, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Atom;\n});","define('mobiledoc-kit/models/card-node', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CardNode = (function () {\n function CardNode(editor, card, section, element, options) {\n _classCallCheck(this, CardNode);\n\n this.editor = editor;\n this.card = card;\n this.section = section;\n this.element = element;\n this.options = options;\n\n this.mode = null;\n\n this._teardownCallback = null;\n this._rendered = null;\n }\n\n _createClass(CardNode, [{\n key: 'render',\n value: function render(mode) {\n if (this.mode === mode) {\n return;\n }\n\n this.teardown();\n\n this.mode = mode;\n\n var method = mode === 'display' ? 'render' : 'edit';\n method = this.card[method];\n\n (0, _mobiledocKitUtilsAssert['default'])('Card is missing \"' + method + '\" (tried to render mode: \"' + mode + '\")', !!method);\n var rendered = method({\n env: this.env,\n options: this.options,\n payload: this.section.payload\n });\n\n this._validateAndAppendRenderResult(rendered);\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n if (this._teardownCallback) {\n this._teardownCallback();\n this._teardownCallback = null;\n }\n if (this._rendered) {\n this.element.removeChild(this._rendered);\n this._rendered = null;\n }\n }\n }, {\n key: 'didRender',\n value: function didRender() {\n if (this._didRenderCallback) {\n this._didRenderCallback();\n }\n }\n }, {\n key: 'display',\n value: function display() {\n this.render('display');\n }\n }, {\n key: 'edit',\n value: function edit() {\n this.render('edit');\n }\n }, {\n key: 'remove',\n value: function remove() {\n var _this = this;\n\n this.editor.run(function (postEditor) {\n return postEditor.removeSection(_this.section);\n });\n }\n }, {\n key: '_validateAndAppendRenderResult',\n value: function _validateAndAppendRenderResult(rendered) {\n if (!rendered) {\n return;\n }\n\n var name = this.card.name;\n\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + name + '\" must render dom (render value was: \"' + rendered + '\")', !!rendered.nodeType);\n this.element.appendChild(rendered);\n this._rendered = rendered;\n this.didRender();\n }\n }, {\n key: 'env',\n get: function get() {\n var _this2 = this;\n\n return {\n name: this.card.name,\n isInEditor: true,\n onTeardown: function onTeardown(callback) {\n return _this2._teardownCallback = callback;\n },\n didRender: function didRender(callback) {\n return _this2._didRenderCallback = callback;\n },\n edit: function edit() {\n return _this2.edit();\n },\n save: function save(payload) {\n var transition = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\n _this2.section.payload = payload;\n\n _this2.editor._postDidChange();\n if (transition) {\n _this2.display();\n }\n },\n cancel: function cancel() {\n return _this2.display();\n },\n remove: function remove() {\n return _this2.remove();\n },\n postModel: this.section\n };\n }\n }]);\n\n return CardNode;\n })();\n\n exports['default'] = CardNode;\n});","define('mobiledoc-kit/models/card', ['exports', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/copy'], function (exports, _mobiledocKitModels_section, _mobiledocKitModelsTypes, _mobiledocKitUtilsCopy) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var CARD_MODES = {\n DISPLAY: 'display',\n EDIT: 'edit'\n };\n\n exports.CARD_MODES = CARD_MODES;\n var CARD_LENGTH = 1;\n\n var DEFAULT_INITIAL_MODE = CARD_MODES.DISPLAY;\n\n var Card = (function (_Section) {\n _inherits(Card, _Section);\n\n function Card(name, payload) {\n _classCallCheck(this, Card);\n\n _get(Object.getPrototypeOf(Card.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.CARD_TYPE);\n this.name = name;\n this.payload = payload;\n this.setInitialMode(DEFAULT_INITIAL_MODE);\n this.isCardSection = true;\n }\n\n _createClass(Card, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'clone',\n value: function clone() {\n var payload = (0, _mobiledocKitUtilsCopy.shallowCopyObject)(this.payload);\n var card = this.builder.createCardSection(this.name, payload);\n // If this card is currently rendered, clone the mode it is\n // currently in as the default mode of the new card.\n var mode = this._initialMode;\n if (this.renderNode && this.renderNode.cardNode) {\n mode = this.renderNode.cardNode.mode;\n }\n card.setInitialMode(mode);\n return card;\n }\n\n /**\n * set the mode that this will be rendered into initially\n * @private\n */\n }, {\n key: 'setInitialMode',\n value: function setInitialMode(initialMode) {\n // TODO validate initialMode\n this._initialMode = initialMode;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return CARD_LENGTH;\n }\n }]);\n\n return Card;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Card;\n});","define('mobiledoc-kit/models/image', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var Image = (function (_Section) {\n _inherits(Image, _Section);\n\n function Image() {\n _classCallCheck(this, Image);\n\n _get(Object.getPrototypeOf(Image.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE);\n this.src = null;\n }\n\n _createClass(Image, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return false;\n }\n }, {\n key: 'length',\n get: function get() {\n return 1;\n }\n }]);\n\n return Image;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = Image;\n});","define('mobiledoc-kit/models/lifecycle-callbacks', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LifecycleCallbacks = (function () {\n function LifecycleCallbacks() {\n var _this = this;\n\n var queueNames = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, LifecycleCallbacks);\n\n this.callbackQueues = {};\n this.removalQueues = {};\n\n queueNames.forEach(function (name) {\n _this.callbackQueues[name] = [];\n _this.removalQueues[name] = [];\n });\n }\n\n _createClass(LifecycleCallbacks, [{\n key: 'runCallbacks',\n value: function runCallbacks(queueName) {\n var args = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var queue = this._getQueue(queueName);\n queue.forEach(function (cb) {\n return cb.apply(undefined, _toConsumableArray(args));\n });\n\n var toRemove = this.removalQueues[queueName];\n toRemove.forEach(function (cb) {\n var index = queue.indexOf(cb);\n if (index !== -1) {\n queue.splice(index, 1);\n }\n });\n\n this.removalQueues[queueName] = [];\n }\n }, {\n key: 'addCallback',\n value: function addCallback(queueName, callback) {\n this._getQueue(queueName).push(callback);\n }\n }, {\n key: '_scheduleCallbackForRemoval',\n value: function _scheduleCallbackForRemoval(queueName, callback) {\n this.removalQueues[queueName].push(callback);\n }\n }, {\n key: 'addCallbackOnce',\n value: function addCallbackOnce(queueName, callback) {\n var queue = this._getQueue(queueName);\n if (queue.indexOf(callback) === -1) {\n queue.push(callback);\n this._scheduleCallbackForRemoval(queueName, callback);\n }\n }\n }, {\n key: '_getQueue',\n value: function _getQueue(queueName) {\n var queue = this.callbackQueues[queueName];\n (0, _mobiledocKitUtilsAssert['default'])('No queue found for \"' + queueName + '\"', !!queue);\n return queue;\n }\n }]);\n\n return LifecycleCallbacks;\n })();\n\n exports['default'] = LifecycleCallbacks;\n});","define('mobiledoc-kit/models/list-item', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_ITEM_TAGNAMES = ['li'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_ITEM_TAGNAMES = VALID_LIST_ITEM_TAGNAMES;\n\n var ListItem = (function (_Markerable) {\n _inherits(ListItem, _Markerable);\n\n function ListItem(tagName) {\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, ListItem);\n\n _get(Object.getPrototypeOf(ListItem.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, tagName, markers);\n this.isListItem = true;\n this.isNested = true;\n }\n\n _createClass(ListItem, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_ITEM_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n\n // FIXME need to check if we are going to split into two list items\n // or a list item and a new markup section:\n var isLastItem = !this.next;\n var createNewSection = !marker && offset === 0 && isLastItem;\n\n var beforeSection = this.builder.createListItem();\n var afterSection = createNewSection ? this.builder.createMarkupSection() : this.builder.createListItem();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }, {\n key: 'post',\n get: function get() {\n return this.section.post;\n }\n }]);\n\n return ListItem;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = ListItem;\n});","define('mobiledoc-kit/models/list-section', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/_section', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitModels_section, _mobiledocKitModels_attributable, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var VALID_LIST_SECTION_TAGNAMES = ['ul', 'ol'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_LIST_SECTION_TAGNAMES = VALID_LIST_SECTION_TAGNAMES;\n var DEFAULT_TAG_NAME = VALID_LIST_SECTION_TAGNAMES[0];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n\n var ListSection = (function (_Section) {\n _inherits(ListSection, _Section);\n\n function ListSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n\n var _this = this;\n\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n _classCallCheck(this, ListSection);\n\n _get(Object.getPrototypeOf(ListSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.LIST_SECTION_TYPE);\n this.tagName = tagName;\n this.isListSection = true;\n this.isLeafSection = false;\n\n (0, _mobiledocKitModels_attributable.attributable)(this);\n (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var k = _ref2[0];\n var v = _ref2[1];\n return _this.setAttribute(k, v);\n });\n\n this.items = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(i) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert non-list-item to list (is: ' + i.type + ')', i.isListItem);\n i.section = i.parent = _this;\n },\n freeItem: function freeItem(i) {\n return i.section = i.parent = null;\n }\n });\n this.sections = this.items;\n\n items.forEach(function (i) {\n return _this.items.append(i);\n });\n }\n\n _createClass(ListSection, [{\n key: 'canJoin',\n value: function canJoin() {\n return false;\n }\n }, {\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_LIST_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'headPosition',\n value: function headPosition() {\n return this.items.head.headPosition();\n }\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n return this.items.tail.tailPosition();\n }\n }, {\n key: 'clone',\n value: function clone() {\n var newSection = this.builder.createListSection(this.tagName);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(this.items, function (i) {\n return newSection.items.append(i.clone());\n });\n return newSection;\n }\n\n /**\n * Mutates this list\n * @param {ListSection|Markerable}\n * @return null\n */\n }, {\n key: 'join',\n value: function join(other) {\n var _this2 = this;\n\n if (other.isListSection) {\n other.items.forEach(function (i) {\n return _this2.join(i);\n });\n } else if (other.isMarkerable) {\n var item = this.builder.createListItem();\n item.join(other);\n this.items.append(item);\n }\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.items.isEmpty;\n }\n }]);\n\n return ListSection;\n })(_mobiledocKitModels_section['default']);\n\n exports['default'] = ListSection;\n});","define('mobiledoc-kit/models/marker', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/mixin', 'mobiledoc-kit/utils/markuperable', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsMixin, _mobiledocKitUtilsMarkuperable, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsAssert, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // Unicode uses a pair of \"surrogate\" characters\" (a high- and low-surrogate)\n // to encode characters outside the basic multilingual plane (like emoji and\n // some languages).\n // These values are the unicode code points for the start and end of the\n // high- and low-surrogate characters.\n // See \"high surrogate\" and \"low surrogate\" on\n // https://en.wikipedia.org/wiki/Unicode_block\n var HIGH_SURROGATE_RANGE = [0xD800, 0xDBFF];\n exports.HIGH_SURROGATE_RANGE = HIGH_SURROGATE_RANGE;\n var LOW_SURROGATE_RANGE = [0xDC00, 0xDFFF];\n\n exports.LOW_SURROGATE_RANGE = LOW_SURROGATE_RANGE;\n var Marker = (function (_LinkedItem) {\n _inherits(Marker, _LinkedItem);\n\n function Marker() {\n var _this = this;\n\n var value = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n _classCallCheck(this, Marker);\n\n _get(Object.getPrototypeOf(Marker.prototype), 'constructor', this).call(this);\n this.value = value;\n (0, _mobiledocKitUtilsAssert['default'])('Marker must have value', value !== undefined && value !== null);\n this.markups = [];\n this.type = _mobiledocKitModelsTypes.MARKER_TYPE;\n this.isMarker = true;\n this.isAtom = false;\n markups.forEach(function (m) {\n return _this.addMarkup(m);\n });\n }\n\n _createClass(Marker, [{\n key: 'clone',\n value: function clone() {\n var clonedMarkups = this.markups.slice();\n return this.builder.createMarker(this.value, clonedMarkups);\n }\n }, {\n key: 'charAt',\n value: function charAt(offset) {\n return this.value.slice(offset, offset + 1);\n }\n\n /**\n * A marker's text is equal to its value.\n * Compare with an Atom which distinguishes between text and value\n */\n }, {\n key: 'deleteValueAtOffset',\n\n // delete the character at this offset,\n // update the value with the new value\n value: function deleteValueAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot delete value at offset outside bounds', offset >= 0 && offset <= this.length);\n\n var width = 1;\n var code = this.value.charCodeAt(offset);\n if (code >= HIGH_SURROGATE_RANGE[0] && code <= HIGH_SURROGATE_RANGE[1]) {\n width = 2;\n } else if (code >= LOW_SURROGATE_RANGE[0] && code <= LOW_SURROGATE_RANGE[1]) {\n width = 2;\n offset = offset - 1;\n }\n\n var left = this.value.slice(0, offset);\n var right = this.value.slice(offset + width);\n\n this.value = left + right;\n\n return width;\n }\n }, {\n key: 'canJoin',\n value: function canJoin(other) {\n return other && other.isMarker && (0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(this.markups, other.markups);\n }\n }, {\n key: 'textUntil',\n value: function textUntil(offset) {\n return this.value.slice(0, offset);\n }\n }, {\n key: 'split',\n value: function split() {\n var offset = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n var endOffset = arguments.length <= 1 || arguments[1] === undefined ? this.length : arguments[1];\n\n var markers = [this.builder.createMarker(this.value.substring(0, offset)), this.builder.createMarker(this.value.substring(offset, endOffset)), this.builder.createMarker(this.value.substring(endOffset))];\n\n this.markups.forEach(function (mu) {\n return markers.forEach(function (m) {\n return m.addMarkup(mu);\n });\n });\n return markers;\n }\n\n /**\n * @return {Array} 2 markers either or both of which could be blank\n */\n }, {\n key: 'splitAtOffset',\n value: function splitAtOffset(offset) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot split a marker at an offset > its length', offset <= this.length);\n var value = this.value;\n var builder = this.builder;\n\n var pre = builder.createMarker(value.substring(0, offset));\n var post = builder.createMarker(value.substring(offset));\n\n this.markups.forEach(function (markup) {\n pre.addMarkup(markup);\n post.addMarkup(markup);\n });\n\n return [pre, post];\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.isBlank;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.length === 0;\n }\n }, {\n key: 'text',\n get: function get() {\n return this.value;\n }\n }, {\n key: 'length',\n get: function get() {\n return this.value.length;\n }\n }]);\n\n return Marker;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n (0, _mobiledocKitUtilsMixin['default'])(Marker, _mobiledocKitUtilsMarkuperable['default']);\n\n exports['default'] = Marker;\n});","define('mobiledoc-kit/models/markup-section', ['exports', 'mobiledoc-kit/models/_markerable', 'mobiledoc-kit/models/_attributable', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitModels_markerable, _mobiledocKitModels_attributable, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsObjectUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n // valid values of `tagName` for a MarkupSection\n var VALID_MARKUP_SECTION_TAGNAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_SECTION_TAGNAMES = VALID_MARKUP_SECTION_TAGNAMES;\n // valid element names for a MarkupSection. A MarkupSection with a tagName\n // not in this will be rendered as a div with a className matching the\n // tagName\n var MARKUP_SECTION_ELEMENT_NAMES = ['aside', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n exports.MARKUP_SECTION_ELEMENT_NAMES = MARKUP_SECTION_ELEMENT_NAMES;\n var DEFAULT_TAG_NAME = VALID_MARKUP_SECTION_TAGNAMES[8];\n\n exports.DEFAULT_TAG_NAME = DEFAULT_TAG_NAME;\n var MarkupSection = (function (_Markerable) {\n _inherits(MarkupSection, _Markerable);\n\n function MarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];\n\n var _this = this;\n\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n _classCallCheck(this, MarkupSection);\n\n _get(Object.getPrototypeOf(MarkupSection.prototype), 'constructor', this).call(this, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, tagName, markers);\n\n (0, _mobiledocKitModels_attributable.attributable)(this);\n (0, _mobiledocKitUtilsObjectUtils.entries)(attributes).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var k = _ref2[0];\n var v = _ref2[1];\n return _this.setAttribute(k, v);\n });\n\n this.isMarkupSection = true;\n }\n\n _createClass(MarkupSection, [{\n key: 'isValidTagName',\n value: function isValidTagName(normalizedTagName) {\n return (0, _mobiledocKitUtilsArrayUtils.contains)(VALID_MARKUP_SECTION_TAGNAMES, normalizedTagName);\n }\n }, {\n key: 'splitAtMarker',\n value: function splitAtMarker(marker) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var beforeSection = this.builder.createMarkupSection(this.tagName, [], false, this.attributes);\n var afterSection = this.builder.createMarkupSection();\n\n return this._redistributeMarkers(beforeSection, afterSection, marker, offset);\n }\n }]);\n\n return MarkupSection;\n })(_mobiledocKitModels_markerable['default']);\n\n exports['default'] = MarkupSection;\n});","define('mobiledoc-kit/models/markup', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var VALID_MARKUP_TAGNAMES = ['a', 'b', 'code', 'em', 'i', 's', // strikethrough\n 'strong', 'sub', // subscript\n 'sup', // superscript\n 'u'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n exports.VALID_MARKUP_TAGNAMES = VALID_MARKUP_TAGNAMES;\n var VALID_ATTRIBUTES = ['href', 'rel'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n /**\n * A Markup is similar with an inline HTML tag that might be added to\n * text to modify its meaning and/or display. Examples of types of markup\n * that could be added are bold ('b'), italic ('i'), strikethrough ('s'), and `a` tags (links).\n * @property {String} tagName\n */\n\n var Markup = (function () {\n /*\n * @param {Object} attributes key-values\n */\n\n function Markup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, Markup);\n\n this.tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must use attributes object param (not array) for Markup', !Array.isArray(attributes));\n\n this.attributes = (0, _mobiledocKitUtilsArrayUtils.filterObject)(attributes, VALID_ATTRIBUTES);\n this.type = _mobiledocKitModelsTypes.MARKUP_TYPE;\n\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markup of tagName ' + tagName, VALID_MARKUP_TAGNAMES.indexOf(this.tagName) !== -1);\n }\n\n /**\n * Whether text in the forward direction of the cursor (i.e. to the right in ltr text)\n * should be considered to have this markup applied to it.\n * @private\n */\n\n _createClass(Markup, [{\n key: 'isForwardInclusive',\n value: function isForwardInclusive() {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(\"a\") ? false : true;\n }\n }, {\n key: 'isBackwardInclusive',\n value: function isBackwardInclusive() {\n return false;\n }\n }, {\n key: 'hasTag',\n value: function hasTag(tagName) {\n return this.tagName === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n }\n\n /**\n * Returns the attribute value\n * @param {String} name, e.g. \"href\"\n */\n }, {\n key: 'getAttribute',\n value: function getAttribute(name) {\n return this.attributes[name];\n }\n }], [{\n key: 'isValidElement',\n value: function isValidElement(element) {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n return VALID_MARKUP_TAGNAMES.indexOf(tagName) !== -1;\n }\n }]);\n\n return Markup;\n })();\n\n exports['default'] = Markup;\n});","define('mobiledoc-kit/models/post-node-builder', ['exports', 'mobiledoc-kit/models/atom', 'mobiledoc-kit/models/post', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/image', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsAtom, _mobiledocKitModelsPost, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsImage, _mobiledocKitModelsMarker, _mobiledocKitModelsMarkup, _mobiledocKitModelsCard, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function cacheKey(tagName, attributes) {\n return (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName) + '-' + (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(attributes).join('-');\n }\n\n function addMarkupToCache(cache, markup) {\n cache[cacheKey(markup.tagName, markup.attributes)] = markup;\n }\n\n function findMarkupInCache(cache, tagName, attributes) {\n var key = cacheKey(tagName, attributes);\n return cache[key];\n }\n\n /**\n * The PostNodeBuilder is used to create new {@link Post} primitives, such\n * as a MarkupSection, a CardSection, a Markup, etc. Every instance of an\n * {@link Editor} has its own builder instance. The builder can be used\n * inside an {@link Editor#run} callback to programmatically create new\n * Post primitives to insert into the document.\n * A PostNodeBuilder should be read from the Editor, *not* instantiated on its own.\n */\n\n var PostNodeBuilder = (function () {\n /**\n * @private\n */\n\n function PostNodeBuilder() {\n _classCallCheck(this, PostNodeBuilder);\n\n this.markupCache = {};\n }\n\n /**\n * @return {Post} A new, blank post\n */\n\n _createClass(PostNodeBuilder, [{\n key: 'createPost',\n value: function createPost() {\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var post = new _mobiledocKitModelsPost['default']();\n post.builder = this;\n\n sections.forEach(function (s) {\n return post.sections.append(s);\n });\n\n return post;\n }\n }, {\n key: 'createMarkerableSection',\n value: function createMarkerableSection(type, tagName) {\n var markers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.createListItem(markers);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.createMarkupSection(tagName, markers);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot create markerable section of type ' + type, false);\n }\n }\n\n /**\n * @param {tagName} [tagName='P']\n * @param {Marker[]} [markers=[]]\n * @return {MarkupSection}\n */\n }, {\n key: 'createMarkupSection',\n value: function createMarkupSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME : arguments[0];\n var markers = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var isGenerated = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n var attributes = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsMarkupSection['default'](tagName, markers, attributes);\n if (isGenerated) {\n section.isGenerated = true;\n }\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListSection',\n value: function createListSection() {\n var tagName = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitModelsListSection.DEFAULT_TAG_NAME : arguments[0];\n var items = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var section = new _mobiledocKitModelsListSection['default'](tagName, items, attributes);\n section.builder = this;\n return section;\n }\n }, {\n key: 'createListItem',\n value: function createListItem() {\n var markers = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('li');\n var item = new _mobiledocKitModelsListItem['default'](tagName, markers);\n item.builder = this;\n return item;\n }\n }, {\n key: 'createImageSection',\n value: function createImageSection(url) {\n var section = new _mobiledocKitModelsImage['default']();\n if (url) {\n section.src = url;\n }\n return section;\n }\n\n /**\n * @param {String} name\n * @param {Object} [payload={}]\n * @return {CardSection}\n */\n }, {\n key: 'createCardSection',\n value: function createCardSection(name) {\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var card = new _mobiledocKitModelsCard['default'](name, payload);\n card.builder = this;\n return card;\n }\n\n /**\n * @param {String} value\n * @param {Markup[]} [markups=[]]\n * @return {Marker}\n */\n }, {\n key: 'createMarker',\n value: function createMarker(value) {\n var markups = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var marker = new _mobiledocKitModelsMarker['default'](value, markups);\n marker.builder = this;\n return marker;\n }\n\n /**\n * @param {String} name\n * @param {String} [value='']\n * @param {Object} [payload={}]\n * @param {Markup[]} [markups=[]]\n * @return {Atom}\n */\n }, {\n key: 'createAtom',\n value: function createAtom(name) {\n var value = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];\n var payload = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n var markups = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3];\n\n var atom = new _mobiledocKitModelsAtom['default'](name, value, payload, markups);\n atom.builder = this;\n return atom;\n }\n\n /**\n * @param {String} tagName\n * @param {Object} attributes Key-value pairs of attributes for the markup\n * @return {Markup}\n */\n }, {\n key: 'createMarkup',\n value: function createMarkup(tagName) {\n var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n\n var markup = findMarkupInCache(this.markupCache, tagName, attributes);\n if (!markup) {\n markup = new _mobiledocKitModelsMarkup['default'](tagName, attributes);\n markup.builder = this;\n addMarkupToCache(this.markupCache, markup);\n }\n\n return markup;\n }\n }]);\n\n return PostNodeBuilder;\n })();\n\n exports['default'] = PostNodeBuilder;\n});","define('mobiledoc-kit/models/post', ['exports', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/set', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsTypes, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsSet, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * The Post is an in-memory representation of an editor's document.\n * An editor always has a single post. The post is organized into a list of\n * sections. Each section may be markerable (contains \"markers\", aka editable\n * text) or non-markerable (e.g., a card).\n * When persisting a post, it must first be serialized (loss-lessly) into\n * mobiledoc using {@link Editor#serialize}.\n */\n\n var Post = (function () {\n /**\n * @private\n */\n\n function Post() {\n var _this = this;\n\n _classCallCheck(this, Post);\n\n this.type = _mobiledocKitModelsTypes.POST_TYPE;\n this.sections = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(s) {\n return s.post = s.parent = _this;\n },\n freeItem: function freeItem(s) {\n return s.post = s.parent = null;\n }\n });\n }\n\n /**\n * @return {Position} The position at the start of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n\n _createClass(Post, [{\n key: 'headPosition',\n value: function headPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.head.headPosition();\n }\n }\n\n /**\n * @return {Position} The position at the end of the post (will be a {@link BlankPosition}\n * if the post is blank)\n * @public\n */\n }, {\n key: 'tailPosition',\n value: function tailPosition() {\n if (this.isBlank) {\n return _mobiledocKitUtilsCursorPosition['default'].blankPosition();\n } else {\n return this.sections.tail.tailPosition();\n }\n }\n\n /**\n * @return {Range} A range encompassing the entire post\n * @public\n */\n }, {\n key: 'toRange',\n value: function toRange() {\n return this.headPosition().toRange(this.tailPosition());\n }\n }, {\n key: 'markersContainedByRange',\n\n /**\n * @param {Range} range\n * @return {Array} markers that are completely contained by the range\n */\n value: function markersContainedByRange(range) {\n var markers = [];\n\n this.walkMarkerableSections(range, function (section) {\n section._markersInRange(range.trimTo(section), function (m, _ref) {\n var isContained = _ref.isContained;\n if (isContained) {\n markers.push(m);\n }\n });\n });\n\n return markers;\n }\n }, {\n key: 'markupsInRange',\n value: function markupsInRange(range) {\n var markups = new _mobiledocKitUtilsSet['default']();\n\n if (range.isCollapsed) {\n var pos = range.head;\n if (pos.isMarkerable) {\n var back = pos.markerIn(-1);\n var forward = pos.markerIn(1);\n\n if (back && forward && back === forward) {\n back.markups.forEach(function (m) {\n return markups.add(m);\n });\n } else {\n (back && back.markups || []).forEach(function (m) {\n if (m.isForwardInclusive()) {\n markups.add(m);\n }\n });\n (forward && forward.markups || []).forEach(function (m) {\n if (m.isBackwardInclusive()) {\n markups.add(m);\n }\n });\n }\n }\n } else {\n this.walkMarkerableSections(range, function (section) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markupsInRange(range.trimTo(section)), function (m) {\n return markups.add(m);\n });\n });\n }\n\n return markups.toArray();\n }\n }, {\n key: 'walkAllLeafSections',\n value: function walkAllLeafSections(callback) {\n var range = this.headPosition().toRange(this.tailPosition());\n return this.walkLeafSections(range, callback);\n }\n }, {\n key: 'walkLeafSections',\n value: function walkLeafSections(range, callback) {\n var head = range.head;\n var tail = range.tail;\n\n var index = 0;\n var nextSection = undefined,\n shouldStop = undefined;\n var currentSection = head.section;\n\n while (currentSection) {\n nextSection = this._nextLeafSection(currentSection);\n shouldStop = currentSection === tail.section;\n\n callback(currentSection, index);\n index++;\n\n if (shouldStop) {\n break;\n } else {\n currentSection = nextSection;\n }\n }\n }\n }, {\n key: 'walkMarkerableSections',\n value: function walkMarkerableSections(range, callback) {\n this.walkLeafSections(range, function (section) {\n if (section.isMarkerable) {\n callback(section);\n }\n });\n }\n\n // return the next section that has markers after this one,\n // possibly skipping non-markerable sections\n }, {\n key: '_nextLeafSection',\n value: function _nextLeafSection(section) {\n if (!section) {\n return null;\n }\n\n var next = section.next;\n if (next) {\n if (next.isLeafSection) {\n return next;\n } else if (next.items) {\n return next.items.head;\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot determine next section from non-leaf-section', false);\n }\n } else if (section.isNested) {\n // if there is no section after this, but this section is a child\n // (e.g. a ListItem inside a ListSection), check for a markerable\n // section after its parent\n return this._nextLeafSection(section.parent);\n }\n }\n\n /**\n * @param {Range} range\n * @return {Post} A new post, constrained to {range}\n */\n }, {\n key: 'trimTo',\n value: function trimTo(range) {\n var post = this.builder.createPost();\n var builder = this.builder;\n\n var sectionParent = post,\n listParent = null;\n this.walkLeafSections(range, function (section) {\n var newSection = undefined;\n if (section.isMarkerable) {\n if (section.isListItem) {\n if (listParent) {\n sectionParent = null;\n } else {\n listParent = builder.createListSection(section.parent.tagName);\n post.sections.append(listParent);\n sectionParent = null;\n }\n newSection = builder.createListItem();\n listParent.items.append(newSection);\n } else {\n listParent = null;\n sectionParent = post;\n newSection = builder.createMarkupSection(section.tagName);\n }\n\n var currentRange = range.trimTo(section);\n (0, _mobiledocKitUtilsArrayUtils.forEach)(section.markersFor(currentRange.headSectionOffset, currentRange.tailSectionOffset), function (m) {\n return newSection.markers.append(m);\n });\n } else {\n newSection = section.clone();\n sectionParent = post;\n }\n if (sectionParent) {\n sectionParent.sections.append(newSection);\n }\n });\n return post;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.sections.isEmpty;\n }\n\n /**\n * If the post has no sections, or only has one, blank section, then it does\n * not have content and this method returns false. Otherwise it is true.\n * @return {Boolean}\n * @public\n */\n }, {\n key: 'hasContent',\n get: function get() {\n if (this.sections.length > 1 || this.sections.length === 1 && !this.sections.head.isBlank) {\n return true;\n } else {\n return false;\n }\n }\n }]);\n\n return Post;\n })();\n\n exports['default'] = Post;\n});","define('mobiledoc-kit/models/render-node', ['exports', 'mobiledoc-kit/utils/linked-item', 'mobiledoc-kit/utils/linked-list', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsLinkedItem, _mobiledocKitUtilsLinkedList, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var RenderNode = (function (_LinkedItem) {\n _inherits(RenderNode, _LinkedItem);\n\n function RenderNode(postNode, renderTree) {\n _classCallCheck(this, RenderNode);\n\n _get(Object.getPrototypeOf(RenderNode.prototype), 'constructor', this).call(this);\n this.parent = null;\n this.isDirty = true;\n this.isRemoved = false;\n this.postNode = postNode;\n this._childNodes = null;\n this._element = null;\n this._cursorElement = null; // blank render nodes need a cursor element\n this.renderTree = renderTree;\n\n // RenderNodes for Markers keep track of their markupElement\n this.markupElement = null;\n\n // RenderNodes for Atoms use these properties\n this.headTextNode = null;\n this.tailTextNode = null;\n this.atomNode = null;\n\n // RenderNodes for cards use this property\n this.cardNode = null;\n }\n\n _createClass(RenderNode, [{\n key: 'isAttached',\n value: function isAttached() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot check if a renderNode is attached without an element.', !!this.element);\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(this.renderTree.rootElement, this.element);\n }\n }, {\n key: 'scheduleForRemoval',\n value: function scheduleForRemoval() {\n this.isRemoved = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markDirty',\n value: function markDirty() {\n this.isDirty = true;\n if (this.parent) {\n this.parent.markDirty();\n }\n }\n }, {\n key: 'markClean',\n value: function markClean() {\n this.isDirty = false;\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.element = null;\n this.parent = null;\n this.postNode = null;\n this.renderTree = null;\n }\n }, {\n key: 'reparsesMutationOfChildNode',\n value: function reparsesMutationOfChildNode(node) {\n if (this.postNode.isCardSection) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.cardNode.element, node);\n } else if (this.postNode.isAtom) {\n return !(0, _mobiledocKitUtilsDomUtils.containsNode)(this.atomNode.element, node);\n }\n return true;\n }\n }, {\n key: 'childNodes',\n get: function get() {\n var _this = this;\n\n if (!this._childNodes) {\n this._childNodes = new _mobiledocKitUtilsLinkedList['default']({\n adoptItem: function adoptItem(item) {\n return item.parent = _this;\n },\n freeItem: function freeItem(item) {\n return item.destroy();\n }\n });\n }\n return this._childNodes;\n }\n }, {\n key: 'isRendered',\n get: function get() {\n return !!this.element;\n }\n }, {\n key: 'element',\n set: function set(element) {\n var currentElement = this._element;\n this._element = element;\n\n if (currentElement) {\n this.renderTree.removeElementRenderNode(currentElement);\n }\n\n if (element) {\n this.renderTree.setElementRenderNode(element, this);\n }\n },\n get: function get() {\n return this._element;\n }\n }, {\n key: 'cursorElement',\n set: function set(cursorElement) {\n this._cursorElement = cursorElement;\n },\n get: function get() {\n return this._cursorElement || this.element;\n }\n }]);\n\n return RenderNode;\n })(_mobiledocKitUtilsLinkedItem['default']);\n\n exports['default'] = RenderNode;\n});","define('mobiledoc-kit/models/render-tree', ['exports', 'mobiledoc-kit/models/render-node', 'mobiledoc-kit/utils/element-map'], function (exports, _mobiledocKitModelsRenderNode, _mobiledocKitUtilsElementMap) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var RenderTree = (function () {\n function RenderTree(rootPostNode) {\n _classCallCheck(this, RenderTree);\n\n this._rootNode = this.buildRenderNode(rootPostNode);\n this._elements = new _mobiledocKitUtilsElementMap['default']();\n }\n\n /*\n * @return {RenderNode} The root render node in this tree\n */\n\n _createClass(RenderTree, [{\n key: 'getElementRenderNode',\n\n /*\n * @param {DOMNode} element\n * @return {RenderNode} The renderNode for this element, if any\n */\n value: function getElementRenderNode(element) {\n return this._elements.get(element);\n }\n }, {\n key: 'setElementRenderNode',\n value: function setElementRenderNode(element, renderNode) {\n this._elements.set(element, renderNode);\n }\n }, {\n key: 'removeElementRenderNode',\n value: function removeElementRenderNode(element) {\n this._elements.remove(element);\n }\n\n /**\n * @param {DOMNode} element\n * Walk up from the dom element until we find a renderNode element\n */\n }, {\n key: 'findRenderNodeFromElement',\n value: function findRenderNodeFromElement(element) {\n var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {\n return true;\n } : arguments[1];\n\n var renderNode = undefined;\n while (element) {\n renderNode = this.getElementRenderNode(element);\n if (renderNode && conditionFn(renderNode)) {\n return renderNode;\n }\n\n // continue loop\n element = element.parentNode;\n\n // stop if we are at the root element\n if (element === this.rootElement) {\n if (conditionFn(this.rootNode)) {\n return this.rootNode;\n } else {\n return;\n }\n }\n }\n }\n }, {\n key: 'buildRenderNode',\n value: function buildRenderNode(postNode) {\n var renderNode = new _mobiledocKitModelsRenderNode['default'](postNode, this);\n postNode.renderNode = renderNode;\n return renderNode;\n }\n }, {\n key: 'rootNode',\n get: function get() {\n return this._rootNode;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'isDirty',\n get: function get() {\n return this.rootNode && this.rootNode.isDirty;\n }\n\n /*\n * @return {DOMNode} The root DOM element in this tree\n */\n }, {\n key: 'rootElement',\n get: function get() {\n return this.rootNode.element;\n }\n }]);\n\n return RenderTree;\n })();\n\n exports['default'] = RenderTree;\n});","define('mobiledoc-kit/models/types', ['exports'], function (exports) {\n 'use strict';\n\n var MARKUP_SECTION_TYPE = 'markup-section';\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var LIST_SECTION_TYPE = 'list-section';\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var MARKUP_TYPE = 'markup';\n exports.MARKUP_TYPE = MARKUP_TYPE;\n var MARKER_TYPE = 'marker';\n exports.MARKER_TYPE = MARKER_TYPE;\n var POST_TYPE = 'post';\n exports.POST_TYPE = POST_TYPE;\n var LIST_ITEM_TYPE = 'list-item';\n exports.LIST_ITEM_TYPE = LIST_ITEM_TYPE;\n var CARD_TYPE = 'card-section';\n exports.CARD_TYPE = CARD_TYPE;\n var IMAGE_SECTION_TYPE = 'image-section';\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var ATOM_TYPE = 'atom';\n exports.ATOM_TYPE = ATOM_TYPE;\n});","define('mobiledoc-kit/parsers/dom', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/parsers/section', 'mobiledoc-kit/models/markup'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsTypes, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCharacters, _mobiledocKitParsersSection, _mobiledocKitModelsMarkup) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.transformHTMLText = transformHTMLText;\n exports.trimSectionText = trimSectionText;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var GOOGLE_DOCS_CONTAINER_ID_REGEX = /^docs\\-internal\\-guid/;\n\n var NO_BREAK_SPACE_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.NO_BREAK_SPACE, 'g');\n var TAB_CHARACTER_REGEX = new RegExp(_mobiledocKitRenderersEditorDom.TAB_CHARACTER, 'g');\n\n function transformHTMLText(textContent) {\n var text = textContent;\n text = text.replace(NO_BREAK_SPACE_REGEX, ' ');\n text = text.replace(TAB_CHARACTER_REGEX, _mobiledocKitUtilsCharacters.TAB);\n return text;\n }\n\n function trimSectionText(section) {\n if (section.isMarkerable && section.markers.length) {\n var _section$markers = section.markers;\n var head = _section$markers.head;\n var tail = _section$markers.tail;\n\n head.value = head.value.replace(/^\\s+/, '');\n tail.value = tail.value.replace(/\\s+$/, '');\n }\n }\n\n function isGoogleDocsContainer(element) {\n return !(0, _mobiledocKitUtilsDomUtils.isTextNode)(element) && !(0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) && (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName) === (0, _mobiledocKitUtilsDomUtils.normalizeTagName)('b') && GOOGLE_DOCS_CONTAINER_ID_REGEX.test(element.id);\n }\n\n function detectRootElement(element) {\n var childNodes = element.childNodes || [];\n var googleDocsContainer = (0, _mobiledocKitUtilsArrayUtils.detect)(childNodes, isGoogleDocsContainer);\n\n if (googleDocsContainer) {\n return googleDocsContainer;\n } else {\n return element;\n }\n }\n\n var TAG_REMAPPING = {\n 'b': 'strong',\n 'i': 'em'\n };\n\n function remapTagName(tagName) {\n var normalized = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n var remapped = TAG_REMAPPING[normalized];\n return remapped || normalized;\n }\n\n function trim(str) {\n return str.replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n\n function walkMarkerableNodes(parent, callback) {\n var currentNode = parent;\n\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(currentNode) || (0, _mobiledocKitUtilsDomUtils.isElementNode)(currentNode) && currentNode.classList.contains(_mobiledocKitRenderersEditorDom.ATOM_CLASS_NAME)) {\n callback(currentNode);\n } else {\n currentNode = currentNode.firstChild;\n while (currentNode) {\n walkMarkerableNodes(currentNode, callback);\n currentNode = currentNode.nextSibling;\n }\n }\n }\n\n /**\n * Parses DOM element -> Post\n * @private\n */\n\n var DOMParser = (function () {\n function DOMParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, DOMParser);\n\n this.builder = builder;\n this.sectionParser = new _mobiledocKitParsersSection['default'](this.builder, options);\n }\n\n _createClass(DOMParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n var post = this.builder.createPost();\n var rootElement = detectRootElement(element);\n\n this._eachChildNode(rootElement, function (child) {\n var sections = _this.parseSections(child);\n _this.appendSections(post, sections);\n });\n\n // trim leading/trailing whitespace of markerable sections to avoid\n // unnessary whitespace from indented HTML input\n (0, _mobiledocKitUtilsArrayUtils.forEach)(post.sections, function (section) {\n return trimSectionText(section);\n });\n\n return post;\n }\n }, {\n key: 'appendSections',\n value: function appendSections(post, sections) {\n var _this2 = this;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(sections, function (section) {\n return _this2.appendSection(post, section);\n });\n }\n }, {\n key: 'appendSection',\n value: function appendSection(post, section) {\n if (section.isBlank || section.isMarkerable && trim(section.text) === \"\" && !(0, _mobiledocKitUtilsArrayUtils.any)(section.markers, function (marker) {\n return marker.isAtom;\n })) {\n return;\n }\n\n var lastSection = post.sections.tail;\n if (lastSection && lastSection._inferredTagName && section._inferredTagName && lastSection.tagName === section.tagName) {\n lastSection.join(section);\n } else {\n post.sections.append(section);\n }\n }\n }, {\n key: '_eachChildNode',\n value: function _eachChildNode(element, callback) {\n var nodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n return callback(node);\n });\n }\n }, {\n key: 'parseSections',\n value: function parseSections(element) {\n return this.sectionParser.parse(element);\n }\n\n // walk up from the textNode until the rootNode, converting each\n // parentNode into a markup\n }, {\n key: 'collectMarkups',\n value: function collectMarkups(textNode, rootNode) {\n var markups = [];\n var currentNode = textNode.parentNode;\n while (currentNode && currentNode !== rootNode) {\n var markup = this.markupFromNode(currentNode);\n if (markup) {\n markups.push(markup);\n }\n\n currentNode = currentNode.parentNode;\n }\n return markups;\n }\n\n // Turn an element node into a markup\n }, {\n key: 'markupFromNode',\n value: function markupFromNode(node) {\n if (_mobiledocKitModelsMarkup['default'].isValidElement(node)) {\n var tagName = remapTagName(node.tagName);\n var attributes = (0, _mobiledocKitUtilsDomUtils.getAttributes)(node);\n return this.builder.createMarkup(tagName, attributes);\n }\n }\n\n // FIXME should move to the section parser?\n // FIXME the `collectMarkups` logic could simplify the section parser?\n }, {\n key: 'reparseSection',\n value: function reparseSection(section, renderTree) {\n switch (section.type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n return this.reparseListSection(section, renderTree);\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n return this.reparseListItem(section, renderTree);\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n return this.reparseMarkupSection(section, renderTree);\n default:\n return; // can only parse the above types\n }\n }\n }, {\n key: 'reparseMarkupSection',\n value: function reparseMarkupSection(section, renderTree) {\n return this._reparseSectionContainingMarkers(section, renderTree);\n }\n }, {\n key: 'reparseListItem',\n value: function reparseListItem(listItem, renderTree) {\n return this._reparseSectionContainingMarkers(listItem, renderTree);\n }\n }, {\n key: 'reparseListSection',\n value: function reparseListSection(listSection, renderTree) {\n var _this3 = this;\n\n listSection.items.forEach(function (li) {\n return _this3.reparseListItem(li, renderTree);\n });\n }\n }, {\n key: '_reparseSectionContainingMarkers',\n value: function _reparseSectionContainingMarkers(section, renderTree) {\n var _this4 = this;\n\n var element = section.renderNode.element;\n var seenRenderNodes = [];\n var previousMarker = undefined;\n\n walkMarkerableNodes(element, function (node) {\n var marker = undefined;\n var renderNode = renderTree.getElementRenderNode(node);\n if (renderNode) {\n if (renderNode.postNode.isMarker) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n if (text.length) {\n marker = renderNode.postNode;\n marker.value = text;\n marker.markups = markups;\n } else {\n renderNode.scheduleForRemoval();\n }\n } else if (renderNode.postNode.isAtom) {\n var _renderNode = renderNode;\n var headTextNode = _renderNode.headTextNode;\n var tailTextNode = _renderNode.tailTextNode;\n\n if (headTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = headTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n headTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n if (previousMarker && previousMarker.isMarker) {\n previousMarker.value += value;\n if (previousMarker.renderNode) {\n previousMarker.renderNode.markDirty();\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newPreviousMarker = _this4.builder.createMarker(value, newMarkups);\n section.markers.insertBefore(newPreviousMarker, postNode);\n\n var newPreviousRenderNode = renderTree.buildRenderNode(newPreviousMarker);\n newPreviousRenderNode.markDirty();\n section.renderNode.markDirty();\n\n seenRenderNodes.push(newPreviousRenderNode);\n section.renderNode.childNodes.insertBefore(newPreviousRenderNode, renderNode);\n }\n }\n if (tailTextNode.textContent !== _mobiledocKitRenderersEditorDom.ZWNJ) {\n var value = tailTextNode.textContent.replace(new RegExp(_mobiledocKitRenderersEditorDom.ZWNJ, 'g'), '');\n tailTextNode.textContent = _mobiledocKitRenderersEditorDom.ZWNJ;\n\n if (renderNode.postNode.next && renderNode.postNode.next.isMarker) {\n var nextMarker = renderNode.postNode.next;\n\n if (nextMarker.renderNode) {\n var nextValue = nextMarker.renderNode.element.textContent;\n nextMarker.renderNode.element.textContent = value + nextValue;\n } else {\n var nextValue = value + nextMarker.value;\n nextMarker.value = nextValue;\n }\n } else {\n var postNode = renderNode.postNode;\n var newMarkups = postNode.markups.slice();\n var newMarker = _this4.builder.createMarker(value, newMarkups);\n\n section.markers.insertAfter(newMarker, postNode);\n\n var newRenderNode = renderTree.buildRenderNode(newMarker);\n seenRenderNodes.push(newRenderNode);\n\n newRenderNode.markDirty();\n section.renderNode.markDirty();\n\n section.renderNode.childNodes.insertAfter(newRenderNode, renderNode);\n }\n }\n if (renderNode) {\n marker = renderNode.postNode;\n }\n }\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n var text = transformHTMLText(node.textContent);\n var markups = _this4.collectMarkups(node, element);\n marker = _this4.builder.createMarker(text, markups);\n\n renderNode = renderTree.buildRenderNode(marker);\n renderNode.element = node;\n renderNode.markClean();\n section.renderNode.markDirty();\n\n var previousRenderNode = previousMarker && previousMarker.renderNode;\n section.markers.insertAfter(marker, previousMarker);\n section.renderNode.childNodes.insertAfter(renderNode, previousRenderNode);\n }\n\n if (renderNode) {\n seenRenderNodes.push(renderNode);\n }\n previousMarker = marker;\n });\n\n var renderNode = section.renderNode.childNodes.head;\n while (renderNode) {\n if (seenRenderNodes.indexOf(renderNode) === -1) {\n renderNode.scheduleForRemoval();\n }\n renderNode = renderNode.next;\n }\n }\n }]);\n\n return DOMParser;\n })();\n\n exports['default'] = DOMParser;\n});","define('mobiledoc-kit/parsers/html', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/parsers/dom'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitParsersDom) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var HTMLParser = (function () {\n function HTMLParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, HTMLParser);\n\n (0, _mobiledocKitUtilsAssert['default'])('Must pass builder to HTMLParser', builder);\n this.builder = builder;\n this.options = options;\n }\n\n /**\n * @param {String} html to parse\n * @return {Post} A post abstract\n */\n\n _createClass(HTMLParser, [{\n key: 'parse',\n value: function parse(html) {\n var dom = (0, _mobiledocKitUtilsDomUtils.parseHTML)(html);\n var parser = new _mobiledocKitParsersDom['default'](this.builder, this.options);\n return parser.parse(dom);\n }\n }]);\n\n return HTMLParser;\n })();\n\n exports['default'] = HTMLParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sectionData = _ref.sections;\n\n try {\n var markerTypes = sectionData[0];\n var sections = sectionData[1];\n\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this2 = this;\n\n sections.forEach(function (section) {\n return _this2.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ' + type, false);\n }\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref3, post) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref4, post) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var src = _ref42[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 3);\n\n var tagName = _ref62[1];\n var items = _ref62[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this3 = this;\n\n items.forEach(function (i) {\n return _this3.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this4 = this;\n\n markers.forEach(function (m) {\n return _this4.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref7, parent) {\n var _this5 = this;\n\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var markerTypeIndexes = _ref72[0];\n var closeCount = _ref72[1];\n var value = _ref72[2];\n\n markerTypeIndexes.forEach(function (index) {\n _this5.markups.push(_this5.markerTypes[index]);\n });\n var marker = this.builder.createMarker(value, this.markups.slice());\n parent.markers.append(marker);\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc031, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_ATOM_MARKER_TYPE:\n {\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n var atomName = _getAtomTypeFromIndex2[0];\n var atomValue = _getAtomTypeFromIndex2[1];\n var atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n }\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/object-utils'], function (exports, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert, _mobiledocKitUtilsObjectUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 4);\n\n var tagName = _ref72[1];\n var markers = _ref72[2];\n var attributesArray = _ref72[3];\n\n var section = this.builder.createMarkupSection(tagName);\n post.sections.append(section);\n if (attributesArray) {\n (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref8) {\n var _ref82 = _slicedToArray(_ref8, 2);\n\n var key = _ref82[0];\n var value = _ref82[1];\n\n section.setAttribute(key, value);\n });\n }\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref9, post) {\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var tagName = _ref92[1];\n var items = _ref92[2];\n var attributesArray = _ref92[3];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n if (attributesArray) {\n (0, _mobiledocKitUtilsObjectUtils.entries)((0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray)).forEach(function (_ref10) {\n var _ref102 = _slicedToArray(_ref10, 2);\n\n var key = _ref102[0];\n var value = _ref102[1];\n\n section.setAttribute(key, value);\n });\n }\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref11, parent) {\n var _this7 = this;\n\n var _ref112 = _slicedToArray(_ref11, 4);\n\n var type = _ref112[0];\n var markerTypeIndexes = _ref112[1];\n var closeCount = _ref112[2];\n var value = _ref112[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_ATOM_MARKER_TYPE:\n {\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n var atomName = _getAtomTypeFromIndex2[0];\n var atomValue = _getAtomTypeFromIndex2[1];\n var atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n }\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc03, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /*\n * Parses from mobiledoc -> post\n */\n\n var MobiledocParser = (function () {\n function MobiledocParser(builder) {\n _classCallCheck(this, MobiledocParser);\n\n this.builder = builder;\n }\n\n /**\n * @param {Mobiledoc}\n * @return {Post}\n */\n\n _createClass(MobiledocParser, [{\n key: 'parse',\n value: function parse(_ref) {\n var sections = _ref.sections;\n var markerTypes = _ref.markups;\n var cardTypes = _ref.cards;\n var atomTypes = _ref.atoms;\n\n try {\n var post = this.builder.createPost();\n\n this.markups = [];\n this.markerTypes = this.parseMarkerTypes(markerTypes);\n this.cardTypes = this.parseCardTypes(cardTypes);\n this.atomTypes = this.parseAtomTypes(atomTypes);\n this.parseSections(sections, post);\n\n return post;\n } catch (e) {\n (0, _mobiledocKitUtilsAssert['default'])('Unable to parse mobiledoc: ' + e.message, false);\n }\n }\n }, {\n key: 'parseMarkerTypes',\n value: function parseMarkerTypes(markerTypes) {\n var _this = this;\n\n return markerTypes.map(function (markerType) {\n return _this.parseMarkerType(markerType);\n });\n }\n }, {\n key: 'parseMarkerType',\n value: function parseMarkerType(_ref2) {\n var _ref22 = _slicedToArray(_ref2, 2);\n\n var tagName = _ref22[0];\n var attributesArray = _ref22[1];\n\n var attributesObject = (0, _mobiledocKitUtilsArrayUtils.kvArrayToObject)(attributesArray || []);\n return this.builder.createMarkup(tagName, attributesObject);\n }\n }, {\n key: 'parseCardTypes',\n value: function parseCardTypes(cardTypes) {\n var _this2 = this;\n\n return cardTypes.map(function (cardType) {\n return _this2.parseCardType(cardType);\n });\n }\n }, {\n key: 'parseCardType',\n value: function parseCardType(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var cardName = _ref32[0];\n var cardPayload = _ref32[1];\n\n return [cardName, cardPayload];\n }\n }, {\n key: 'parseAtomTypes',\n value: function parseAtomTypes(atomTypes) {\n var _this3 = this;\n\n return atomTypes.map(function (atomType) {\n return _this3.parseAtomType(atomType);\n });\n }\n }, {\n key: 'parseAtomType',\n value: function parseAtomType(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var atomName = _ref42[0];\n var atomValue = _ref42[1];\n var atomPayload = _ref42[2];\n\n return [atomName, atomValue, atomPayload];\n }\n }, {\n key: 'parseSections',\n value: function parseSections(sections, post) {\n var _this4 = this;\n\n sections.forEach(function (section) {\n return _this4.parseSection(section, post);\n });\n }\n }, {\n key: 'parseSection',\n value: function parseSection(section, post) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_SECTION_TYPE:\n this.parseMarkupSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_IMAGE_SECTION_TYPE:\n this.parseImageSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_CARD_SECTION_TYPE:\n this.parseCardSection(section, post);\n break;\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_LIST_SECTION_TYPE:\n this.parseListSection(section, post);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected section type ${type}', false);\n }\n }\n }, {\n key: 'getAtomTypeFromIndex',\n value: function getAtomTypeFromIndex(index) {\n var atomType = this.atomTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No atom definition found at index ' + index, !!atomType);\n return atomType;\n }\n }, {\n key: 'getCardTypeFromIndex',\n value: function getCardTypeFromIndex(index) {\n var cardType = this.cardTypes[index];\n (0, _mobiledocKitUtilsAssert['default'])('No card definition found at index ' + index, !!cardType);\n return cardType;\n }\n }, {\n key: 'parseCardSection',\n value: function parseCardSection(_ref5, post) {\n var _ref52 = _slicedToArray(_ref5, 2);\n\n var cardIndex = _ref52[1];\n\n var _getCardTypeFromIndex = this.getCardTypeFromIndex(cardIndex);\n\n var _getCardTypeFromIndex2 = _slicedToArray(_getCardTypeFromIndex, 2);\n\n var name = _getCardTypeFromIndex2[0];\n var payload = _getCardTypeFromIndex2[1];\n\n var section = this.builder.createCardSection(name, payload);\n post.sections.append(section);\n }\n }, {\n key: 'parseImageSection',\n value: function parseImageSection(_ref6, post) {\n var _ref62 = _slicedToArray(_ref6, 2);\n\n var src = _ref62[1];\n\n var section = this.builder.createImageSection(src);\n post.sections.append(section);\n }\n }, {\n key: 'parseMarkupSection',\n value: function parseMarkupSection(_ref7, post) {\n var _ref72 = _slicedToArray(_ref7, 3);\n\n var tagName = _ref72[1];\n var markers = _ref72[2];\n\n var section = this.builder.createMarkupSection(tagName.toLowerCase() === 'pull-quote' ? 'aside' : tagName);\n post.sections.append(section);\n this.parseMarkers(markers, section);\n // Strip blank markers after they have been created. This ensures any\n // markup they include has been correctly populated.\n (0, _mobiledocKitUtilsArrayUtils.filter)(section.markers, function (m) {\n return m.isBlank;\n }).forEach(function (m) {\n section.markers.remove(m);\n });\n }\n }, {\n key: 'parseListSection',\n value: function parseListSection(_ref8, post) {\n var _ref82 = _slicedToArray(_ref8, 3);\n\n var tagName = _ref82[1];\n var items = _ref82[2];\n\n var section = this.builder.createListSection(tagName);\n post.sections.append(section);\n this.parseListItems(items, section);\n }\n }, {\n key: 'parseListItems',\n value: function parseListItems(items, section) {\n var _this5 = this;\n\n items.forEach(function (i) {\n return _this5.parseListItem(i, section);\n });\n }\n }, {\n key: 'parseListItem',\n value: function parseListItem(markers, section) {\n var item = this.builder.createListItem();\n this.parseMarkers(markers, item);\n section.items.append(item);\n }\n }, {\n key: 'parseMarkers',\n value: function parseMarkers(markers, parent) {\n var _this6 = this;\n\n markers.forEach(function (m) {\n return _this6.parseMarker(m, parent);\n });\n }\n }, {\n key: 'parseMarker',\n value: function parseMarker(_ref9, parent) {\n var _this7 = this;\n\n var _ref92 = _slicedToArray(_ref9, 4);\n\n var type = _ref92[0];\n var markerTypeIndexes = _ref92[1];\n var closeCount = _ref92[2];\n var value = _ref92[3];\n\n markerTypeIndexes.forEach(function (index) {\n _this7.markups.push(_this7.markerTypes[index]);\n });\n\n var marker = this.buildMarkerType(type, value);\n parent.markers.append(marker);\n\n this.markups = this.markups.slice(0, this.markups.length - closeCount);\n }\n }, {\n key: 'buildMarkerType',\n value: function buildMarkerType(type, value) {\n switch (type) {\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_MARKUP_MARKER_TYPE:\n return this.builder.createMarker(value, this.markups.slice());\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_ATOM_MARKER_TYPE:\n {\n var _getAtomTypeFromIndex = this.getAtomTypeFromIndex(value);\n\n var _getAtomTypeFromIndex2 = _slicedToArray(_getAtomTypeFromIndex, 3);\n\n var atomName = _getAtomTypeFromIndex2[0];\n var atomValue = _getAtomTypeFromIndex2[1];\n var atomPayload = _getAtomTypeFromIndex2[2];\n\n return this.builder.createAtom(atomName, atomValue, atomPayload, this.markups.slice());\n }\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unexpected marker type ' + type, false);\n }\n }\n }]);\n\n return MobiledocParser;\n })();\n\n exports['default'] = MobiledocParser;\n});","define('mobiledoc-kit/parsers/mobiledoc', ['exports', 'mobiledoc-kit/parsers/mobiledoc/0-2', 'mobiledoc-kit/parsers/mobiledoc/0-3', 'mobiledoc-kit/parsers/mobiledoc/0-3-1', 'mobiledoc-kit/parsers/mobiledoc/0-3-2', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitParsersMobiledoc02, _mobiledocKitParsersMobiledoc03, _mobiledocKitParsersMobiledoc031, _mobiledocKitParsersMobiledoc032, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n function parseVersion(mobiledoc) {\n return mobiledoc.version;\n }\n\n exports['default'] = {\n parse: function parse(builder, mobiledoc) {\n var version = parseVersion(mobiledoc);\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc02['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc03['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc031['default'](builder).parse(mobiledoc);\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION:\n return new _mobiledocKitParsersMobiledoc032['default'](builder).parse(mobiledoc);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc parser requested: ' + version, false);\n }\n }\n };\n});","define('mobiledoc-kit/parsers/section', ['exports', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/models/list-section', 'mobiledoc-kit/models/list-item', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitModelsMarkupSection, _mobiledocKitModelsListSection, _mobiledocKitModelsListItem, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkup, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitParsersDom, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var SKIPPABLE_ELEMENT_TAG_NAMES = ['style', 'head', 'title', 'meta'].map(_mobiledocKitUtilsDomUtils.normalizeTagName);\n\n var NEWLINES = /\\n/g;\n function sanitize(text) {\n return text.replace(NEWLINES, ' ');\n }\n\n /**\n * parses an element into a section, ignoring any non-markup\n * elements contained within\n * @private\n */\n\n var SectionParser = (function () {\n function SectionParser(builder) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n _classCallCheck(this, SectionParser);\n\n this.builder = builder;\n this.plugins = options.plugins || [];\n }\n\n _createClass(SectionParser, [{\n key: 'parse',\n value: function parse(element) {\n var _this = this;\n\n if (this._isSkippable(element)) {\n return [];\n }\n this.sections = [];\n this.state = {};\n\n this._updateStateFromElement(element);\n\n var finished = false;\n\n // top-level text nodes will be run through parseNode later so avoid running\n // the node through parserPlugins twice\n if (!(0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n finished = this.runPlugins(element);\n }\n\n if (!finished) {\n var childNodes = (0, _mobiledocKitUtilsDomUtils.isTextNode)(element) ? [element] : element.childNodes;\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(childNodes, function (el) {\n _this.parseNode(el);\n });\n }\n\n this._closeCurrentSection();\n\n return this.sections;\n }\n }, {\n key: 'runPlugins',\n value: function runPlugins(node) {\n var _this2 = this;\n\n var isNodeFinished = false;\n var env = {\n addSection: function addSection(section) {\n // avoid creating empty paragraphs due to wrapper elements around\n // parser-plugin-handled elements\n if (_this2.state.section.isMarkerable && !_this2.state.text && !_this2.state.section.text) {\n _this2.state.section = null;\n } else {\n _this2._closeCurrentSection();\n }\n _this2.sections.push(section);\n },\n addMarkerable: function addMarkerable(marker) {\n var state = _this2.state;\n var section = state.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Markerables can only be appended to markup sections and list item sections', section && section.isMarkerable);\n if (state.text) {\n _this2._createMarker();\n }\n section.markers.append(marker);\n },\n nodeFinished: function nodeFinished() {\n isNodeFinished = true;\n }\n };\n for (var i = 0; i < this.plugins.length; i++) {\n var plugin = this.plugins[i];\n plugin(node, this.builder, env);\n if (isNodeFinished) {\n return true;\n }\n }\n return false;\n }\n\n /* eslint-disable complexity */\n }, {\n key: 'parseNode',\n value: function parseNode(node) {\n var _this3 = this;\n\n if (!this.state.section) {\n this._updateStateFromElement(node);\n }\n\n var nodeFinished = this.runPlugins(node);\n if (nodeFinished) {\n return;\n }\n\n // handle closing the current section and starting a new one if we hit a\n // new-section-creating element.\n if (this.state.section && !(0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.tagName) {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.tagName);\n var isListSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName);\n var isListItem = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName);\n var isMarkupSection = (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName);\n var isNestedListSection = isListSection && this.state.section.isListItem;\n var lastSection = this.sections[this.sections.length - 1];\n\n // we can hit a list item after parsing a nested list, when that happens\n // and the lists are of different types we need to make sure we switch\n // the list type back\n if (isListItem && lastSection && lastSection.isListSection) {\n var parentElement = node.parentElement;\n var parentElementTagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(parentElement.tagName);\n if (parentElementTagName !== lastSection.tagName) {\n this._closeCurrentSection();\n this._updateStateFromElement(parentElement);\n }\n }\n\n // if we've broken out of a list due to nested section-level elements we\n // can hit the next list item without having a list section in the current\n // state. In this instance we find the parent list node and use it to\n // re-initialize the state with a new list section\n if (isListItem && !(this.state.section.isListItem || this.state.section.isListSection) && !lastSection.isListSection) {\n this._closeCurrentSection();\n this._updateStateFromElement(node.parentElement);\n }\n\n // if we have consecutive list sections of different types (ul, ol) then\n // ensure we close the current section and start a new one\n var isNewListSection = lastSection && lastSection.isListSection && this.state.section.isListItem && isListSection && tagName !== lastSection.tagName;\n\n if (isNewListSection || isListSection && !isNestedListSection || isMarkupSection || isListItem) {\n // don't break out of the list for list items that contain a single

    .\n // deals with typical case of

  • Text

  • Text

  • \n if (this.state.section.isListItem && tagName === 'p' && !node.nextSibling && (0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(node.parentElement.tagName))) {\n this.parseElementNode(node);\n return;\n }\n\n // avoid creating empty paragraphs due to wrapper elements around\n // section-creating elements\n if (this.state.section.isMarkerable && !this.state.text && this.state.section.markers.length === 0) {\n this.state.section = null;\n } else {\n this._closeCurrentSection();\n }\n\n this._updateStateFromElement(node);\n }\n\n if (this.state.section.isListSection) {\n // ensure the list section is closed and added to the sections list.\n // _closeCurrentSection handles pushing list items onto the list section\n this._closeCurrentSection();\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(node.childNodes, function (node) {\n _this3.parseNode(node);\n });\n return;\n }\n }\n\n switch (node.nodeType) {\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.TEXT:\n this.parseTextNode(node);\n break;\n case _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT:\n this.parseElementNode(node);\n break;\n }\n }\n }, {\n key: 'parseElementNode',\n value: function parseElementNode(element) {\n var _state$markups,\n _this4 = this;\n\n var state = this.state;\n\n var markups = this._markupsFromElement(element);\n if (markups.length && state.text.length && state.section.isMarkerable) {\n this._createMarker();\n }\n (_state$markups = state.markups).push.apply(_state$markups, _toConsumableArray(markups));\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.childNodes, function (node) {\n _this4.parseNode(node);\n });\n\n if (markups.length && state.text.length && state.section.isMarkerable) {\n // create the marker started for this node\n this._createMarker();\n }\n\n // pop the current markups from the stack\n state.markups.splice(-markups.length, markups.length);\n }\n }, {\n key: 'parseTextNode',\n value: function parseTextNode(textNode) {\n var state = this.state;\n\n state.text += sanitize(textNode.textContent);\n }\n }, {\n key: '_updateStateFromElement',\n value: function _updateStateFromElement(element) {\n var state = this.state;\n\n state.section = this._createSectionFromElement(element);\n state.markups = this._markupsFromElement(element);\n state.text = '';\n }\n }, {\n key: '_closeCurrentSection',\n value: function _closeCurrentSection() {\n var sections = this.sections;\n var state = this.state;\n\n var lastSection = sections[sections.length - 1];\n\n if (!state.section) {\n return;\n }\n\n // close a trailing text node if it exists\n if (state.text.length && state.section.isMarkerable) {\n this._createMarker();\n }\n\n // push listItems onto the listSection or add a new section\n if (state.section.isListItem && lastSection && lastSection.isListSection) {\n (0, _mobiledocKitParsersDom.trimSectionText)(state.section);\n lastSection.items.append(state.section);\n } else {\n // avoid creating empty markup sections, especially useful for indented source\n if (state.section.isMarkerable && !state.section.text.trim() && !(0, _mobiledocKitUtilsArrayUtils.any)(state.section.markers, function (marker) {\n return marker.isAtom;\n })) {\n state.section = null;\n state.text = '';\n return;\n }\n\n // remove empty list sections before creating a new section\n if (lastSection && lastSection.isListSection && lastSection.items.length === 0) {\n sections.pop();\n }\n\n sections.push(state.section);\n }\n\n state.section = null;\n state.text = '';\n }\n }, {\n key: '_markupsFromElement',\n value: function _markupsFromElement(element) {\n var builder = this.builder;\n\n var markups = [];\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n return markups;\n }\n\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n if (this._isValidMarkupForElement(tagName, element)) {\n markups.push(builder.createMarkup(tagName, (0, _mobiledocKitUtilsDomUtils.getAttributes)(element)));\n }\n\n this._markupsFromElementStyle(element).forEach(function (markup) {\n return markups.push(markup);\n });\n\n return markups;\n }\n }, {\n key: '_isValidMarkupForElement',\n value: function _isValidMarkupForElement(tagName, element) {\n if (_mobiledocKitModelsMarkup.VALID_MARKUP_TAGNAMES.indexOf(tagName) === -1) {\n return false;\n } else if (tagName === 'b') {\n // google docs add a that should not\n // create a \"b\" markup\n return element.style.fontWeight !== 'normal';\n }\n return true;\n }\n }, {\n key: '_markupsFromElementStyle',\n value: function _markupsFromElementStyle(element) {\n var builder = this.builder;\n\n var markups = [];\n var _element$style = element.style;\n var fontStyle = _element$style.fontStyle;\n var fontWeight = _element$style.fontWeight;\n\n if (fontStyle === 'italic') {\n markups.push(builder.createMarkup('em'));\n }\n if (fontWeight === 'bold' || fontWeight === '700') {\n markups.push(builder.createMarkup('strong'));\n }\n return markups;\n }\n }, {\n key: '_createMarker',\n value: function _createMarker() {\n var state = this.state;\n\n var text = (0, _mobiledocKitParsersDom.transformHTMLText)(state.text);\n var marker = this.builder.createMarker(text, state.markups);\n state.section.markers.append(marker);\n state.text = '';\n }\n }, {\n key: '_getSectionDetails',\n value: function _getSectionDetails(element) {\n var sectionType = undefined,\n tagName = undefined,\n inferredTagName = false;\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(element)) {\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n inferredTagName = true;\n } else {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName);\n\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListSection.VALID_LIST_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsListItem.VALID_LIST_ITEM_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.LIST_ITEM_TYPE;\n } else if ((0, _mobiledocKitUtilsArrayUtils.contains)(_mobiledocKitModelsMarkupSection.VALID_MARKUP_SECTION_TAGNAMES, tagName)) {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n } else {\n sectionType = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE;\n tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME;\n inferredTagName = true;\n }\n }\n\n return { sectionType: sectionType, tagName: tagName, inferredTagName: inferredTagName };\n }\n }, {\n key: '_createSectionFromElement',\n value: function _createSectionFromElement(element) {\n var builder = this.builder;\n\n var section = undefined;\n\n var _getSectionDetails2 = this._getSectionDetails(element);\n\n var tagName = _getSectionDetails2.tagName;\n var sectionType = _getSectionDetails2.sectionType;\n var inferredTagName = _getSectionDetails2.inferredTagName;\n\n switch (sectionType) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n section = builder.createListSection(tagName);\n break;\n case _mobiledocKitModelsTypes.LIST_ITEM_TYPE:\n section = builder.createListItem();\n break;\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = builder.createMarkupSection(tagName);\n section._inferredTagName = inferredTagName;\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Cannot parse section from element', false);\n }\n\n return section;\n }\n }, {\n key: '_isSkippable',\n value: function _isSkippable(element) {\n return (0, _mobiledocKitUtilsDomUtils.isCommentNode)(element) || element.nodeType === _mobiledocKitUtilsDomUtils.NODE_TYPES.ELEMENT && (0, _mobiledocKitUtilsArrayUtils.contains)(SKIPPABLE_ELEMENT_TAG_NAMES, (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(element.tagName));\n }\n }]);\n\n return SectionParser;\n })();\n\n exports['default'] = SectionParser;\n});","define('mobiledoc-kit/parsers/text', ['exports', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/types', 'mobiledoc-kit/models/markup-section'], function (exports, _mobiledocKitUtilsAssert, _mobiledocKitModelsTypes, _mobiledocKitModelsMarkupSection) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var UL_LI_REGEX = /^\\* (.*)$/;\n var OL_LI_REGEX = /^\\d\\.? (.*)$/;\n var CR = '\\r';\n var LF = '\\n';\n var CR_REGEX = new RegExp(CR, 'g');\n var CR_LF_REGEX = new RegExp(CR + LF, 'g');\n\n var SECTION_BREAK = LF;\n\n exports.SECTION_BREAK = SECTION_BREAK;\n function normalizeLineEndings(text) {\n return text.replace(CR_LF_REGEX, LF).replace(CR_REGEX, LF);\n }\n\n var TextParser = (function () {\n function TextParser(builder, options) {\n _classCallCheck(this, TextParser);\n\n this.builder = builder;\n this.options = options;\n\n this.post = this.builder.createPost();\n this.prevSection = null;\n }\n\n /**\n * @param {String} text to parse\n * @return {Post} a post abstract\n */\n\n _createClass(TextParser, [{\n key: 'parse',\n value: function parse(text) {\n var _this = this;\n\n text = normalizeLineEndings(text);\n text.split(SECTION_BREAK).forEach(function (text) {\n var section = _this._parseSection(text);\n _this._appendSection(section);\n });\n\n return this.post;\n }\n }, {\n key: '_parseSection',\n value: function _parseSection(text) {\n var tagName = _mobiledocKitModelsMarkupSection.DEFAULT_TAG_NAME,\n type = _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n section = undefined;\n\n if (UL_LI_REGEX.test(text)) {\n tagName = 'ul';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(UL_LI_REGEX)[1];\n } else if (OL_LI_REGEX.test(text)) {\n tagName = 'ol';\n type = _mobiledocKitModelsTypes.LIST_SECTION_TYPE;\n text = text.match(OL_LI_REGEX)[1];\n }\n\n var markers = [this.builder.createMarker(text)];\n\n switch (type) {\n case _mobiledocKitModelsTypes.LIST_SECTION_TYPE:\n {\n var item = this.builder.createListItem(markers);\n var list = this.builder.createListSection(tagName, [item]);\n section = list;\n break;\n }\n case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE:\n section = this.builder.createMarkupSection(tagName, markers);\n break;\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown type encountered ' + type, false);\n }\n\n return section;\n }\n }, {\n key: '_appendSection',\n value: function _appendSection(section) {\n var _this2 = this;\n\n var isSameListSection = section.isListSection && this.prevSection && this.prevSection.isListSection && this.prevSection.tagName === section.tagName;\n\n if (isSameListSection) {\n section.items.forEach(function (item) {\n _this2.prevSection.items.append(item.clone());\n });\n } else {\n this.post.sections.insertAfter(section, this.prevSection);\n this.prevSection = section;\n }\n }\n }]);\n\n return TextParser;\n })();\n\n exports['default'] = TextParser;\n});","define('mobiledoc-kit/renderers/editor-dom', ['exports', 'mobiledoc-kit/models/card-node', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/atom-node', 'mobiledoc-kit/models/types', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/models/markup-section', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/utils/characters'], function (exports, _mobiledocKitModelsCardNode, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsAtomNode, _mobiledocKitModelsTypes, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitModelsMarkupSection, _mobiledocKitUtilsAssert, _mobiledocKitUtilsCharacters) {\n 'use strict';\n\n var _destroyHooks;\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var CARD_ELEMENT_CLASS_NAME = '__mobiledoc-card';\n exports.CARD_ELEMENT_CLASS_NAME = CARD_ELEMENT_CLASS_NAME;\n var NO_BREAK_SPACE = ' ';\n exports.NO_BREAK_SPACE = NO_BREAK_SPACE;\n var TAB_CHARACTER = ' ';\n exports.TAB_CHARACTER = TAB_CHARACTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n var ZWNJ = '‌';\n exports.ZWNJ = ZWNJ;\n var ATOM_CLASS_NAME = '-mobiledoc-kit__atom';\n exports.ATOM_CLASS_NAME = ATOM_CLASS_NAME;\n var EDITOR_HAS_NO_CONTENT_CLASS_NAME = '__has-no-content';\n exports.EDITOR_HAS_NO_CONTENT_CLASS_NAME = EDITOR_HAS_NO_CONTENT_CLASS_NAME;\n var EDITOR_ELEMENT_CLASS_NAME = '__mobiledoc-editor';\n\n exports.EDITOR_ELEMENT_CLASS_NAME = EDITOR_ELEMENT_CLASS_NAME;\n function createElementFromMarkup(doc, markup) {\n var element = doc.createElement(markup.tagName);\n Object.keys(markup.attributes).forEach(function (k) {\n element.setAttribute(k, markup.attributes[k]);\n });\n return element;\n }\n\n var TWO_SPACES = '' + SPACE + SPACE;\n var SPACE_AND_NO_BREAK = '' + SPACE + NO_BREAK_SPACE;\n var SPACES_REGEX = new RegExp(TWO_SPACES, 'g');\n var TAB_REGEX = new RegExp(_mobiledocKitUtilsCharacters.TAB, 'g');\n var endsWithSpace = function endsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.endsWith)(text, SPACE);\n };\n var startsWithSpace = function startsWithSpace(text) {\n return (0, _mobiledocKitUtilsStringUtils.startsWith)(text, SPACE);\n };\n\n // FIXME: This can be done more efficiently with a single pass\n // building a correct string based on the original.\n function renderHTMLText(marker) {\n var text = marker.value;\n text = text.replace(SPACES_REGEX, SPACE_AND_NO_BREAK).replace(TAB_REGEX, TAB_CHARACTER);\n\n // If the first marker has a leading space or the last marker has a\n // trailing space, the browser will collapse the space when we position\n // the cursor.\n // See https://github.com/bustle/mobiledoc-kit/issues/68\n // and https://github.com/bustle/mobiledoc-kit/issues/75\n if (marker.isMarker && endsWithSpace(text) && !marker.next) {\n text = text.substr(0, text.length - 1) + NO_BREAK_SPACE;\n }\n if (marker.isMarker && startsWithSpace(text) && (!marker.prev || marker.prev.isMarker && endsWithSpace(marker.prev.value))) {\n text = NO_BREAK_SPACE + text.substr(1);\n }\n return text;\n }\n\n // ascends from element upward, returning the last parent node that is not\n // parentElement\n function penultimateParentOf(element, parentElement) {\n while (parentElement && element.parentNode !== parentElement && element.parentNode !== document.body // ensure the while loop stops\n ) {\n element = element.parentNode;\n }\n return element;\n }\n\n function setSectionAttributesOnElement(section, element) {\n section.eachAttribute(function (key, value) {\n element.setAttribute(key, value);\n });\n }\n\n function renderMarkupSection(section) {\n var element = undefined;\n if (_mobiledocKitModelsMarkupSection.MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) {\n element = document.createElement(section.tagName);\n } else {\n element = document.createElement('div');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(element, section.tagName);\n }\n\n setSectionAttributesOnElement(section, element);\n\n return element;\n }\n\n function renderListSection(section) {\n var element = document.createElement(section.tagName);\n\n setSectionAttributesOnElement(section, element);\n\n return element;\n }\n\n function renderListItem() {\n return document.createElement('li');\n }\n\n function renderCursorPlaceholder() {\n return document.createElement('br');\n }\n\n function renderInlineCursorPlaceholder() {\n return document.createTextNode(ZWNJ);\n }\n\n function renderCard() {\n var wrapper = document.createElement('div');\n var cardElement = document.createElement('div');\n cardElement.contentEditable = false;\n (0, _mobiledocKitUtilsDomUtils.addClassName)(cardElement, CARD_ELEMENT_CLASS_NAME);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n wrapper.appendChild(cardElement);\n wrapper.appendChild(renderInlineCursorPlaceholder());\n return { wrapper: wrapper, cardElement: cardElement };\n }\n\n /**\n * Wrap the element in all of the opened markups\n * @return {DOMElement} the wrapped element\n * @private\n */\n function wrapElement(element, openedMarkups) {\n var wrappedElement = element;\n\n for (var i = openedMarkups.length - 1; i >= 0; i--) {\n var markup = openedMarkups[i];\n var openedElement = createElementFromMarkup(document, markup);\n openedElement.appendChild(wrappedElement);\n wrappedElement = openedElement;\n }\n\n return wrappedElement;\n }\n\n // Attach the element to its parent element at the correct position based on the\n // previousRenderNode\n function attachElementToParent(element, parentElement) {\n var previousRenderNode = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n if (previousRenderNode) {\n var previousSibling = previousRenderNode.element;\n var previousSiblingPenultimate = penultimateParentOf(previousSibling, parentElement);\n parentElement.insertBefore(element, previousSiblingPenultimate.nextSibling);\n } else {\n parentElement.insertBefore(element, parentElement.firstChild);\n }\n }\n\n function renderAtom(atom, element, previousRenderNode) {\n var atomElement = document.createElement('span');\n atomElement.contentEditable = false;\n\n var wrapper = document.createElement('span');\n (0, _mobiledocKitUtilsDomUtils.addClassName)(wrapper, ATOM_CLASS_NAME);\n var headTextNode = renderInlineCursorPlaceholder();\n var tailTextNode = renderInlineCursorPlaceholder();\n\n wrapper.appendChild(headTextNode);\n wrapper.appendChild(atomElement);\n wrapper.appendChild(tailTextNode);\n\n var wrappedElement = wrapElement(wrapper, atom.openedMarkups);\n attachElementToParent(wrappedElement, element, previousRenderNode);\n\n return {\n markupElement: wrappedElement,\n wrapper: wrapper,\n atomElement: atomElement,\n headTextNode: headTextNode,\n tailTextNode: tailTextNode\n };\n }\n\n function getNextMarkerElement(renderNode) {\n var element = renderNode.element.parentNode;\n var marker = renderNode.postNode;\n var closedCount = marker.closedMarkups.length;\n\n while (closedCount--) {\n element = element.parentNode;\n }\n return element;\n }\n\n /**\n * Render the marker\n * @param {Marker} marker the marker to render\n * @param {DOMNode} element the element to attach the rendered marker to\n * @param {RenderNode} [previousRenderNode] The render node before this one, which\n * affects the determination of where to insert this rendered marker.\n * @return {Object} With properties `element` and `markupElement`.\n * The element (textNode) that has the text for\n * this marker, and the outermost rendered element. If the marker has no\n * markups, element and markupElement will be the same textNode\n * @private\n */\n function renderMarker(marker, parentElement, previousRenderNode) {\n var text = renderHTMLText(marker);\n\n var element = document.createTextNode(text);\n var markupElement = wrapElement(element, marker.openedMarkups);\n attachElementToParent(markupElement, parentElement, previousRenderNode);\n\n return { element: element, markupElement: markupElement };\n }\n\n // Attach the render node's element to the DOM,\n // replacing the originalElement if it exists\n function attachRenderNodeElementToDOM(renderNode) {\n var originalElement = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n var element = renderNode.element;\n var hasRendered = !!originalElement;\n\n if (hasRendered) {\n var parentElement = renderNode.parent.element;\n parentElement.replaceChild(element, originalElement);\n } else {\n var parentElement = undefined,\n nextSiblingElement = undefined;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n parentElement = previousElement.parentNode;\n nextSiblingElement = previousElement.nextSibling;\n } else {\n parentElement = renderNode.parent.element;\n nextSiblingElement = parentElement.firstChild;\n }\n parentElement.insertBefore(element, nextSiblingElement);\n }\n }\n\n function removeRenderNodeSectionFromParent(renderNode, section) {\n var parent = renderNode.parent.postNode;\n parent.sections.remove(section);\n }\n\n function removeRenderNodeElementFromParent(renderNode) {\n if (renderNode.element && renderNode.element.parentNode) {\n renderNode.element.parentNode.removeChild(renderNode.element);\n }\n }\n\n function validateCards() {\n var cards = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(cards, function (card) {\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define type \"dom\", has: \"' + card.type + '\"', card.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Card \"' + card.name + '\" must define `render` method', !!card.render);\n });\n return cards;\n }\n\n function validateAtoms() {\n var atoms = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)(atoms, function (atom) {\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define type \"dom\", has: \"' + atom.type + '\"', atom.type === 'dom');\n (0, _mobiledocKitUtilsAssert['default'])('Atom \"' + atom.name + '\" must define `render` method', !!atom.render);\n });\n return atoms;\n }\n\n var Visitor = (function () {\n function Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Visitor);\n\n this.editor = editor;\n this.cards = validateCards(cards);\n this.atoms = validateAtoms(atoms);\n this.unknownCardHandler = unknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler;\n this.options = options;\n }\n\n _createClass(Visitor, [{\n key: '_findCard',\n value: function _findCard(cardName) {\n var card = (0, _mobiledocKitUtilsArrayUtils.detect)(this.cards, function (card) {\n return card.name === cardName;\n });\n return card || this._createUnknownCard(cardName);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(cardName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown card \"' + cardName + '\" found, but no unknownCardHandler is defined', !!this.unknownCardHandler);\n\n return {\n name: cardName,\n type: 'dom',\n render: this.unknownCardHandler,\n edit: this.unknownCardHandler\n };\n }\n }, {\n key: '_findAtom',\n value: function _findAtom(atomName) {\n var atom = (0, _mobiledocKitUtilsArrayUtils.detect)(this.atoms, function (atom) {\n return atom.name === atomName;\n });\n return atom || this._createUnknownAtom(atomName);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(atomName) {\n (0, _mobiledocKitUtilsAssert['default'])('Unknown atom \"' + atomName + '\" found, but no unknownAtomHandler is defined', !!this.unknownAtomHandler);\n\n return {\n name: atomName,\n type: 'dom',\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: _mobiledocKitModelsTypes.POST_TYPE,\n value: function value(renderNode, post, visit) {\n if (!renderNode.element) {\n renderNode.element = document.createElement('div');\n }\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_ELEMENT_CLASS_NAME);\n if (post.hasContent) {\n (0, _mobiledocKitUtilsDomUtils.removeClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n } else {\n (0, _mobiledocKitUtilsDomUtils.addClassName)(renderNode.element, EDITOR_HAS_NO_CONTENT_CLASS_NAME);\n }\n visit(renderNode, post.sections);\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n // Always rerender the section -- its tag name or attributes may have changed.\n // TODO make this smarter, only rerendering and replacing the element when necessary\n renderNode.element = renderMarkupSection(section);\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n if (section.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, section.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_SECTION_TYPE,\n value: function value(renderNode, section, visit) {\n var originalElement = renderNode.element;\n\n renderNode.element = renderListSection(section);\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var visitAll = true;\n visit(renderNode, section.items, visitAll);\n }\n }, {\n key: _mobiledocKitModelsTypes.LIST_ITEM_TYPE,\n value: function value(renderNode, item, visit) {\n // FIXME do we need to do anything special for rerenders?\n renderNode.element = renderListItem();\n renderNode.cursorElement = null;\n attachRenderNodeElementToDOM(renderNode, null);\n\n if (item.isBlank) {\n var cursorPlaceholder = renderCursorPlaceholder();\n renderNode.element.appendChild(cursorPlaceholder);\n renderNode.cursorElement = cursorPlaceholder;\n } else {\n var visitAll = true;\n visit(renderNode, item.markers, visitAll);\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.MARKER_TYPE,\n value: function value(renderNode, marker) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var _renderMarker = renderMarker(marker, parentElement, renderNode.prev);\n\n var element = _renderMarker.element;\n var markupElement = _renderMarker.markupElement;\n\n renderNode.element = element;\n renderNode.markupElement = markupElement;\n }\n }, {\n key: _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE,\n value: function value(renderNode, section) {\n if (renderNode.element) {\n if (renderNode.element.src !== section.src) {\n renderNode.element.src = section.src;\n }\n } else {\n var element = document.createElement('img');\n element.src = section.src;\n if (renderNode.prev) {\n var previousElement = renderNode.prev.element;\n var nextElement = previousElement.nextSibling;\n if (nextElement) {\n nextElement.parentNode.insertBefore(element, nextElement);\n }\n }\n if (!element.parentNode) {\n renderNode.parent.element.appendChild(element);\n }\n renderNode.element = element;\n }\n }\n }, {\n key: _mobiledocKitModelsTypes.CARD_TYPE,\n value: function value(renderNode, section) {\n var originalElement = renderNode.element;\n var editor = this.editor;\n var options = this.options;\n\n var card = this._findCard(section.name);\n\n var _renderCard = renderCard();\n\n var wrapper = _renderCard.wrapper;\n var cardElement = _renderCard.cardElement;\n\n renderNode.element = wrapper;\n attachRenderNodeElementToDOM(renderNode, originalElement);\n\n var cardNode = new _mobiledocKitModelsCardNode['default'](editor, card, section, cardElement, options);\n renderNode.cardNode = cardNode;\n\n var initialMode = section._initialMode;\n cardNode[initialMode]();\n }\n }, {\n key: _mobiledocKitModelsTypes.ATOM_TYPE,\n value: function value(renderNode, atomModel) {\n var parentElement = undefined;\n\n if (renderNode.prev) {\n parentElement = getNextMarkerElement(renderNode.prev);\n } else {\n parentElement = renderNode.parent.element;\n }\n\n var editor = this.editor;\n var options = this.options;\n\n var _renderAtom = renderAtom(atomModel, parentElement, renderNode.prev);\n\n var wrapper = _renderAtom.wrapper;\n var markupElement = _renderAtom.markupElement;\n var atomElement = _renderAtom.atomElement;\n var headTextNode = _renderAtom.headTextNode;\n var tailTextNode = _renderAtom.tailTextNode;\n\n var atom = this._findAtom(atomModel.name);\n\n var atomNode = renderNode.atomNode;\n if (!atomNode) {\n // create new AtomNode\n atomNode = new _mobiledocKitModelsAtomNode['default'](editor, atom, atomModel, atomElement, options);\n } else {\n // retarget atomNode to new atom element\n atomNode.element = atomElement;\n }\n\n atomNode.render();\n\n renderNode.atomNode = atomNode;\n renderNode.element = wrapper;\n renderNode.headTextNode = headTextNode;\n renderNode.tailTextNode = tailTextNode;\n renderNode.markupElement = markupElement;\n }\n }]);\n\n return Visitor;\n })();\n\n var destroyHooks = (_destroyHooks = {}, _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.POST_TYPE, function () /*renderNode, post*/{\n (0, _mobiledocKitUtilsAssert['default'])('post destruction is not supported by the renderer', false);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (renderNode, li) {\n removeRenderNodeSectionFromParent(renderNode, li);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.MARKER_TYPE, function (renderNode, marker) {\n // FIXME before we render marker, should delete previous renderNode's element\n // and up until the next marker element\n\n // If an atom throws during render we may end up later destroying a renderNode\n // that has not rendered yet, so exit early here if so.\n if (!renderNode.isRendered) {\n return;\n }\n var markupElement = renderNode.markupElement;\n\n if (marker.section) {\n marker.section.markers.remove(marker);\n }\n\n if (markupElement.parentNode) {\n // if no parentNode, the browser already removed this element\n markupElement.parentNode.removeChild(markupElement);\n }\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (renderNode, section) {\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.CARD_TYPE, function (renderNode, section) {\n if (renderNode.cardNode) {\n renderNode.cardNode.teardown();\n }\n removeRenderNodeSectionFromParent(renderNode, section);\n removeRenderNodeElementFromParent(renderNode);\n }), _defineProperty(_destroyHooks, _mobiledocKitModelsTypes.ATOM_TYPE, function (renderNode, atom) {\n if (renderNode.atomNode) {\n renderNode.atomNode.teardown();\n }\n\n // an atom is a kind of marker so just call its destroy hook vs copying here\n destroyHooks[_mobiledocKitModelsTypes.MARKER_TYPE](renderNode, atom);\n }), _destroyHooks);\n\n // removes children from parentNode (a RenderNode) that are scheduled for removal\n function removeDestroyedChildren(parentNode) {\n var forceRemoval = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n var child = parentNode.childNodes.head;\n var nextChild = undefined,\n method = undefined;\n while (child) {\n nextChild = child.next;\n if (child.isRemoved || forceRemoval) {\n removeDestroyedChildren(child, true);\n method = child.postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('editor-dom cannot destroy \"' + method + '\"', !!destroyHooks[method]);\n destroyHooks[method](child, child.postNode);\n parentNode.childNodes.remove(child);\n }\n child = nextChild;\n }\n }\n\n // Find an existing render node for the given postNode, or\n // create one, insert it into the tree, and return it\n function lookupNode(renderTree, parentNode, postNode, previousNode) {\n if (postNode.renderNode) {\n return postNode.renderNode;\n } else {\n var renderNode = renderTree.buildRenderNode(postNode);\n parentNode.childNodes.insertAfter(renderNode, previousNode);\n return renderNode;\n }\n }\n\n var Renderer = (function () {\n function Renderer(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options) {\n _classCallCheck(this, Renderer);\n\n this.editor = editor;\n this.visitor = new Visitor(editor, cards, atoms, unknownCardHandler, unknownAtomHandler, options);\n this.nodes = [];\n this.hasRendered = false;\n }\n\n _createClass(Renderer, [{\n key: 'destroy',\n value: function destroy() {\n if (!this.hasRendered) {\n return;\n }\n var renderNode = this.renderTree.rootNode;\n var force = true;\n removeDestroyedChildren(renderNode, force);\n }\n }, {\n key: 'visit',\n value: function visit(renderTree, parentNode, postNodes) {\n var _this = this;\n\n var visitAll = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];\n\n var previousNode = undefined;\n postNodes.forEach(function (postNode) {\n var node = lookupNode(renderTree, parentNode, postNode, previousNode);\n if (node.isDirty || visitAll) {\n _this.nodes.push(node);\n }\n previousNode = node;\n });\n }\n }, {\n key: 'render',\n value: function render(renderTree) {\n var _this2 = this;\n\n this.hasRendered = true;\n this.renderTree = renderTree;\n var renderNode = renderTree.rootNode;\n var method = undefined,\n postNode = undefined;\n\n while (renderNode) {\n removeDestroyedChildren(renderNode);\n postNode = renderNode.postNode;\n\n method = postNode.type;\n (0, _mobiledocKitUtilsAssert['default'])('EditorDom visitor cannot handle type ' + method, !!this.visitor[method]);\n this.visitor[method](renderNode, postNode, function () {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return _this2.visit.apply(_this2, [renderTree].concat(args));\n });\n renderNode.markClean();\n renderNode = this.nodes.shift();\n }\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-kit/renderers/mobiledoc/0-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.2.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, name, payload]);\n },\n openPost: function openPost() {\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n sections: [this.markerTypes, this.sections]\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-1', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.1';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3-2', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.2';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName, attributes) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers, attributes]);\n },\n openListSection: function openListSection(tagName, attributes) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items, attributes]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc/0-3', ['exports', 'mobiledoc-kit/utils/compiler', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitUtilsCompiler, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) {\n 'use strict';\n\n var _visitor;\n\n function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n var MOBILEDOC_VERSION = '0.3.0';\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var MOBILEDOC_MARKUP_SECTION_TYPE = 1;\n exports.MOBILEDOC_MARKUP_SECTION_TYPE = MOBILEDOC_MARKUP_SECTION_TYPE;\n var MOBILEDOC_IMAGE_SECTION_TYPE = 2;\n exports.MOBILEDOC_IMAGE_SECTION_TYPE = MOBILEDOC_IMAGE_SECTION_TYPE;\n var MOBILEDOC_LIST_SECTION_TYPE = 3;\n exports.MOBILEDOC_LIST_SECTION_TYPE = MOBILEDOC_LIST_SECTION_TYPE;\n var MOBILEDOC_CARD_SECTION_TYPE = 10;\n\n exports.MOBILEDOC_CARD_SECTION_TYPE = MOBILEDOC_CARD_SECTION_TYPE;\n var MOBILEDOC_MARKUP_MARKER_TYPE = 0;\n exports.MOBILEDOC_MARKUP_MARKER_TYPE = MOBILEDOC_MARKUP_MARKER_TYPE;\n var MOBILEDOC_ATOM_MARKER_TYPE = 1;\n\n exports.MOBILEDOC_ATOM_MARKER_TYPE = MOBILEDOC_ATOM_MARKER_TYPE;\n var visitor = (_visitor = {}, _defineProperty(_visitor, _mobiledocKitModelsTypes.POST_TYPE, function (node, opcodes) {\n opcodes.push(['openPost']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.sections, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkupSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openListSection', node.tagName]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.items, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.LIST_ITEM_TYPE, function (node, opcodes) {\n opcodes.push(['openListItem']);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.markers, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE, function (node, opcodes) {\n opcodes.push(['openImageSection', node.src]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.CARD_TYPE, function (node, opcodes) {\n opcodes.push(['openCardSection', node.name, node.payload]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKER_TYPE, function (node, opcodes) {\n opcodes.push(['openMarker', node.closedMarkups.length, node.value]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.MARKUP_TYPE, function (node, opcodes) {\n opcodes.push(['openMarkup', node.tagName, (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(node.attributes)]);\n }), _defineProperty(_visitor, _mobiledocKitModelsTypes.ATOM_TYPE, function (node, opcodes) {\n opcodes.push(['openAtom', node.closedMarkups.length, node.name, node.value, node.payload]);\n (0, _mobiledocKitUtilsCompiler.visitArray)(visitor, node.openedMarkups, opcodes);\n }), _visitor);\n\n var postOpcodeCompiler = {\n openMarker: function openMarker(closeCount, value) {\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_MARKUP_MARKER_TYPE, this.markupMarkerIds, closeCount, value || '']);\n },\n openMarkupSection: function openMarkupSection(tagName) {\n this.markers = [];\n this.sections.push([MOBILEDOC_MARKUP_SECTION_TYPE, tagName, this.markers]);\n },\n openListSection: function openListSection(tagName) {\n this.items = [];\n this.sections.push([MOBILEDOC_LIST_SECTION_TYPE, tagName, this.items]);\n },\n openListItem: function openListItem() {\n this.markers = [];\n this.items.push(this.markers);\n },\n openImageSection: function openImageSection(url) {\n this.sections.push([MOBILEDOC_IMAGE_SECTION_TYPE, url]);\n },\n openCardSection: function openCardSection(name, payload) {\n var index = this._addCardTypeIndex(name, payload);\n this.sections.push([MOBILEDOC_CARD_SECTION_TYPE, index]);\n },\n openAtom: function openAtom(closeCount, name, value, payload) {\n var index = this._addAtomTypeIndex(name, value, payload);\n this.markupMarkerIds = [];\n this.markers.push([MOBILEDOC_ATOM_MARKER_TYPE, this.markupMarkerIds, closeCount, index]);\n },\n openPost: function openPost() {\n this.atomTypes = [];\n this.cardTypes = [];\n this.markerTypes = [];\n this.sections = [];\n this.result = {\n version: MOBILEDOC_VERSION,\n atoms: this.atomTypes,\n cards: this.cardTypes,\n markups: this.markerTypes,\n sections: this.sections\n };\n },\n openMarkup: function openMarkup(tagName, attributes) {\n var index = this._findOrAddMarkerTypeIndex(tagName, attributes);\n this.markupMarkerIds.push(index);\n },\n _addCardTypeIndex: function _addCardTypeIndex(cardName, payload) {\n var cardType = [cardName, payload];\n this.cardTypes.push(cardType);\n return this.cardTypes.length - 1;\n },\n _addAtomTypeIndex: function _addAtomTypeIndex(atomName, atomValue, payload) {\n var atomType = [atomName, atomValue, payload];\n this.atomTypes.push(atomType);\n return this.atomTypes.length - 1;\n },\n _findOrAddMarkerTypeIndex: function _findOrAddMarkerTypeIndex(tagName, attributesArray) {\n if (!this._markerTypeCache) {\n this._markerTypeCache = {};\n }\n var key = tagName + '-' + attributesArray.join('-');\n\n var index = this._markerTypeCache[key];\n if (index === undefined) {\n var markerType = [tagName];\n if (attributesArray.length) {\n markerType.push(attributesArray);\n }\n this.markerTypes.push(markerType);\n\n index = this.markerTypes.length - 1;\n this._markerTypeCache[key] = index;\n }\n\n return index;\n }\n };\n\n /**\n * Render from post -> mobiledoc\n */\n exports['default'] = {\n /**\n * @param {Post}\n * @return {Mobiledoc}\n */\n render: function render(post) {\n var opcodes = [];\n (0, _mobiledocKitUtilsCompiler.visit)(visitor, post, opcodes);\n var compiler = Object.create(postOpcodeCompiler);\n (0, _mobiledocKitUtilsCompiler.compile)(compiler, opcodes);\n return compiler.result;\n }\n };\n});","define('mobiledoc-kit/renderers/mobiledoc', ['exports', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var MOBILEDOC_VERSION = _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION;\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n exports['default'] = {\n render: function render(post, version) {\n switch (version) {\n case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc02['default'].render(post);\n case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc03['default'].render(post);\n case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc031['default'].render(post);\n case undefined:\n case null:\n case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION:\n return _mobiledocKitRenderersMobiledoc032['default'].render(post);\n default:\n (0, _mobiledocKitUtilsAssert['default'])('Unknown version of mobiledoc renderer requested: ' + version, false);\n }\n }\n };\n});","define(\"mobiledoc-kit/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function detect(enumerable, callback) {\n if (enumerable.detect) {\n return enumerable.detect(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return enumerable[i];\n }\n }\n }\n }\n\n function any(enumerable, callback) {\n if (enumerable.any) {\n return enumerable.any(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (callback(enumerable[i])) {\n return true;\n }\n }\n\n return false;\n }\n\n function every(enumerable, callback) {\n if (enumerable.every) {\n return enumerable.every(callback);\n }\n\n for (var i = 0; i < enumerable.length; i++) {\n if (!callback(enumerable[i])) {\n return false;\n }\n }\n return true;\n }\n\n function toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n }\n\n /**\n * Useful for array-like things that aren't\n * actually arrays, like NodeList\n * @private\n */\n function forEach(enumerable, callback) {\n if (enumerable.forEach) {\n enumerable.forEach(callback);\n } else {\n for (var i = 0; i < enumerable.length; i++) {\n callback(enumerable[i], i);\n }\n }\n }\n\n function filter(enumerable, conditionFn) {\n var filtered = [];\n forEach(enumerable, function (i) {\n if (conditionFn(i)) {\n filtered.push(i);\n }\n });\n return filtered;\n }\n\n /**\n * @return {Integer} the number of items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItemLength(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return offset;\n }\n\n /**\n * @return {Array} the items that are the same, starting from the 0th index, in a and b\n * @private\n */\n function commonItems(listA, listB) {\n var offset = 0;\n while (offset < listA.length && offset < listB.length) {\n if (listA[offset] !== listB[offset]) {\n break;\n }\n offset++;\n }\n return listA.slice(0, offset);\n }\n\n // return new array without falsy items like ruby's `compact`\n function compact(enumerable) {\n return filter(enumerable, function (i) {\n return !!i;\n });\n }\n\n function reduce(enumerable, callback, initialValue) {\n var previousValue = initialValue;\n forEach(enumerable, function (val, index) {\n previousValue = callback(previousValue, val, index);\n });\n return previousValue;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n function kvArrayToObject(array) {\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n\n // check shallow equality of two non-nested arrays\n function isArrayEqual(arr1, arr2) {\n var l1 = arr1.length,\n l2 = arr2.length;\n if (l1 !== l2) {\n return false;\n }\n\n for (var i = 0; i < l1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n return true;\n }\n\n // return an object with only the valid keys\n function filterObject(object) {\n var validKeys = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];\n\n var result = {};\n forEach(filter(Object.keys(object), function (key) {\n return validKeys.indexOf(key) !== -1;\n }), function (key) {\n return result[key] = object[key];\n });\n return result;\n }\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function values(object) {\n return Object.keys(object).map(function (key) {\n return object[key];\n });\n }\n\n exports.detect = detect;\n exports.forEach = forEach;\n exports.any = any;\n exports.every = every;\n exports.filter = filter;\n exports.commonItemLength = commonItemLength;\n exports.commonItems = commonItems;\n exports.compact = compact;\n exports.reduce = reduce;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n exports.kvArrayToObject = kvArrayToObject;\n exports.isArrayEqual = isArrayEqual;\n exports.toArray = toArray;\n exports.filterObject = filterObject;\n exports.contains = contains;\n exports.values = values;\n});","define('mobiledoc-kit/utils/assert', ['exports', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n exports['default'] = function (message, conditional) {\n if (!conditional) {\n throw new _mobiledocKitUtilsMobiledocError['default'](message);\n }\n };\n});","define('mobiledoc-kit/utils/browser', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n isMac: function isMac() {\n return typeof window !== 'undefined' && window.navigator && /Mac/.test(window.navigator.platform);\n },\n isWin: function isWin() {\n return typeof window !== 'undefined' && window.navigator && /Win/.test(window.navigator.platform);\n }\n };\n});","define('mobiledoc-kit/utils/characters', ['exports'], function (exports) {\n 'use strict';\n\n var TAB = '\\t';\n exports.TAB = TAB;\n var ENTER = '\\n';\n exports.ENTER = ENTER;\n var SPACE = ' ';\n exports.SPACE = SPACE;\n});","define('mobiledoc-kit/utils/compiler', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports.visit = visit;\n exports.compile = compile;\n exports.visitArray = visitArray;\n\n function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }\n\n function visit(visitor, node, opcodes) {\n var method = node.type;\n (0, _mobiledocKitUtilsAssert['default'])('Cannot visit unknown type ' + method, !!visitor[method]);\n visitor[method](node, opcodes);\n }\n\n function compile(compiler, opcodes) {\n for (var i = 0, l = opcodes.length; i < l; i++) {\n var _opcodes$i = _toArray(opcodes[i]);\n\n var method = _opcodes$i[0];\n\n var params = _opcodes$i.slice(1);\n\n var _length = params.length;\n if (_length === 0) {\n compiler[method].call(compiler);\n } else if (_length === 1) {\n compiler[method].call(compiler, params[0]);\n } else if (_length === 2) {\n compiler[method].call(compiler, params[0], params[1]);\n } else {\n compiler[method].apply(compiler, params);\n }\n }\n }\n\n function visitArray(visitor, nodes, opcodes) {\n if (!nodes || nodes.length === 0) {\n return;\n }\n (0, _mobiledocKitUtilsArrayUtils.forEach)(nodes, function (node) {\n visit(visitor, node, opcodes);\n });\n }\n});","define(\"mobiledoc-kit/utils/copy\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function shallowCopyObject(object) {\n var copy = {};\n Object.keys(object).forEach(function (key) {\n copy[key] = object[key];\n });\n return copy;\n }\n\n exports.shallowCopyObject = shallowCopyObject;\n});","define('mobiledoc-kit/utils/cursor', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/key'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKey) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n exports.Position = _mobiledocKitUtilsCursorPosition['default'];\n exports.Range = _mobiledocKitUtilsCursorRange['default'];\n\n var Cursor = (function () {\n function Cursor(editor) {\n _classCallCheck(this, Cursor);\n\n this.editor = editor;\n this.renderTree = editor._renderTree;\n this.post = editor.post;\n }\n\n _createClass(Cursor, [{\n key: 'clearSelection',\n value: function clearSelection() {\n (0, _mobiledocKitUtilsSelectionUtils.clearSelection)();\n }\n\n /**\n * @return {Boolean} true when there is either a collapsed cursor in the\n * editor's element or a selection that is contained in the editor's element\n */\n }, {\n key: 'hasCursor',\n value: function hasCursor() {\n return this.editor.hasRendered && (this._hasCollapsedSelection() || this._hasSelection());\n }\n }, {\n key: 'hasSelection',\n value: function hasSelection() {\n return this.editor.hasRendered && this._hasSelection();\n }\n\n /**\n * @return {Boolean} Can the cursor be on this element?\n */\n }, {\n key: 'isAddressable',\n value: function isAddressable(element) {\n var renderTree = this.renderTree;\n\n var renderNode = renderTree.findRenderNodeFromElement(element);\n if (renderNode && renderNode.postNode.isCardSection) {\n var renderedElement = renderNode.element;\n\n // card sections have addressable text nodes containing ‌\n // as their first and last child\n if (element !== renderedElement && element !== renderedElement.firstChild && element !== renderedElement.lastChild) {\n return false;\n }\n }\n\n return !!renderNode;\n }\n\n /*\n * @return {Range} Cursor#Range object\n */\n }, {\n key: '_findNodeForPosition',\n value: function _findNodeForPosition(position) {\n var section = position.section;\n\n var node = undefined,\n offset = undefined;\n if (section.isCardSection) {\n offset = 0;\n if (position.offset === 0) {\n node = section.renderNode.element.firstChild;\n } else {\n node = section.renderNode.element.lastChild;\n }\n } else if (section.isBlank) {\n node = section.renderNode.cursorElement;\n offset = 0;\n } else {\n var marker = position.marker;\n var offsetInMarker = position.offsetInMarker;\n\n if (marker.isAtom) {\n if (offsetInMarker > 0) {\n // FIXME -- if there is a next marker, focus on it?\n offset = 0;\n node = marker.renderNode.tailTextNode;\n } else {\n offset = 0;\n node = marker.renderNode.headTextNode;\n }\n } else {\n node = marker.renderNode.element;\n offset = offsetInMarker;\n }\n }\n\n return { node: node, offset: offset };\n }\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n if (range.isBlank) {\n this.clearSelection();\n return;\n }\n\n var head = range.head;\n var tail = range.tail;\n var direction = range.direction;\n\n var _findNodeForPosition2 = this._findNodeForPosition(head);\n\n var headNode = _findNodeForPosition2.node;\n var headOffset = _findNodeForPosition2.offset;\n\n var _findNodeForPosition3 = this._findNodeForPosition(tail);\n\n var tailNode = _findNodeForPosition3.node;\n var tailOffset = _findNodeForPosition3.offset;\n\n this._moveToNode(headNode, headOffset, tailNode, tailOffset, direction);\n\n // Firefox sometimes doesn't keep focus in the editor after adding a card\n this.editor._ensureFocus();\n }\n }, {\n key: 'selectedText',\n value: function selectedText() {\n // FIXME remove this\n return this.selection.toString();\n }\n\n /**\n * @param {textNode} node\n * @param {integer} offset\n * @param {textNode} endNode\n * @param {integer} endOffset\n * @param {integer} direction forward or backward, default forward\n * @private\n */\n }, {\n key: '_moveToNode',\n value: function _moveToNode(node, offset, endNode, endOffset) {\n var direction = arguments.length <= 4 || arguments[4] === undefined ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : arguments[4];\n\n this.clearSelection();\n\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD) {\n var _ref = [endNode, endOffset, node, offset];\n node = _ref[0];\n offset = _ref[1];\n endNode = _ref[2];\n endOffset = _ref[3];\n }\n\n var range = document.createRange();\n range.setStart(node, offset);\n if (direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD && !!this.selection.extend) {\n this.selection.addRange(range);\n this.selection.extend(endNode, endOffset);\n } else {\n range.setEnd(endNode, endOffset);\n this.selection.addRange(range);\n }\n }\n }, {\n key: '_hasSelection',\n value: function _hasSelection() {\n var element = this.editor.element;\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange || _selectionRange.collapsed) {\n return false;\n }\n\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode) && (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.focusNode);\n }\n }, {\n key: '_hasCollapsedSelection',\n value: function _hasCollapsedSelection() {\n var _selectionRange = this._selectionRange;\n\n if (!_selectionRange) {\n return false;\n }\n\n var element = this.editor.element;\n return (0, _mobiledocKitUtilsDomUtils.containsNode)(element, this.selection.anchorNode);\n }\n }, {\n key: 'offsets',\n get: function get() {\n if (!this.hasCursor()) {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n\n var selection = this.selection;\n var renderTree = this.renderTree;\n\n var parentNode = this.editor.element;\n selection = (0, _mobiledocKitUtilsSelectionUtils.constrainSelectionTo)(selection, parentNode);\n\n var _comparePosition = (0, _mobiledocKitUtilsSelectionUtils.comparePosition)(selection);\n\n var headNode = _comparePosition.headNode;\n var headOffset = _comparePosition.headOffset;\n var tailNode = _comparePosition.tailNode;\n var tailOffset = _comparePosition.tailOffset;\n var direction = _comparePosition.direction;\n\n var headPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, headNode, headOffset);\n var tailPosition = _mobiledocKitUtilsCursorPosition['default'].fromNode(renderTree, tailNode, tailOffset);\n\n return new _mobiledocKitUtilsCursorRange['default'](headPosition, tailPosition, direction);\n }\n }, {\n key: 'selection',\n get: function get() {\n return window.getSelection();\n }\n }, {\n key: '_selectionRange',\n get: function get() {\n var selection = this.selection;\n\n if (selection.rangeCount === 0) {\n return null;\n }\n return selection.getRangeAt(0);\n }\n }]);\n\n return Cursor;\n })();\n\n exports['default'] = Cursor;\n});","define('mobiledoc-kit/utils/cursor/position', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/models/marker', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsAssert, _mobiledocKitModelsMarker, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsKey, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var FORWARD = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n var BACKWARD = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n\n // generated via http://xregexp.com/ to cover chars that \\w misses\n // (new XRegExp('\\\\p{Alphabetic}|[0-9]|_|:')).toString()\n var WORD_CHAR_REGEX = /[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͅͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևְ-ׇֽֿׁׂׅׄא-תװ-ײؐ-ؚؠ-ٗٙ-ٟٮ-ۓە-ۜۡ-ۭۨ-ۯۺ-ۼۿܐ-ܿݍ-ޱߊ-ߪߴߵߺࠀ-ࠗࠚ-ࠬࡀ-ࡘࢠ-ࢴࣣ-ࣰࣩ-ऻऽ-ौॎ-ॐॕ-ॣॱ-ঃঅ-ঌএঐও-নপ-রলশ-হঽ-ৄেৈোৌৎৗড়ঢ়য়-ৣৰৱਁ-ਃਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਾ-ੂੇੈੋੌੑਖ਼-ੜਫ਼ੰ-ੵઁ-ઃઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽ-ૅે-ૉોૌૐૠ-ૣૹଁ-ଃଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽ-ୄେୈୋୌୖୗଡ଼ଢ଼ୟ-ୣୱஂஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹா-ூெ-ைொ-ௌௐௗఀ-ఃఅ-ఌఎ-ఐఒ-నప-హఽ-ౄె-ైొ-ౌౕౖౘ-ౚౠ-ౣಁ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೄೆ-ೈೊ-ೌೕೖೞೠ-ೣೱೲഁ-ഃഅ-ഌഎ-ഐഒ-ഺഽ-ൄെ-ൈൊ-ൌൎൗൟ-ൣൺ-ൿංඃඅ-ඖක-නඳ-රලව-ෆා-ුූෘ-ෟෲෳก-ฺเ-ๆํກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ູົ-ຽເ-ໄໆໍໜ-ໟༀཀ-ཇཉ-ཬཱ-ཱྀྈ-ྗྙ-ྼက-ံးျ-ဿၐ-ၢၥ-ၨၮ-ႆႎႜႝႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ፟ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜓᜠ-ᜳᝀ-ᝓᝠ-ᝬᝮ-ᝰᝲᝳក-ឳា-ៈៗៜᠠ-ᡷᢀ-ᢪᢰ-ᣵᤀ-ᤞᤠ-ᤫᤰ-ᤸᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨛᨠ-ᩞᩡ-ᩴᪧᬀ-ᬳᬵ-ᭃᭅ-ᭋᮀ-ᮩᮬ-ᮯᮺ-ᯥᯧ-ᯱᰀ-ᰵᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳳᳵᳶᴀ-ᶿᷧ-ᷴḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⷠ-ⷿⸯ々-〇〡-〩〱-〵〸-〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙴ-ꙻꙿ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞭꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠧꡀ-ꡳꢀ-ꣃꣲ-ꣷꣻꣽꤊ-ꤪꤰ-ꥒꥠ-ꥼꦀ-ꦲꦴ-ꦿꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨶꩀ-ꩍꩠ-ꩶꩺꩾ-ꪾꫀꫂꫛ-ꫝꫠ-ꫯꫲ-ꫵꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯪ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]|[0-9]|_|:/;\n\n function findParentSectionFromNode(renderTree, node) {\n var renderNode = renderTree.findRenderNodeFromElement(node, function (renderNode) {\n return renderNode.postNode.isSection;\n });\n\n return renderNode && renderNode.postNode;\n }\n\n function findOffsetInMarkerable(markerable, node, offset) {\n var offsetInSection = 0;\n var marker = markerable.markers.head;\n while (marker) {\n var markerNode = marker.renderNode.element;\n if (markerNode === node) {\n return offsetInSection + offset;\n } else if (marker.isAtom) {\n if (marker.renderNode.headTextNode === node) {\n return offsetInSection;\n } else if (marker.renderNode.tailTextNode === node) {\n return offsetInSection + 1;\n }\n }\n\n offsetInSection += marker.length;\n marker = marker.next;\n }\n\n return offsetInSection;\n }\n\n function findOffsetInSection(section, node, offset) {\n if (section.isMarkerable) {\n return findOffsetInMarkerable(section, node, offset);\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('findOffsetInSection must be called with markerable or card section', section.isCardSection);\n\n var wrapperNode = section.renderNode.element;\n var endTextNode = wrapperNode.lastChild;\n if (node === endTextNode) {\n return 1;\n }\n return 0;\n }\n }\n\n var Position = undefined,\n BlankPosition = undefined;\n\n Position = (function () {\n /**\n * A position is a logical location (zero-width, or \"collapsed\") in a post,\n * typically between two characters in a section.\n * Two positions (a head and a tail) make up a {@link Range}.\n * @constructor\n */\n\n function Position(section) {\n var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];\n var isBlank = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n _classCallCheck(this, Position);\n\n if (!isBlank) {\n (0, _mobiledocKitUtilsAssert['default'])('Position must have a section that is addressable by the cursor', section && section.isLeafSection);\n (0, _mobiledocKitUtilsAssert['default'])('Position must have numeric offset', typeof offset === 'number');\n }\n\n this.section = section;\n this.offset = offset;\n this.isBlank = isBlank;\n }\n\n /**\n * @param {integer} x x-position in current viewport\n * @param {integer} y y-position in current viewport\n * @param {Editor} editor\n * @return {Position|null}\n */\n\n _createClass(Position, [{\n key: 'toRange',\n\n /**\n * Returns a range from this position to the given tail. If no explicit\n * tail is given this returns a collapsed range focused on this position.\n * @param {Position} [tail=this] The ending position\n * @return {Range}\n * @public\n */\n value: function toRange() {\n var tail = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0];\n var direction = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];\n\n return new _mobiledocKitUtilsCursorRange['default'](this, tail, direction);\n }\n }, {\n key: 'markerIn',\n\n /**\n * Returns the marker in `direction` from this position.\n * If the position is in the middle of a marker, the direction is irrelevant.\n * Otherwise, if the position is at a boundary between two markers, returns the\n * marker to the left if `direction` === BACKWARD and the marker to the right\n * if `direction` === FORWARD (assuming left-to-right text direction).\n * @param {Direction}\n * @return {Marker|undefined}\n */\n value: function markerIn(direction) {\n if (!this.isMarkerable) {\n return;\n }\n\n var marker = this.marker;\n var offsetInMarker = this.offsetInMarker;\n\n if (!marker) {\n return;\n }\n\n if (offsetInMarker > 0 && offsetInMarker < marker.length) {\n return marker;\n } else if (offsetInMarker === 0) {\n return direction === BACKWARD ? marker : marker.prev;\n } else if (offsetInMarker === marker.length) {\n return direction === FORWARD ? marker.next : marker;\n }\n }\n }, {\n key: 'isEqual',\n value: function isEqual(position) {\n return this.section === position.section && this.offset === position.offset;\n }\n\n /**\n * @return {Boolean} If this position is at the head of the post\n */\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return this.move(BACKWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the tail of the post\n */\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return this.move(FORWARD).isEqual(this);\n }\n\n /**\n * @return {Boolean} If this position is at the head of its section\n */\n }, {\n key: 'isHead',\n value: function isHead() {\n return this.isEqual(this.section.headPosition());\n }\n\n /**\n * @return {Boolean} If this position is at the tail of its section\n */\n }, {\n key: 'isTail',\n value: function isTail() {\n return this.isEqual(this.section.tailPosition());\n }\n\n /**\n * Move the position 1 unit in `direction`.\n *\n * @param {Number} units to move. > 0 moves right, < 0 moves left\n * @return {Position} Return a new position one unit in the given\n * direction. If the position is moving left and at the beginning of the post,\n * the same position will be returned. Same if the position is moving right and\n * at the end of the post.\n */\n }, {\n key: 'move',\n value: function move(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Position#move', typeof units === 'number');\n\n if (units < 0) {\n return this.moveLeft().move(++units);\n } else if (units > 0) {\n return this.moveRight().move(--units);\n } else {\n return this;\n }\n }\n\n /**\n * @param {Number} direction (FORWARD or BACKWARD)\n * @return {Position} The result of moving 1 \"word\" unit in `direction`\n */\n }, {\n key: 'moveWord',\n value: function moveWord(direction) {\n var isPostBoundary = direction === BACKWARD ? this.isHeadOfPost() : this.isTailOfPost();\n if (isPostBoundary) {\n return this;\n }\n\n if (!this.isMarkerable) {\n return this.move(direction);\n }\n\n var pos = this;\n\n // Helper fn to check if the pos is at the `dir` boundary of its section\n var isBoundary = function isBoundary(pos, dir) {\n return dir === BACKWARD ? pos.isHead() : pos.isTail();\n };\n // Get the char at this position (looking forward/right)\n var getChar = function getChar(pos) {\n var marker = pos.marker;\n var offsetInMarker = pos.offsetInMarker;\n\n return marker.charAt(offsetInMarker);\n };\n // Get the char in `dir` at this position\n var peekChar = function peekChar(pos, dir) {\n return dir === BACKWARD ? getChar(pos.move(BACKWARD)) : getChar(pos);\n };\n // Whether there is an atom in `dir` from this position\n var isAtom = function isAtom(pos, dir) {\n // Special case when position is at end, the marker associated with it is\n // the marker to its left. Normally `pos#marker` is the marker to the right of the pos's offset.\n if (dir === BACKWARD && pos.isTail() && pos.marker.isAtom) {\n return true;\n }\n return dir === BACKWARD ? pos.move(BACKWARD).marker.isAtom : pos.marker.isAtom;\n };\n\n if (isBoundary(pos, direction)) {\n // extend movement into prev/next section\n return pos.move(direction).moveWord(direction);\n }\n\n var seekWord = function seekWord(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && !WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first word char\n while (seekWord(pos)) {\n pos = pos.move(direction);\n }\n\n if (isAtom(pos, direction)) {\n return pos.move(direction);\n }\n\n var seekBoundary = function seekBoundary(pos) {\n return !isBoundary(pos, direction) && !isAtom(pos, direction) && WORD_CHAR_REGEX.test(peekChar(pos, direction));\n };\n\n // move(dir) while we are seeking the first boundary position\n while (seekBoundary(pos)) {\n pos = pos.move(direction);\n }\n\n return pos;\n }\n\n /**\n * The position to the left of this position.\n * If this position is the post's headPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveLeft',\n value: function moveLeft() {\n if (this.isHead()) {\n var prev = this.section.previousLeafSection();\n return prev ? prev.tailPosition() : this;\n } else {\n var offset = this.offset - 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset);\n if (code >= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.LOW_SURROGATE_RANGE[1]) {\n offset = offset - 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n\n /**\n * The position to the right of this position.\n * If this position is the post's tailPosition it returns itself.\n * @return {Position}\n * @private\n */\n }, {\n key: 'moveRight',\n value: function moveRight() {\n if (this.isTail()) {\n var next = this.section.nextLeafSection();\n return next ? next.headPosition() : this;\n } else {\n var offset = this.offset + 1;\n if (this.isMarkerable && this.marker) {\n var code = this.marker.value.charCodeAt(offset - 1);\n if (code >= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[0] && code <= _mobiledocKitModelsMarker.HIGH_SURROGATE_RANGE[1]) {\n offset = offset + 1;\n }\n }\n return new Position(this.section, offset);\n }\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n var _this = this;\n\n var post = this.section.post;\n var leafSectionIndex = undefined;\n post.walkAllLeafSections(function (section, index) {\n if (section === _this.section) {\n leafSectionIndex = index;\n }\n });\n return leafSectionIndex;\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return this.section && this.section.isMarkerable;\n }\n\n /**\n * Returns the marker at this position, in the backward direction\n * (i.e., the marker to the left of the cursor if the cursor is on a marker boundary and text is left-to-right)\n * @return {Marker|undefined}\n */\n }, {\n key: 'marker',\n get: function get() {\n return this.isMarkerable && this.markerPosition.marker;\n }\n }, {\n key: 'offsetInMarker',\n get: function get() {\n return this.markerPosition.offset;\n }\n }, {\n key: 'markerPosition',\n\n /**\n * @private\n */\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot get markerPosition without a section', !!this.section);\n (0, _mobiledocKitUtilsAssert['default'])('cannot get markerPosition of a non-markerable', !!this.section.isMarkerable);\n return this.section.markerPositionAtOffset(this.offset);\n }\n }], [{\n key: 'atPoint',\n value: function atPoint(x, y, editor) {\n var _renderTree = editor._renderTree;\n var rootElement = editor.element;\n\n var elementFromPoint = document.elementFromPoint(x, y);\n if (!(0, _mobiledocKitUtilsDomUtils.containsNode)(rootElement, elementFromPoint)) {\n return;\n }\n\n var _findOffsetInNode = (0, _mobiledocKitUtilsSelectionUtils.findOffsetInNode)(elementFromPoint, { left: x, top: y });\n\n var node = _findOffsetInNode.node;\n var offset = _findOffsetInNode.offset;\n\n return Position.fromNode(_renderTree, node, offset);\n }\n }, {\n key: 'blankPosition',\n value: function blankPosition() {\n return new BlankPosition();\n }\n }, {\n key: 'fromNode',\n value: function fromNode(renderTree, node, offset) {\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(node)) {\n return Position.fromTextNode(renderTree, node, offset);\n } else {\n return Position.fromElementNode(renderTree, node, offset);\n }\n }\n }, {\n key: 'fromTextNode',\n value: function fromTextNode(renderTree, textNode, offsetInNode) {\n var renderNode = renderTree.getElementRenderNode(textNode);\n var section = undefined,\n offsetInSection = undefined;\n\n if (renderNode) {\n var marker = renderNode.postNode;\n section = marker.section;\n\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for mapped text node \"' + textNode.textContent + '\"', !!section);\n offsetInSection = section.offsetOfMarker(marker, offsetInNode);\n } else {\n // all text nodes should be rendered by markers except:\n // * text nodes inside cards\n // * text nodes created by the browser during text input\n // both of these should have rendered parent sections, though\n section = findParentSectionFromNode(renderTree, textNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section for un-mapped text node \"' + textNode.textContent + '\"', !!section);\n\n offsetInSection = findOffsetInSection(section, textNode, offsetInNode);\n }\n\n return new Position(section, offsetInSection);\n }\n }, {\n key: 'fromElementNode',\n value: function fromElementNode(renderTree, elementNode, offset) {\n var position = undefined;\n\n // The browser may change the reported selection to equal the editor's root\n // element if the user clicks an element that is immediately removed,\n // which can happen when clicking to remove a card.\n if (elementNode === renderTree.rootElement) {\n var post = renderTree.rootNode.postNode;\n position = offset === 0 ? post.headPosition() : post.tailPosition();\n } else {\n var section = findParentSectionFromNode(renderTree, elementNode);\n (0, _mobiledocKitUtilsAssert['default'])('Could not find parent section from element node', !!section);\n\n if (section.isCardSection) {\n // Selections in cards are usually made on a text node\n // containing a ‌ on one side or the other of the card but\n // some scenarios (Firefox) will result in selecting the\n // card's wrapper div. If the offset is 2 we've selected\n // the final zwnj and should consider the cursor at the\n // end of the card (offset 1). Otherwise, the cursor is at\n // the start of the card\n position = offset < 2 ? section.headPosition() : section.tailPosition();\n } else {\n\n // In Firefox it is possible for the cursor to be on an atom's wrapper\n // element. (In Chrome/Safari, the browser corrects this to be on\n // one of the text nodes surrounding the wrapper).\n // This code corrects for when the browser reports the cursor position\n // to be on the wrapper element itself\n var renderNode = renderTree.getElementRenderNode(elementNode);\n var postNode = renderNode && renderNode.postNode;\n if (postNode && postNode.isAtom) {\n var sectionOffset = section.offsetOfMarker(postNode);\n if (offset > 1) {\n // we are on the tail side of the atom\n sectionOffset += postNode.length;\n }\n position = new Position(section, sectionOffset);\n } else if (offset >= elementNode.childNodes.length) {\n\n // This is to deal with how Firefox handles triple-click selections.\n // See https://stackoverflow.com/a/21234837/1269194 for an\n // explanation.\n position = section.tailPosition();\n } else {\n // The offset is 0 if the cursor is on a non-atom-wrapper element node\n // (e.g., a
    tag in a blank markup section)\n position = section.headPosition();\n }\n }\n }\n\n return position;\n }\n }]);\n\n return Position;\n })();\n\n BlankPosition = (function (_Position) {\n _inherits(BlankPosition, _Position);\n\n function BlankPosition() {\n _classCallCheck(this, BlankPosition);\n\n _get(Object.getPrototypeOf(BlankPosition.prototype), 'constructor', this).call(this, null, 0, true);\n }\n\n _createClass(BlankPosition, [{\n key: 'isEqual',\n value: function isEqual(other) {\n return other && other.isBlank;\n }\n }, {\n key: 'toRange',\n value: function toRange() {\n return _mobiledocKitUtilsCursorRange['default'].blankRange();\n }\n }, {\n key: 'isHeadOfPost',\n value: function isHeadOfPost() {\n return false;\n }\n }, {\n key: 'isTailOfPost',\n value: function isTailOfPost() {\n return false;\n }\n }, {\n key: 'isHead',\n value: function isHead() {\n return false;\n }\n }, {\n key: 'isTail',\n value: function isTail() {\n return false;\n }\n }, {\n key: 'move',\n value: function move() {\n return this;\n }\n }, {\n key: 'moveWord',\n value: function moveWord() {\n return this;\n }\n }, {\n key: 'leafSectionIndex',\n get: function get() {\n (0, _mobiledocKitUtilsAssert['default'])('must implement get leafSectionIndex', false);\n }\n }, {\n key: 'isMarkerable',\n get: function get() {\n return false;\n }\n }, {\n key: 'marker',\n get: function get() {\n return false;\n }\n }, {\n key: 'markerPosition',\n get: function get() {\n return {};\n }\n }]);\n\n return BlankPosition;\n })(Position);\n\n exports['default'] = Position;\n});","define('mobiledoc-kit/utils/cursor/range', ['exports', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsKey, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * A logical range of a {@link Post}.\n * Usually an instance of Range will be read from the {@link Editor#range} property,\n * but it may be useful to instantiate a range directly when programmatically modifying a Post.\n */\n\n var Range = (function () {\n /**\n * @param {Position} head\n * @param {Position} [tail=head]\n * @param {Direction} [direction=null]\n * @return {Range}\n * @private\n */\n\n function Range(head) {\n var tail = arguments.length <= 1 || arguments[1] === undefined ? head : arguments[1];\n var direction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n return (function () {\n _classCallCheck(this, Range);\n\n /** @property {Position} head */\n this.head = head;\n\n /** @property {Position} tail */\n this.tail = tail;\n\n /** @property {Direction} direction */\n this.direction = direction;\n }).apply(this, arguments);\n }\n\n /**\n * Shorthand to create a new range from a section(s) and offset(s).\n * When given only a head section and offset, creates a collapsed range.\n * @param {Section} headSection\n * @param {number} headOffset\n * @param {Section} [tailSection=headSection]\n * @param {number} [tailOffset=headOffset]\n * @param {Direction} [direction=null]\n * @return {Range}\n */\n\n _createClass(Range, [{\n key: 'trimTo',\n\n /**\n * @param {Markerable} section\n * @return {Range} A range that is constrained to only the part that\n * includes the section.\n * FIXME -- if the section isn't the head or tail, it's assumed to be\n * wholly contained. It's possible to call `trimTo` with a selection that is\n * outside of the range, though, which would invalidate that assumption.\n * There's no efficient way to determine if a section is within a range, yet.\n * @private\n */\n value: function trimTo(section) {\n var length = section.length;\n\n var headOffset = section === this.head.section ? Math.min(this.head.offset, length) : 0;\n var tailOffset = section === this.tail.section ? Math.min(this.tail.offset, length) : length;\n\n return Range.create(section, headOffset, section, tailOffset);\n }\n\n /**\n * Expands the range 1 unit in the given direction\n * If the range is expandable in the given direction, always returns a\n * non-collapsed range.\n * @param {Number} units If units is > 0, the range is extended to the right,\n * otherwise range is extended to the left.\n * @return {Range}\n * @public\n */\n }, {\n key: 'extend',\n value: function extend(units) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass integer to Range#extend', typeof units === 'number');\n\n if (units === 0) {\n return this;\n }\n\n var head = this.head;\n var tail = this.tail;\n var currentDirection = this.direction;\n\n switch (currentDirection) {\n case _mobiledocKitUtilsKey.DIRECTION.FORWARD:\n return new Range(head, tail.move(units), currentDirection);\n case _mobiledocKitUtilsKey.DIRECTION.BACKWARD:\n return new Range(head.move(units), tail, currentDirection);\n default:\n {\n var newDirection = units > 0 ? _mobiledocKitUtilsKey.DIRECTION.FORWARD : _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n return new Range(head, tail, newDirection).extend(units);\n }\n }\n }\n\n /**\n * Moves this range 1 unit in the given direction.\n * If the range is collapsed, returns a collapsed range shifted by 1 unit,\n * otherwise collapses this range to the position at the `direction` end of the range.\n * Always returns a collapsed range.\n * @param {Direction} direction\n * @return {Range}\n * @public\n */\n }, {\n key: 'move',\n value: function move(direction) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass DIRECTION.FORWARD (' + _mobiledocKitUtilsKey.DIRECTION.FORWARD + ') or DIRECTION.BACKWARD (' + _mobiledocKitUtilsKey.DIRECTION.BACKWARD + ') to Range#move', direction === _mobiledocKitUtilsKey.DIRECTION.FORWARD || direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD);\n\n var focusedPosition = this.focusedPosition;\n var isCollapsed = this.isCollapsed;\n\n if (isCollapsed) {\n return new Range(focusedPosition.move(direction));\n } else {\n return this._collapse(direction);\n }\n }\n\n /**\n * expand a range to all markers matching a given check\n *\n * @param {Function} detectMarker\n * @return {Range} The expanded range\n *\n * @public\n */\n }, {\n key: 'expandByMarker',\n value: function expandByMarker(detectMarker) {\n var head = this.head;\n var tail = this.tail;\n var direction = this.direction;\n var headSection = head.section;\n\n if (headSection !== tail.section) {\n throw new Error('#expandByMarker does not work across sections. Perhaps you should confirm the range is collapsed');\n }\n\n var firstNotMatchingDetect = function firstNotMatchingDetect(i) {\n return !detectMarker(i);\n };\n\n var headMarker = headSection.markers.detect(firstNotMatchingDetect, head.marker, true);\n if (!headMarker && detectMarker(headSection.markers.head)) {\n headMarker = headSection.markers.head;\n } else {\n headMarker = headMarker.next || head.marker;\n }\n var headPosition = new _mobiledocKitUtilsCursorPosition['default'](headSection, headSection.offsetOfMarker(headMarker));\n\n var tailMarker = tail.section.markers.detect(firstNotMatchingDetect, tail.marker);\n if (!tailMarker && detectMarker(headSection.markers.tail)) {\n tailMarker = headSection.markers.tail;\n } else {\n tailMarker = tailMarker.prev || tail.marker;\n }\n var tailPosition = new _mobiledocKitUtilsCursorPosition['default'](tail.section, tail.section.offsetOfMarker(tailMarker) + tailMarker.length);\n\n return headPosition.toRange(tailPosition, direction);\n }\n }, {\n key: '_collapse',\n value: function _collapse(direction) {\n return new Range(direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail);\n }\n }, {\n key: 'isEqual',\n value: function isEqual(other) {\n return other && this.head.isEqual(other.head) && this.tail.isEqual(other.tail);\n }\n }, {\n key: 'focusedPosition',\n get: function get() {\n return this.direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? this.head : this.tail;\n }\n }, {\n key: 'isBlank',\n get: function get() {\n return this.head.isBlank && this.tail.isBlank;\n }\n\n // \"legacy\" APIs\n }, {\n key: 'headSection',\n get: function get() {\n return this.head.section;\n }\n }, {\n key: 'tailSection',\n get: function get() {\n return this.tail.section;\n }\n }, {\n key: 'headSectionOffset',\n get: function get() {\n return this.head.offset;\n }\n }, {\n key: 'tailSectionOffset',\n get: function get() {\n return this.tail.offset;\n }\n }, {\n key: 'isCollapsed',\n get: function get() {\n return this.head.isEqual(this.tail);\n }\n }, {\n key: 'headMarker',\n get: function get() {\n return this.head.marker;\n }\n }, {\n key: 'tailMarker',\n get: function get() {\n return this.tail.marker;\n }\n }, {\n key: 'headMarkerOffset',\n get: function get() {\n return this.head.offsetInMarker;\n }\n }, {\n key: 'tailMarkerOffset',\n get: function get() {\n return this.tail.offsetInMarker;\n }\n }], [{\n key: 'create',\n value: function create(headSection, headOffset) {\n var tailSection = arguments.length <= 2 || arguments[2] === undefined ? headSection : arguments[2];\n var tailOffset = arguments.length <= 3 || arguments[3] === undefined ? headOffset : arguments[3];\n var direction = arguments.length <= 4 || arguments[4] === undefined ? null : arguments[4];\n return (function () {\n return new Range(new _mobiledocKitUtilsCursorPosition['default'](headSection, headOffset), new _mobiledocKitUtilsCursorPosition['default'](tailSection, tailOffset), direction);\n })();\n }\n }, {\n key: 'blankRange',\n value: function blankRange() {\n return new Range(_mobiledocKitUtilsCursorPosition['default'].blankPosition(), _mobiledocKitUtilsCursorPosition['default'].blankPosition());\n }\n }]);\n\n return Range;\n })();\n\n exports['default'] = Range;\n});","define(\"mobiledoc-kit/utils/deprecate\", [\"exports\"], function (exports) {\n /**\n * Usage:\n * Without a conditional, always prints deprecate message:\n * `deprecate('This is deprecated')`\n *\n * Conditional deprecation, works similarly to `assert`, prints deprecation if\n * conditional is false:\n * `deprecate('Deprecated only if foo !== bar', foo === bar)`\n */\n \"use strict\";\n\n exports[\"default\"] = deprecate;\n\n function deprecate(message) {\n var conditional = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];\n\n if (!conditional) {\n // eslint-disable-next-line no-console\n console.log(\"[mobiledoc-kit] [DEPRECATED]: \" + message);\n }\n }\n});","define('mobiledoc-kit/utils/dom-utils', ['exports', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n COMMENT: 8\n };\n\n exports.NODE_TYPES = NODE_TYPES;\n function isTextNode(node) {\n return node.nodeType === NODE_TYPES.TEXT;\n }\n\n function isCommentNode(node) {\n return node.nodeType === NODE_TYPES.COMMENT;\n }\n\n function isElementNode(node) {\n return node.nodeType === NODE_TYPES.ELEMENT;\n }\n\n // perform a pre-order tree traversal of the dom, calling `callbackFn(node)`\n // for every node for which `conditionFn(node)` is true\n function walkDOM(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n var conditionFn = arguments.length <= 2 || arguments[2] === undefined ? function () {\n return true;\n } : arguments[2];\n\n var currentNode = topNode;\n\n if (conditionFn(currentNode)) {\n callbackFn(currentNode);\n }\n\n currentNode = currentNode.firstChild;\n\n while (currentNode) {\n walkDOM(currentNode, callbackFn, conditionFn);\n currentNode = currentNode.nextSibling;\n }\n }\n\n function walkTextNodes(topNode) {\n var callbackFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];\n\n var conditionFn = function conditionFn(node) {\n return isTextNode(node);\n };\n walkDOM(topNode, callbackFn, conditionFn);\n }\n\n function clearChildNodes(element) {\n while (element.childNodes.length) {\n element.removeChild(element.childNodes[0]);\n }\n }\n\n /**\n * @return {Boolean} true when the child node is contained or the same as\n * (e.g., inclusive containment) the parent node\n * see https://github.com/webmodules/node-contains/blob/master/index.js\n * Mimics the behavior of `Node.contains`, which is broken in IE 10\n * @private\n */\n function containsNode(parentNode, childNode) {\n if (parentNode === childNode) {\n return true;\n }\n var position = parentNode.compareDocumentPosition(childNode);\n return !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY);\n }\n\n /**\n * converts the element's NamedNodeMap of attrs into\n * an object with key-value pairs\n * @param {DOMNode} element\n * @return {Object} key-value pairs\n * @private\n */\n function getAttributes(element) {\n var result = {};\n if (element.hasAttributes()) {\n (0, _mobiledocKitUtilsArrayUtils.forEach)(element.attributes, function (_ref) {\n var name = _ref.name;\n var value = _ref.value;\n\n result[name] = value;\n });\n }\n return result;\n }\n\n function addClassName(element, className) {\n element.classList.add(className);\n }\n\n function removeClassName(element, className) {\n element.classList.remove(className);\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n\n function parseHTML(html) {\n var div = document.createElement('div');\n div.innerHTML = html;\n return div;\n }\n\n function serializeHTML(node) {\n var div = document.createElement('div');\n div.appendChild(node);\n return div.innerHTML;\n }\n\n exports.containsNode = containsNode;\n exports.clearChildNodes = clearChildNodes;\n exports.getAttributes = getAttributes;\n exports.walkDOM = walkDOM;\n exports.walkTextNodes = walkTextNodes;\n exports.addClassName = addClassName;\n exports.removeClassName = removeClassName;\n exports.normalizeTagName = normalizeTagName;\n exports.isTextNode = isTextNode;\n exports.isCommentNode = isCommentNode;\n exports.isElementNode = isElementNode;\n exports.parseHTML = parseHTML;\n exports.serializeHTML = serializeHTML;\n});","define('mobiledoc-kit/utils/element-map', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // start at one to make the falsy semantics easier\n var uuidGenerator = 1;\n\n var ElementMap = (function () {\n function ElementMap() {\n _classCallCheck(this, ElementMap);\n\n this._map = {};\n }\n\n _createClass(ElementMap, [{\n key: 'set',\n value: function set(key, value) {\n var uuid = key._uuid;\n if (!uuid) {\n key._uuid = uuid = '' + uuidGenerator++;\n }\n this._map[uuid] = value;\n }\n }, {\n key: 'get',\n value: function get(key) {\n if (key._uuid) {\n return this._map[key._uuid];\n }\n return null;\n }\n }, {\n key: 'remove',\n value: function remove(key) {\n (0, _mobiledocKitUtilsAssert['default'])('tried to fetch a value for an element not seen before', !!key._uuid);\n delete this._map[key._uuid];\n }\n }]);\n\n return ElementMap;\n })();\n\n exports['default'] = ElementMap;\n});","define('mobiledoc-kit/utils/element-utils', ['exports', 'mobiledoc-kit/utils/string-utils', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsStringUtils, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function getEventTargetMatchingTag(tagName, target, container) {\n tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagName);\n // Traverses up DOM from an event target to find the node matching specifed tag\n while (target && target !== container) {\n if ((0, _mobiledocKitUtilsDomUtils.normalizeTagName)(target.tagName) === tagName) {\n return target;\n }\n target = target.parentNode;\n }\n }\n\n function getElementRelativeOffset(element) {\n var offset = { left: 0, top: -window.pageYOffset };\n var offsetParent = element.offsetParent;\n var offsetParentPosition = window.getComputedStyle(offsetParent).position;\n var offsetParentRect;\n\n if (offsetParentPosition === 'relative') {\n offsetParentRect = offsetParent.getBoundingClientRect();\n offset.left = offsetParentRect.left;\n offset.top = offsetParentRect.top;\n }\n return offset;\n }\n\n function getElementComputedStyleNumericProp(element, prop) {\n return parseFloat(window.getComputedStyle(element)[prop]);\n }\n\n function positionElementToRect(element, rect, topOffset, leftOffset) {\n var relativeOffset = getElementRelativeOffset(element);\n var style = element.style;\n var round = Math.round;\n var left, top;\n\n topOffset = topOffset || 0;\n leftOffset = leftOffset || 0;\n left = round(rect.left - relativeOffset.left - leftOffset);\n top = round(rect.top - relativeOffset.top - topOffset);\n style.left = left + 'px';\n style.top = top + 'px';\n return { left: left, top: top };\n }\n\n function positionElementHorizontallyCenteredToRect(element, rect, topOffset) {\n var horizontalCenter = element.offsetWidth / 2 - rect.width / 2;\n return positionElementToRect(element, rect, topOffset, horizontalCenter);\n }\n\n function positionElementCenteredBelow(element, belowElement) {\n var elementMargin = getElementComputedStyleNumericProp(element, 'marginTop');\n return positionElementHorizontallyCenteredToRect(element, belowElement.getBoundingClientRect(), -element.offsetHeight - elementMargin);\n }\n\n function setData(element, name, value) {\n if (element.dataset) {\n element.dataset[name] = value;\n } else {\n var dataName = (0, _mobiledocKitUtilsStringUtils.dasherize)(name);\n return element.setAttribute(dataName, value);\n }\n }\n\n function whenElementIsNotInDOM(element, callback) {\n var isCanceled = false;\n var observerFn = function observerFn() {\n if (isCanceled) {\n return;\n }\n if (!element.parentNode) {\n callback();\n } else {\n window.requestAnimationFrame(observerFn);\n }\n };\n observerFn();\n return { cancel: function cancel() {\n return isCanceled = true;\n } };\n }\n\n exports.setData = setData;\n exports.getEventTargetMatchingTag = getEventTargetMatchingTag;\n exports.getElementRelativeOffset = getElementRelativeOffset;\n exports.getElementComputedStyleNumericProp = getElementComputedStyleNumericProp;\n exports.positionElementToRect = positionElementToRect;\n exports.positionElementHorizontallyCenteredToRect = positionElementHorizontallyCenteredToRect;\n exports.positionElementCenteredBelow = positionElementCenteredBelow;\n exports.whenElementIsNotInDOM = whenElementIsNotInDOM;\n});","define('mobiledoc-kit/utils/environment', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n hasDOM: function hasDOM() {\n return typeof document !== 'undefined';\n }\n };\n});","define(\"mobiledoc-kit/utils/fixed-queue\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var FixedQueue = (function () {\n function FixedQueue() {\n var length = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];\n\n _classCallCheck(this, FixedQueue);\n\n this._maxLength = length;\n this._items = [];\n }\n\n _createClass(FixedQueue, [{\n key: \"pop\",\n value: function pop() {\n return this._items.pop();\n }\n }, {\n key: \"push\",\n value: function push(item) {\n this._items.push(item);\n if (this.length > this._maxLength) {\n this._items.shift();\n }\n }\n }, {\n key: \"clear\",\n value: function clear() {\n this._items = [];\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this._items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this._items.length;\n }\n }]);\n\n return FixedQueue;\n })();\n\n exports[\"default\"] = FixedQueue;\n});","define('mobiledoc-kit/utils/key', ['exports', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/keys', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKeys, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n exports.modifierMask = modifierMask;\n exports.specialCharacterToCode = specialCharacterToCode;\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * @typedef Direction\n * @enum {number}\n * @property {number} FORWARD\n * @property {number} BACKWARD\n */\n var DIRECTION = {\n FORWARD: 1,\n BACKWARD: -1\n };\n exports.DIRECTION = DIRECTION;\n var MODIFIERS = {\n META: 1, // also called \"command\" on OS X\n CTRL: 2,\n SHIFT: 4,\n ALT: 8 // also called \"option\" on OS X\n };\n\n exports.MODIFIERS = MODIFIERS;\n\n function modifierMask(event) {\n var metaKey = event.metaKey;\n var shiftKey = event.shiftKey;\n var ctrlKey = event.ctrlKey;\n var altKey = event.altKey;\n\n var modVal = function modVal(val, modifier) {\n return val && modifier || 0;\n };\n return modVal(metaKey, MODIFIERS.META) + modVal(shiftKey, MODIFIERS.SHIFT) + modVal(ctrlKey, MODIFIERS.CTRL) + modVal(altKey, MODIFIERS.ALT);\n }\n\n var SPECIAL_KEYS = {\n BACKSPACE: _mobiledocKitUtilsKeycodes['default'].BACKSPACE,\n TAB: _mobiledocKitUtilsKeycodes['default'].TAB,\n ENTER: _mobiledocKitUtilsKeycodes['default'].ENTER,\n ESC: _mobiledocKitUtilsKeycodes['default'].ESC,\n SPACE: _mobiledocKitUtilsKeycodes['default'].SPACE,\n PAGEUP: _mobiledocKitUtilsKeycodes['default'].PAGEUP,\n PAGEDOWN: _mobiledocKitUtilsKeycodes['default'].PAGEDOWN,\n END: _mobiledocKitUtilsKeycodes['default'].END,\n HOME: _mobiledocKitUtilsKeycodes['default'].HOME,\n LEFT: _mobiledocKitUtilsKeycodes['default'].LEFT,\n UP: _mobiledocKitUtilsKeycodes['default'].UP,\n RIGHT: _mobiledocKitUtilsKeycodes['default'].RIGHT,\n DOWN: _mobiledocKitUtilsKeycodes['default'].DOWN,\n INS: _mobiledocKitUtilsKeycodes['default'].INS,\n DEL: _mobiledocKitUtilsKeycodes['default'].DELETE\n };\n\n function specialCharacterToCode(specialCharacter) {\n return SPECIAL_KEYS[specialCharacter];\n }\n\n // heuristic for determining if `event` is a key event\n function isKeyEvent(event) {\n return (/^key/.test(event.type)\n );\n }\n\n /**\n * An abstraction around a KeyEvent\n * that key listeners in the editor can use\n * to determine what sort of key was pressed\n */\n var Key = (function () {\n function Key(event) {\n _classCallCheck(this, Key);\n\n this.key = event.key;\n this.keyCode = event.keyCode;\n this.charCode = event.charCode;\n this.event = event;\n this.modifierMask = modifierMask(event);\n }\n\n _createClass(Key, [{\n key: 'toString',\n value: function toString() {\n if (this.isTab()) {\n return _mobiledocKitUtilsCharacters.TAB;\n }\n return String.fromCharCode(this.charCode);\n }\n\n // See https://caniuse.com/#feat=keyboardevent-key for browser support.\n }, {\n key: 'isKeySupported',\n value: function isKeySupported() {\n return this.key;\n }\n }, {\n key: 'isKey',\n value: function isKey(identifier) {\n if (this.isKeySupported()) {\n (0, _mobiledocKitUtilsAssert['default'])('Must define Keys.' + identifier + '.', _mobiledocKitUtilsKeys['default'][identifier]);\n return this.key === _mobiledocKitUtilsKeys['default'][identifier];\n } else {\n (0, _mobiledocKitUtilsAssert['default'])('Must define Keycodes.' + identifier + '.', _mobiledocKitUtilsKeycodes['default'][identifier]);\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'][identifier];\n }\n }\n }, {\n key: 'isEscape',\n value: function isEscape() {\n return this.isKey('ESC');\n }\n }, {\n key: 'isDelete',\n value: function isDelete() {\n return this.isKey('BACKSPACE') || this.isForwardDelete();\n }\n }, {\n key: 'isForwardDelete',\n value: function isForwardDelete() {\n return this.isKey('DELETE');\n }\n }, {\n key: 'isArrow',\n value: function isArrow() {\n return this.isHorizontalArrow() || this.isVerticalArrow();\n }\n }, {\n key: 'isHorizontalArrow',\n value: function isHorizontalArrow() {\n return this.isLeftArrow() || this.isRightArrow();\n }\n }, {\n key: 'isHorizontalArrowWithoutModifiersOtherThanShift',\n value: function isHorizontalArrowWithoutModifiersOtherThanShift() {\n return this.isHorizontalArrow() && !(this.ctrlKey || this.metaKey || this.altKey);\n }\n }, {\n key: 'isVerticalArrow',\n value: function isVerticalArrow() {\n return this.isKey('UP') || this.isKey('DOWN');\n }\n }, {\n key: 'isLeftArrow',\n value: function isLeftArrow() {\n return this.isKey('LEFT');\n }\n }, {\n key: 'isRightArrow',\n value: function isRightArrow() {\n return this.isKey('RIGHT');\n }\n }, {\n key: 'isHome',\n value: function isHome() {\n return this.isKey('HOME');\n }\n }, {\n key: 'isEnd',\n value: function isEnd() {\n return this.isKey('END');\n }\n }, {\n key: 'isPageUp',\n value: function isPageUp() {\n return this.isKey('PAGEUP');\n }\n }, {\n key: 'isPageDown',\n value: function isPageDown() {\n return this.isKey('PAGEDOWN');\n }\n }, {\n key: 'isInsert',\n value: function isInsert() {\n return this.isKey('INS');\n }\n }, {\n key: 'isClear',\n value: function isClear() {\n return this.isKey('CLEAR');\n }\n }, {\n key: 'isPause',\n value: function isPause() {\n return this.isKey('PAUSE');\n }\n }, {\n key: 'isSpace',\n value: function isSpace() {\n return this.isKey('SPACE');\n }\n\n // In Firefox, pressing ctrl-TAB will switch to another open browser tab, but\n // it will also fire a keydown event for the tab+modifier (ctrl). This causes\n // Mobiledoc to erroneously insert a tab character before FF switches to the\n // new browser tab. Chrome doesn't fire this event so the issue doesn't\n // arise there. Fix this by returning false when the TAB key event includes a\n // modifier.\n // See: https://github.com/bustle/mobiledoc-kit/issues/565\n }, {\n key: 'isTab',\n value: function isTab() {\n return !this.hasAnyModifier() && this.isKey('TAB');\n }\n }, {\n key: 'isEnter',\n value: function isEnter() {\n return this.isKey('ENTER');\n }\n\n /*\n * If the key is the actual shift key. This is false when the shift key\n * is held down and the source `event` is not the shift key.\n * @see {isShift}\n * @return {bool}\n */\n }, {\n key: 'isShiftKey',\n value: function isShiftKey() {\n return this.isKey('SHIFT');\n }\n\n /*\n * If the key is the actual alt key (aka \"option\" on mac). This is false when the alt key\n * is held down and the source `event` is not the alt key.\n * @return {bool}\n */\n }, {\n key: 'isAltKey',\n value: function isAltKey() {\n return this.isKey('ALT');\n }\n\n /*\n * If the key is the actual ctrl key. This is false when the ctrl key\n * is held down and the source `event` is not the ctrl key.\n * @return {bool}\n */\n }, {\n key: 'isCtrlKey',\n value: function isCtrlKey() {\n return this.isKey('CTRL');\n }\n }, {\n key: 'isIME',\n value: function isIME() {\n // FIXME the IME action seems to get lost when we issue an\n // `editor.deleteSelection` before it (in Chrome)\n return this.keyCode === _mobiledocKitUtilsKeycodes['default'].IME;\n }\n }, {\n key: 'isShift',\n\n /**\n * If the shift key is depressed.\n * For example, while holding down meta+shift, pressing the \"v\"\n * key would result in an event whose `Key` had `isShift()` with a truthy value,\n * because the shift key is down when pressing the \"v\".\n * @see {isShiftKey} which checks if the key is actually the shift key itself.\n * @return {bool}\n */\n value: function isShift() {\n return this.shiftKey;\n }\n }, {\n key: 'hasModifier',\n value: function hasModifier(modifier) {\n return modifier & this.modifierMask;\n }\n }, {\n key: 'hasAnyModifier',\n value: function hasAnyModifier() {\n return !!this.modifierMask;\n }\n }, {\n key: 'isPrintableKey',\n value: function isPrintableKey() {\n return !(this.isArrow() || this.isHome() || this.isEnd() || this.isPageUp() || this.isPageDown() || this.isInsert() || this.isClear() || this.isPause() || this.isEscape());\n }\n }, {\n key: 'isNumberKey',\n value: function isNumberKey() {\n if (this.isKeySupported()) {\n return this.key >= '0' && this.key <= '9';\n } else {\n var code = this.keyCode;\n return code >= _mobiledocKitUtilsKeycodes['default']['0'] && code <= _mobiledocKitUtilsKeycodes['default']['9'] || code >= _mobiledocKitUtilsKeycodes['default'].NUMPAD_0 && code <= _mobiledocKitUtilsKeycodes['default'].NUMPAD_9; // numpad keys\n }\n }\n }, {\n key: 'isLetterKey',\n value: function isLetterKey() {\n if (this.isKeySupported()) {\n var key = this.key;\n return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z';\n } else {\n var code = this.keyCode;\n return code >= _mobiledocKitUtilsKeycodes['default'].A && code <= _mobiledocKitUtilsKeycodes['default'].Z || code >= _mobiledocKitUtilsKeycodes['default'].a && code <= _mobiledocKitUtilsKeycodes['default'].z;\n }\n }\n }, {\n key: 'isPunctuation',\n value: function isPunctuation() {\n if (this.isKeySupported()) {\n var key = this.key;\n return key >= ';' && key <= '`' || key >= '[' && key <= '\"';\n } else {\n var code = this.keyCode;\n return code >= _mobiledocKitUtilsKeycodes['default'][';'] && code <= _mobiledocKitUtilsKeycodes['default']['`'] || code >= _mobiledocKitUtilsKeycodes['default']['['] && code <= _mobiledocKitUtilsKeycodes['default']['\"'];\n }\n }\n\n /**\n * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position\n * and http://stackoverflow.com/a/12467610/137784\n */\n }, {\n key: 'isPrintable',\n value: function isPrintable() {\n if (this.ctrlKey || this.metaKey) {\n return false;\n }\n\n // Firefox calls keypress events for some keys that should not be printable\n if (!this.isPrintableKey()) {\n return false;\n }\n\n return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME();\n }\n }, {\n key: 'direction',\n get: function get() {\n switch (true) {\n case this.isDelete():\n return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n case this.isHorizontalArrow():\n return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD;\n }\n }\n }, {\n key: 'ctrlKey',\n get: function get() {\n return MODIFIERS.CTRL & this.modifierMask;\n }\n }, {\n key: 'metaKey',\n get: function get() {\n return MODIFIERS.META & this.modifierMask;\n }\n }, {\n key: 'shiftKey',\n get: function get() {\n return MODIFIERS.SHIFT & this.modifierMask;\n }\n }, {\n key: 'altKey',\n get: function get() {\n return MODIFIERS.ALT & this.modifierMask;\n }\n }], [{\n key: 'fromEvent',\n value: function fromEvent(event) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass a Key event to Key.fromEvent', event && isKeyEvent(event));\n return new Key(event);\n }\n }]);\n\n return Key;\n })();\n\n exports['default'] = Key;\n});","define('mobiledoc-kit/utils/keycodes', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n BACKSPACE: 8,\n SPACE: 32,\n ENTER: 13,\n SHIFT: 16,\n ESC: 27,\n DELETE: 46,\n '0': 48,\n '9': 57,\n A: 65,\n Z: 90,\n a: 97,\n z: 122,\n 'NUMPAD_0': 186,\n 'NUMPAD_9': 111,\n ';': 186,\n '.': 190,\n '`': 192,\n '[': 219,\n '\"': 222,\n\n // Input Method Editor uses multiple keystrokes to display characters.\n // Example on mac: press option-i then i. This fires 2 key events in Chrome\n // with keyCode 229 and displays ˆ and then î.\n // See http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html#fixed-virtual-key-codes\n IME: 229,\n\n TAB: 9,\n CLEAR: 12,\n PAUSE: 19,\n PAGEUP: 33,\n PAGEDOWN: 34,\n END: 35,\n HOME: 36,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n INS: 45,\n META: 91,\n ALT: 18,\n CTRL: 17\n };\n});","define('mobiledoc-kit/utils/keys', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n BACKSPACE: 'Backspace',\n SPACE: ' ',\n ENTER: 'Enter',\n SHIFT: 'Shift',\n ESC: 'Escape',\n DELETE: 'Delete',\n INS: 'Insert',\n HOME: 'Home',\n END: 'End',\n PAGEUP: 'PageUp',\n PAGEDOWN: 'PageDown',\n CLEAR: 'Clear',\n PAUSE: 'Pause',\n TAB: 'Tab',\n ALT: 'Alt',\n CTRL: 'Control',\n\n LEFT: 'ArrowLeft',\n RIGHT: 'ArrowRight',\n UP: 'ArrowUp',\n DOWN: 'ArrowDown'\n };\n});","define(\"mobiledoc-kit/utils/linked-item\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var LinkedItem = function LinkedItem() {\n _classCallCheck(this, LinkedItem);\n\n this.next = null;\n this.prev = null;\n };\n\n exports[\"default\"] = LinkedItem;\n});","define('mobiledoc-kit/utils/linked-list', ['exports', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var PARENT_PROP = '__parent';\n\n var LinkedList = (function () {\n function LinkedList(options) {\n _classCallCheck(this, LinkedList);\n\n this.head = null;\n this.tail = null;\n this.length = 0;\n\n if (options) {\n var adoptItem = options.adoptItem;\n var freeItem = options.freeItem;\n\n this._adoptItem = adoptItem;\n this._freeItem = freeItem;\n }\n }\n\n _createClass(LinkedList, [{\n key: 'adoptItem',\n value: function adoptItem(item) {\n item[PARENT_PROP] = this;\n this.length++;\n if (this._adoptItem) {\n this._adoptItem(item);\n }\n }\n }, {\n key: 'freeItem',\n value: function freeItem(item) {\n item[PARENT_PROP] = null;\n this.length--;\n if (this._freeItem) {\n this._freeItem(item);\n }\n }\n }, {\n key: 'prepend',\n value: function prepend(item) {\n this.insertBefore(item, this.head);\n }\n }, {\n key: 'append',\n value: function append(item) {\n this.insertBefore(item, null);\n }\n }, {\n key: 'insertAfter',\n value: function insertAfter(item, prevItem) {\n var nextItem = prevItem ? prevItem.next : this.head;\n this.insertBefore(item, nextItem);\n }\n }, {\n key: '_ensureItemIsNotAlreadyInList',\n value: function _ensureItemIsNotAlreadyInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item.next && !item.prev && this.head !== item);\n }\n }, {\n key: 'insertBefore',\n value: function insertBefore(item, nextItem) {\n this._ensureItemIsNotInList(item);\n this.adoptItem(item);\n\n var insertPos = undefined;\n if (nextItem && nextItem.prev) {\n insertPos = 'middle';\n } else if (nextItem) {\n insertPos = 'start';\n } else {\n insertPos = 'end';\n }\n\n switch (insertPos) {\n case 'start':\n if (this.head) {\n item.next = this.head;\n this.head.prev = item;\n }\n this.head = item;\n\n break;\n case 'middle':\n {\n var prevItem = nextItem.prev;\n item.next = nextItem;\n item.prev = prevItem;\n nextItem.prev = item;\n prevItem.next = item;\n\n break;\n }\n case 'end':\n {\n var tail = this.tail;\n item.prev = tail;\n\n if (tail) {\n tail.next = item;\n } else {\n this.head = item;\n }\n this.tail = item;\n\n break;\n }\n }\n }\n }, {\n key: 'remove',\n value: function remove(item) {\n if (!item[PARENT_PROP]) {\n return;\n }\n this._ensureItemIsInThisList(item);\n this.freeItem(item);\n\n var prev = item.prev;\n var next = item.next;\n\n item.prev = null;\n item.next = null;\n\n if (prev) {\n prev.next = next;\n } else {\n this.head = next;\n }\n\n if (next) {\n next.prev = prev;\n } else {\n this.tail = prev;\n }\n }\n }, {\n key: 'forEach',\n value: function forEach(callback) {\n var item = this.head;\n var index = 0;\n while (item) {\n callback(item, index++);\n item = item.next;\n }\n }\n }, {\n key: 'map',\n value: function map(callback) {\n var result = [];\n this.forEach(function (i) {\n return result.push(callback(i));\n });\n return result;\n }\n }, {\n key: 'walk',\n value: function walk(startItem, endItem, callback) {\n var item = startItem || this.head;\n while (item) {\n callback(item);\n if (item === endItem) {\n break;\n }\n item = item.next;\n }\n }\n }, {\n key: 'readRange',\n value: function readRange(startItem, endItem) {\n var items = [];\n this.walk(startItem, endItem, function (item) {\n items.push(item);\n });\n return items;\n }\n }, {\n key: 'toArray',\n value: function toArray() {\n return this.readRange();\n }\n }, {\n key: 'detect',\n value: function detect(callback) {\n var item = arguments.length <= 1 || arguments[1] === undefined ? this.head : arguments[1];\n var reverse = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];\n\n while (item) {\n if (callback(item)) {\n return item;\n }\n item = reverse ? item.prev : item.next;\n }\n }\n }, {\n key: 'any',\n value: function any(callback) {\n return !!this.detect(callback);\n }\n }, {\n key: 'every',\n value: function every(callback) {\n var item = this.head;\n while (item) {\n if (!callback(item)) {\n return false;\n }\n item = item.next;\n }\n return true;\n }\n }, {\n key: 'objectAt',\n value: function objectAt(targetIndex) {\n var index = -1;\n return this.detect(function () {\n index++;\n return targetIndex === index;\n });\n }\n }, {\n key: 'splice',\n value: function splice(targetItem, removalCount, newItems) {\n var _this = this;\n\n var item = targetItem;\n var nextItem = item.next;\n var count = 0;\n while (item && count < removalCount) {\n count++;\n nextItem = item.next;\n this.remove(item);\n item = nextItem;\n }\n newItems.forEach(function (newItem) {\n _this.insertBefore(newItem, nextItem);\n });\n }\n }, {\n key: 'removeBy',\n value: function removeBy(conditionFn) {\n var item = this.head;\n while (item) {\n var nextItem = item.next;\n\n if (conditionFn(item)) {\n this.remove(item);\n }\n\n item = nextItem;\n }\n }\n }, {\n key: '_ensureItemIsNotInList',\n value: function _ensureItemIsNotInList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot insert an item into a list if it is already in a list', !item[PARENT_PROP]);\n }\n }, {\n key: '_ensureItemIsInThisList',\n value: function _ensureItemIsInThisList(item) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot remove item that is in another list', item[PARENT_PROP] === this);\n }\n }, {\n key: 'isEmpty',\n get: function get() {\n return this.length === 0;\n }\n }]);\n\n return LinkedList;\n })();\n\n exports['default'] = LinkedList;\n});","define(\"mobiledoc-kit/utils/log-manager\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Logger = (function () {\n function Logger(type, manager) {\n _classCallCheck(this, Logger);\n\n this.type = type;\n this.manager = manager;\n }\n\n _createClass(Logger, [{\n key: \"isEnabled\",\n value: function isEnabled() {\n return this.manager.isEnabled(this.type);\n }\n }, {\n key: \"log\",\n value: function log() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n args.unshift(\"[\" + this.type + \"]\");\n if (this.isEnabled()) {\n var _window$console;\n\n (_window$console = window.console).log.apply(_window$console, args);\n }\n }\n }]);\n\n return Logger;\n })();\n\n var LogManager = (function () {\n function LogManager() {\n _classCallCheck(this, LogManager);\n\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n\n _createClass(LogManager, [{\n key: \"for\",\n value: function _for(type) {\n return new Logger(type, this);\n }\n }, {\n key: \"enableAll\",\n value: function enableAll() {\n this.allEnabled = true;\n }\n }, {\n key: \"enableTypes\",\n value: function enableTypes(types) {\n this.enabledTypes = this.enabledTypes.concat(types);\n }\n }, {\n key: \"disable\",\n value: function disable() {\n this.enabledTypes = [];\n this.allEnabled = false;\n }\n }, {\n key: \"isEnabled\",\n value: function isEnabled(type) {\n return this.allEnabled || this.enabledTypes.indexOf(type) !== -1;\n }\n }]);\n\n return LogManager;\n })();\n\n exports[\"default\"] = LogManager;\n});","define('mobiledoc-kit/utils/markuperable', ['exports', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils'], function (exports, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var Markerupable = (function () {\n function Markerupable() {\n _classCallCheck(this, Markerupable);\n }\n\n _createClass(Markerupable, [{\n key: 'clearMarkups',\n value: function clearMarkups() {\n this.markups = [];\n }\n }, {\n key: 'addMarkup',\n value: function addMarkup(markup) {\n this.markups.push(markup);\n }\n }, {\n key: 'addMarkupAtIndex',\n value: function addMarkupAtIndex(markup, index) {\n this.markups.splice(index, 0, markup);\n }\n }, {\n key: 'removeMarkup',\n value: function removeMarkup(markupOrMarkupCallback) {\n var _this = this;\n\n var callback = undefined;\n if (typeof markupOrMarkupCallback === 'function') {\n callback = markupOrMarkupCallback;\n } else {\n (function () {\n var markup = markupOrMarkupCallback;\n callback = function (_markup) {\n return _markup === markup;\n };\n })();\n }\n\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.markups, callback), function (m) {\n return _this._removeMarkup(m);\n });\n }\n }, {\n key: '_removeMarkup',\n value: function _removeMarkup(markup) {\n var index = this.markups.indexOf(markup);\n if (index !== -1) {\n this.markups.splice(index, 1);\n }\n }\n }, {\n key: 'hasMarkup',\n value: function hasMarkup(tagNameOrMarkup) {\n return !!this.getMarkup(tagNameOrMarkup);\n }\n }, {\n key: 'getMarkup',\n value: function getMarkup(tagNameOrMarkup) {\n var _this2 = this;\n\n if (typeof tagNameOrMarkup === 'string') {\n var _ret2 = (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(tagNameOrMarkup);\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup.tagName === tagName;\n })\n };\n })();\n\n if (typeof _ret2 === 'object') return _ret2.v;\n } else {\n var _ret3 = (function () {\n var targetMarkup = tagNameOrMarkup;\n return {\n v: (0, _mobiledocKitUtilsArrayUtils.detect)(_this2.markups, function (markup) {\n return markup === targetMarkup;\n })\n };\n })();\n\n if (typeof _ret3 === 'object') return _ret3.v;\n }\n }\n }, {\n key: 'openedMarkups',\n get: function get() {\n var count = 0;\n if (this.prev) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.prev.markups);\n }\n\n return this.markups.slice(count);\n }\n }, {\n key: 'closedMarkups',\n get: function get() {\n var count = 0;\n if (this.next) {\n count = (0, _mobiledocKitUtilsArrayUtils.commonItemLength)(this.markups, this.next.markups);\n }\n\n return this.markups.slice(count);\n }\n }]);\n\n return Markerupable;\n })();\n\n exports['default'] = Markerupable;\n});","define(\"mobiledoc-kit/utils/merge\", [\"exports\"], function (exports) {\n \"use strict\";\n\n function mergeWithOptions(original, updates, options) {\n options = options || {};\n for (var prop in updates) {\n if (options.hasOwnProperty(prop)) {\n original[prop] = options[prop];\n } else if (updates.hasOwnProperty(prop)) {\n original[prop] = updates[prop];\n }\n }\n return original;\n }\n\n /**\n * Merges properties of one object into another\n * @private\n */\n function merge(original, updates) {\n return mergeWithOptions(original, updates);\n }\n\n exports.mergeWithOptions = mergeWithOptions;\n exports.merge = merge;\n});","define('mobiledoc-kit/utils/mixin', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = mixin;\n var CONSTRUCTOR_FN_NAME = 'constructor';\n\n function mixin(target, source) {\n target = target.prototype;\n // Fallback to just `source` to allow mixing in a plain object (pojo)\n source = source.prototype || source;\n\n Object.getOwnPropertyNames(source).forEach(function (name) {\n if (name !== CONSTRUCTOR_FN_NAME) {\n var descriptor = Object.getOwnPropertyDescriptor(source, name);\n\n Object.defineProperty(target, name, descriptor);\n }\n });\n }\n});","define('mobiledoc-kit/utils/mobiledoc-error', ['exports'], function (exports) {\n 'use strict';\n\n var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];\n\n function MobiledocError() {\n var tmp = Error.apply(this, arguments);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.\n for (var idx = 0; idx < errorProps.length; idx++) {\n this[errorProps[idx]] = tmp[errorProps[idx]];\n }\n }\n\n MobiledocError.prototype = Object.create(Error.prototype);\n\n exports['default'] = MobiledocError;\n});","define(\"mobiledoc-kit/utils/object-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.entries = entries;\n\n function entries(obj) {\n var ownProps = Object.keys(obj);\n var i = ownProps.length;\n var resArray = new Array(i);\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]];\n }\n\n return resArray;\n }\n});","define('mobiledoc-kit/utils/parse-utils', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/text'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersText) {\n /* global JSON */\n 'use strict';\n\n exports.getContentFromPasteEvent = getContentFromPasteEvent;\n exports.setClipboardData = setClipboardData;\n exports.parsePostFromPaste = parsePostFromPaste;\n exports.parsePostFromDrop = parsePostFromDrop;\n var MIME_TEXT_PLAIN = 'text/plain';\n exports.MIME_TEXT_PLAIN = MIME_TEXT_PLAIN;\n var MIME_TEXT_HTML = 'text/html';\n exports.MIME_TEXT_HTML = MIME_TEXT_HTML;\n var NONSTANDARD_IE_TEXT_TYPE = 'Text';\n\n exports.NONSTANDARD_IE_TEXT_TYPE = NONSTANDARD_IE_TEXT_TYPE;\n var MOBILEDOC_REGEX = new RegExp(/data\\-mobiledoc='(.*?)'>/);\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromHTML(html, builder, plugins) {\n var post = undefined;\n\n if (MOBILEDOC_REGEX.test(html)) {\n var mobiledocString = html.match(MOBILEDOC_REGEX)[1];\n var mobiledoc = JSON.parse(mobiledocString);\n post = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n } else {\n post = new _mobiledocKitParsersHtml['default'](builder, { plugins: plugins }).parse(html);\n }\n\n return post;\n }\n\n /**\n * @return {Post}\n * @private\n */\n function parsePostFromText(text, builder, plugins) {\n var parser = new _mobiledocKitParsersText['default'](builder, { plugins: plugins });\n var post = parser.parse(text);\n return post;\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n\n function getContentFromPasteEvent(event, window) {\n var html = '',\n text = '';\n\n var clipboardData = event.clipboardData;\n\n if (clipboardData && clipboardData.getData) {\n html = clipboardData.getData(MIME_TEXT_HTML);\n text = clipboardData.getData(MIME_TEXT_PLAIN);\n } else if (window.clipboardData && window.clipboardData.getData) {\n // IE\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n html = window.clipboardData.getData(NONSTANDARD_IE_TEXT_TYPE);\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @return {{html: String, text: String}}\n * @private\n */\n function getContentFromDropEvent(event, logger) {\n var html = '',\n text = '';\n\n try {\n html = event.dataTransfer.getData(MIME_TEXT_HTML);\n text = event.dataTransfer.getData(MIME_TEXT_PLAIN);\n } catch (e) {\n // FIXME IE11 does not include any data in the 'text/html' or 'text/plain'\n // mimetypes. It throws an error 'Invalid argument' when attempting to read\n // these properties.\n if (logger) {\n logger.log('Error getting drop data: ', e);\n }\n }\n\n return { html: html, text: text };\n }\n\n /**\n * @param {CopyEvent|CutEvent}\n * @param {Editor}\n * @param {Window}\n * @private\n */\n\n function setClipboardData(event, _ref, window) {\n var mobiledoc = _ref.mobiledoc;\n var html = _ref.html;\n var text = _ref.text;\n\n if (mobiledoc && html) {\n html = '
    ' + html + '
    ';\n }\n\n var clipboardData = event.clipboardData;\n var nonstandardClipboardData = window.clipboardData;\n\n if (clipboardData && clipboardData.setData) {\n clipboardData.setData(MIME_TEXT_HTML, html);\n clipboardData.setData(MIME_TEXT_PLAIN, text);\n } else if (nonstandardClipboardData && nonstandardClipboardData.setData) {\n // The Internet Explorers (including Edge) have a non-standard way of interacting with the\n // Clipboard API (see http://caniuse.com/#feat=clipboard). In short, they expose a global window.clipboardData\n // object instead of the per-event event.clipboardData object on the other browsers.\n nonstandardClipboardData.setData(NONSTANDARD_IE_TEXT_TYPE, html);\n }\n }\n\n /**\n * @param {PasteEvent}\n * @param {{builder: Builder, _parserPlugins: Array}} options\n * @return {Post}\n * @private\n */\n\n function parsePostFromPaste(pasteEvent, _ref2) {\n var builder = _ref2.builder;\n var plugins = _ref2._parserPlugins;\n\n var _ref3 = arguments.length <= 2 || arguments[2] === undefined ? { targetFormat: 'html' } : arguments[2];\n\n var targetFormat = _ref3.targetFormat;\n\n var _getContentFromPasteEvent = getContentFromPasteEvent(pasteEvent, window);\n\n var html = _getContentFromPasteEvent.html;\n var text = _getContentFromPasteEvent.text;\n\n if (targetFormat === 'html' && html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n\n /**\n * @param {DropEvent}\n * @param {Editor} editor\n * @param {Object} [options={}] Can pass a logger\n * @return {Post}\n * @private\n */\n\n function parsePostFromDrop(dropEvent, editor) {\n var _ref4 = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var logger = _ref4.logger;\n var builder = editor.builder;\n var plugins = editor._parserPlugins;\n\n var _getContentFromDropEvent = getContentFromDropEvent(dropEvent, logger);\n\n var html = _getContentFromDropEvent.html;\n var text = _getContentFromDropEvent.text;\n\n if (html && html.length) {\n return parsePostFromHTML(html, builder, plugins);\n } else if (text && text.length) {\n return parsePostFromText(text, builder, plugins);\n }\n }\n});","define(\"mobiledoc-kit/utils/placeholder-image-src\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var placeholderImageSrc = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAMFBMVEXp7vG6vsHm6+63u77Hy868wMPe4+bO09bh5unr8fTR1djAxMfM0NPX3N/c4eTBxcjXRf5TAAACh0lEQVR4nO3b6ZKqMBSFUSQMYZL3f9tbBq/NEEDiqUqOfusn1ZXKbjcQlGQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC6RkbsGHuabChEtHmiGYfS3EQYM+Sxw/gMQvmcNnYaj6oTDHi73WPn2eqnj9B8zo3TJXcq5uNjXmVff86VwSR3JtryMa1BYqi7S1hJDCVpSigyLcGhJJEwzlCSNtPKrbVhVwsdCfOhH7uuaG3ARV9DwsaOzxt3N1yPqCHhvXytTUz92VDpmE/LLhZwl++R6Sds6sUa/PL6K/2E2fIhw1xdRKefsFolrPc+xNx/N0k/4fpBsdhL2HfeiN+TsDCms8dDpeRyS3P3QDl6Iqaf8L0rTf+80m6Lmn7Ct+4Wxf+/2RY1/YRv3PHz/u+fsCmqgoTnq7Z+8SGviqoh4dnKu1ieqauiakh4/PQ0r6ivqDoSHj0B97eNRVG1JNxV+L4bnxdVecJtRTdFVZ7QU9F1UXUn9FZ0VVRlCav5ob2KLouqKmFjy676u2HsVnRRVFUJq3J+8KCi86IqSthMvyl209Hjijqm3RsqAZ5pNfa5PJ2KelJRjQmr1/r7cfy0ouoSNvOfvbvhvKLaEr4qOin9kTQnrN7LpDZhE/Zmhp6Eq4p+YcKgiipKGFhRRQkDK6ooYfgLbiSMioQkJGF8P5XwHv4O+7AaKiXzaeXh1kMl5AffTUxiKEm/krD94BR8Gdxl1fceSlR58ZhXKbEpyD2amNiBtmrJLTMHL1LF8/rpXkSZXEmz8K8uvAFFNm6Iq0aBLUFOmeCuJ6exrcCmoLpN7kYx891bSAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgh/wDdr8peyRHLogAAAAASUVORK5CYII=\";\n\n exports[\"default\"] = placeholderImageSrc;\n});","define('mobiledoc-kit/utils/selection-utils', ['exports', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n function clearSelection() {\n window.getSelection().removeAllRanges();\n }\n\n function textNodeRects(node) {\n var range = document.createRange();\n range.setEnd(node, node.nodeValue.length);\n range.setStart(node, 0);\n return range.getClientRects();\n }\n\n function findOffsetInTextNode(node, coords) {\n var len = node.nodeValue.length;\n var range = document.createRange();\n for (var i = 0; i < len; i++) {\n range.setEnd(node, i + 1);\n range.setStart(node, i);\n var rect = range.getBoundingClientRect();\n if (rect.top === rect.bottom) {\n continue;\n }\n if (rect.left <= coords.left && rect.right >= coords.left && rect.top <= coords.top && rect.bottom >= coords.top) {\n return { node: node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };\n }\n }\n return { node: node, offset: 0 };\n }\n\n /*\n * @param {Object} coords with `top` and `left`\n * @see https://github.com/ProseMirror/prosemirror/blob/4c22e3fe97d87a355a0534e25d65aaf0c0d83e57/src/edit/dompos.js\n * @return {Object} {node, offset}\n */\n /* eslint-disable complexity */\n function findOffsetInNode(_x, _x2) {\n var _again = true;\n\n _function: while (_again) {\n var node = _x,\n coords = _x2;\n _again = false;\n\n var closest = undefined,\n dyClosest = 1e8,\n coordsClosest = undefined,\n offset = 0;\n for (var child = node.firstChild; child; child = child.nextSibling) {\n var rects = undefined;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child)) {\n rects = child.getClientRects();\n } else if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(child)) {\n rects = textNodeRects(child);\n } else {\n continue;\n }\n\n for (var i = 0; i < rects.length; i++) {\n var rect = rects[i];\n if (rect.left <= coords.left && rect.right >= coords.left) {\n var dy = rect.top > coords.top ? rect.top - coords.top : rect.bottom < coords.top ? coords.top - rect.bottom : 0;\n if (dy < dyClosest) {\n closest = child;\n dyClosest = dy;\n coordsClosest = dy ? { left: coords.left, top: rect.top } : coords;\n if ((0, _mobiledocKitUtilsDomUtils.isElementNode)(child) && !child.firstChild) {\n offset = i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);\n }\n continue;\n }\n }\n if (!closest && (coords.top >= rect.bottom || coords.top >= rect.top && coords.left >= rect.right)) {\n offset = i + 1;\n }\n }\n }\n if (!closest) {\n return { node: node, offset: offset };\n }\n if ((0, _mobiledocKitUtilsDomUtils.isTextNode)(closest)) {\n return findOffsetInTextNode(closest, coordsClosest);\n }\n if (closest.firstChild) {\n _x = closest;\n _x2 = coordsClosest;\n _again = true;\n closest = dyClosest = coordsClosest = offset = child = rects = i = rect = dy = undefined;\n continue _function;\n }\n return { node: node, offset: offset };\n }\n }\n /* eslint-enable complexity */\n\n function constrainNodeTo(node, parentNode, existingOffset) {\n var compare = parentNode.compareDocumentPosition(node);\n if (compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n // the node is inside parentNode, do nothing\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_CONTAINS) {\n // the node contains parentNode. This shouldn't happen.\n return { node: node, offset: existingOffset };\n } else if (compare & Node.DOCUMENT_POSITION_PRECEDING) {\n // node is before parentNode. return start of deepest first child\n var child = parentNode.firstChild;\n while (child.firstChild) {\n child = child.firstChild;\n }\n return { node: child, offset: 0 };\n } else if (compare & Node.DOCUMENT_POSITION_FOLLOWING) {\n // node is after parentNode. return end of deepest last child\n var child = parentNode.lastChild;\n while (child.lastChild) {\n child = child.lastChild;\n }\n\n var offset = (0, _mobiledocKitUtilsDomUtils.isTextNode)(child) ? child.textContent.length : 1;\n return { node: child, offset: offset };\n } else {\n return { node: node, offset: existingOffset };\n }\n }\n\n /*\n * Returns a new selection that is constrained within parentNode.\n * If the anchorNode or focusNode are outside the parentNode, they are replaced with the beginning\n * or end of the parentNode's children\n */\n function constrainSelectionTo(selection, parentNode) {\n var _constrainNodeTo = constrainNodeTo(selection.anchorNode, parentNode, selection.anchorOffset);\n\n var anchorNode = _constrainNodeTo.node;\n var anchorOffset = _constrainNodeTo.offset;\n\n var _constrainNodeTo2 = constrainNodeTo(selection.focusNode, parentNode, selection.focusOffset);\n\n var focusNode = _constrainNodeTo2.node;\n var focusOffset = _constrainNodeTo2.offset;\n\n return { anchorNode: anchorNode, anchorOffset: anchorOffset, focusNode: focusNode, focusOffset: focusOffset };\n }\n\n function comparePosition(_x3) {\n var _again2 = true;\n\n _function2: while (_again2) {\n var selection = _x3;\n _again2 = false;\n var anchorNode = selection.anchorNode;\n var focusNode = selection.focusNode;\n var anchorOffset = selection.anchorOffset;\n var focusOffset = selection.focusOffset;\n\n var headNode = undefined,\n tailNode = undefined,\n headOffset = undefined,\n tailOffset = undefined,\n direction = undefined;\n\n var position = anchorNode.compareDocumentPosition(focusNode);\n\n // IE may select return focus and anchor nodes far up the DOM tree instead of\n // picking the deepest, most specific possible node. For example in\n //\n //
    abcdef
    \n //\n // with a cursor between c and d, IE might say the focusNode is
    with\n // an offset of 1. However the anchorNode for a selection might still be\n // 2 if there was a selection.\n //\n // This code walks down the DOM tree until a good comparison of position can be\n // made.\n //\n if (position & Node.DOCUMENT_POSITION_CONTAINS) {\n if (focusOffset < focusNode.childNodes.length) {\n focusNode = focusNode.childNodes[focusOffset];\n focusOffset = 0;\n } else {\n // This situation happens on IE when triple-clicking to select.\n // Set the focus to the very last character inside the node.\n while (focusNode.lastChild) {\n focusNode = focusNode.lastChild;\n }\n focusOffset = focusNode.textContent.length;\n }\n\n _x3 = {\n focusNode: focusNode,\n focusOffset: focusOffset,\n anchorNode: anchorNode, anchorOffset: anchorOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = undefined;\n continue _function2;\n } else if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {\n var offset = anchorOffset - 1;\n if (offset < 0) {\n offset = 0;\n }\n _x3 = {\n anchorNode: anchorNode.childNodes[offset],\n anchorOffset: 0,\n focusNode: focusNode, focusOffset: focusOffset\n };\n _again2 = true;\n anchorNode = focusNode = anchorOffset = focusOffset = headNode = tailNode = headOffset = tailOffset = direction = position = offset = undefined;\n continue _function2;\n\n // The meat of translating anchor and focus nodes to head and tail nodes\n } else if (position & Node.DOCUMENT_POSITION_FOLLOWING) {\n headNode = anchorNode;tailNode = focusNode;\n headOffset = anchorOffset;tailOffset = focusOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n headNode = focusNode;tailNode = anchorNode;\n headOffset = focusOffset;tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else {\n // same node\n headNode = tailNode = anchorNode;\n headOffset = anchorOffset;\n tailOffset = focusOffset;\n if (tailOffset < headOffset) {\n // Swap the offset order\n headOffset = focusOffset;\n tailOffset = anchorOffset;\n direction = _mobiledocKitUtilsKey.DIRECTION.BACKWARD;\n } else if (headOffset < tailOffset) {\n direction = _mobiledocKitUtilsKey.DIRECTION.FORWARD;\n } else {\n direction = null;\n }\n }\n\n return { headNode: headNode, headOffset: headOffset, tailNode: tailNode, tailOffset: tailOffset, direction: direction };\n }\n }\n\n exports.clearSelection = clearSelection;\n exports.comparePosition = comparePosition;\n exports.findOffsetInNode = findOffsetInNode;\n exports.constrainSelectionTo = constrainSelectionTo;\n});","define(\"mobiledoc-kit/utils/set\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n var Set = (function () {\n function Set() {\n var _this = this;\n\n var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n _classCallCheck(this, Set);\n\n this.items = [];\n items.forEach(function (i) {\n return _this.add(i);\n });\n }\n\n _createClass(Set, [{\n key: \"add\",\n value: function add(item) {\n if (!this.has(item)) {\n this.items.push(item);\n }\n }\n }, {\n key: \"has\",\n value: function has(item) {\n return this.items.indexOf(item) !== -1;\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n return this.items;\n }\n }, {\n key: \"length\",\n get: function get() {\n return this.items.length;\n }\n }]);\n\n return Set;\n })();\n\n exports[\"default\"] = Set;\n});","define('mobiledoc-kit/utils/string-utils', ['exports'], function (exports) {\n /*\n * @param {String} string\n * @return {String} a dasherized string. 'modelIndex' -> 'model-index', etc\n */\n 'use strict';\n\n exports.dasherize = dasherize;\n exports.capitalize = capitalize;\n exports.startsWith = startsWith;\n exports.endsWith = endsWith;\n\n function dasherize(string) {\n return string.replace(/[A-Z]/g, function (match, offset) {\n var lower = match.toLowerCase();\n\n return offset === 0 ? lower : '-' + lower;\n });\n }\n\n function capitalize(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n }\n\n function startsWith(string, character) {\n return string.charAt(0) === character;\n }\n\n function endsWith(string, endString) {\n var index = string.lastIndexOf(endString);\n return index !== -1 && index === string.length - endString.length;\n }\n});","define('mobiledoc-kit/utils/to-range', ['exports', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/assert'], function (exports, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsAssert) {\n 'use strict';\n\n exports['default'] = toRange;\n\n function toRange(rangeLike) {\n (0, _mobiledocKitUtilsAssert['default'])('Must pass non-blank object to \"toRange\"', !!rangeLike);\n\n if (rangeLike instanceof _mobiledocKitUtilsCursorRange['default']) {\n return rangeLike;\n } else if (rangeLike instanceof _mobiledocKitUtilsCursorPosition['default']) {\n return rangeLike.toRange();\n }\n\n (0, _mobiledocKitUtilsAssert['default'])('Incorrect structure for rangeLike: ' + rangeLike, false);\n }\n});","define('mobiledoc-kit/version', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = '##VERSION##';\n});","define('mobiledoc-kit/views/tooltip', ['exports', 'mobiledoc-kit/views/view', 'mobiledoc-kit/utils/element-utils'], function (exports, _mobiledocKitViewsView, _mobiledocKitUtilsElementUtils) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n var DELAY = 200;\n\n var Tooltip = (function (_View) {\n _inherits(Tooltip, _View);\n\n function Tooltip(options) {\n var _this = this;\n\n _classCallCheck(this, Tooltip);\n\n var rootElement = options.rootElement;\n\n var timeout = undefined;\n options.classNames = ['__mobiledoc-tooltip'];\n _get(Object.getPrototypeOf(Tooltip.prototype), 'constructor', this).call(this, options);\n\n this.addEventListener(rootElement, 'mouseover', function (e) {\n var target = (0, _mobiledocKitUtilsElementUtils.getEventTargetMatchingTag)(options.showForTag, e.target, rootElement);\n if (target && target.isContentEditable) {\n timeout = setTimeout(function () {\n _this.showLink(target.href, target);\n }, DELAY);\n }\n });\n\n this.addEventListener(rootElement, 'mouseout', function (e) {\n clearTimeout(timeout);\n if (_this.elementObserver) {\n _this.elementObserver.cancel();\n }\n var toElement = e.toElement || e.relatedTarget;\n if (toElement && toElement.className !== _this.element.className) {\n _this.hide();\n }\n });\n }\n\n _createClass(Tooltip, [{\n key: 'showMessage',\n value: function showMessage(message, element) {\n var tooltipElement = this.element;\n tooltipElement.innerHTML = message;\n this.show();\n (0, _mobiledocKitUtilsElementUtils.positionElementCenteredBelow)(tooltipElement, element);\n }\n }, {\n key: 'showLink',\n value: function showLink(link, element) {\n var _this2 = this;\n\n var message = '' + link + '';\n this.showMessage(message, element);\n this.elementObserver = (0, _mobiledocKitUtilsElementUtils.whenElementIsNotInDOM)(element, function () {\n return _this2.hide();\n });\n }\n }]);\n\n return Tooltip;\n })(_mobiledocKitViewsView['default']);\n\n exports['default'] = Tooltip;\n});","define('mobiledoc-kit/views/view', ['exports', 'mobiledoc-kit/utils/dom-utils'], function (exports, _mobiledocKitUtilsDomUtils) {\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var View = (function () {\n function View() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, View);\n\n options.tagName = options.tagName || 'div';\n options.container = options.container || document.body;\n\n this.element = document.createElement(options.tagName);\n this.container = options.container;\n this.isShowing = false;\n\n var classNames = options.classNames || [];\n classNames.forEach(function (name) {\n return (0, _mobiledocKitUtilsDomUtils.addClassName)(_this.element, name);\n });\n this._eventListeners = [];\n }\n\n _createClass(View, [{\n key: 'addEventListener',\n value: function addEventListener(element, type, listener) {\n element.addEventListener(type, listener);\n this._eventListeners.push([element, type, listener]);\n }\n }, {\n key: 'removeAllEventListeners',\n value: function removeAllEventListeners() {\n this._eventListeners.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3);\n\n var element = _ref2[0];\n var type = _ref2[1];\n var listener = _ref2[2];\n\n element.removeEventListener(type, listener);\n });\n }\n }, {\n key: 'show',\n value: function show() {\n if (!this.isShowing) {\n this.container.appendChild(this.element);\n this.isShowing = true;\n return true;\n }\n }\n }, {\n key: 'hide',\n value: function hide() {\n if (this.isShowing) {\n this.container.removeChild(this.element);\n this.isShowing = false;\n return true;\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.removeAllEventListeners();\n this.hide();\n this.isDestroyed = true;\n }\n }]);\n\n return View;\n })();\n\n exports['default'] = View;\n});","define('mobiledoc-text-renderer/cards/image', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = {\n name: 'image-card',\n type: 'text',\n render: function render() {}\n };\n});","define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n\n function registerGlobal(window) {\n window.MobiledocTextRenderer = _mobiledocTextRendererRendererFactory['default'];\n }\n\n exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default'];\n exports['default'] = _mobiledocTextRendererRendererFactory['default'];\n});","define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) {\n 'use strict';\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocTextRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var cards = _ref.cards;\n var atoms = _ref.atoms;\n var cardOptions = _ref.cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n\n _classCallCheck(this, RendererFactory);\n\n cards = cards || [];\n validateCards(cards);\n atoms = atoms || [];\n validateAtoms(atoms);\n cardOptions = cardOptions || {};\n\n this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION:\n return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render();\n case undefined:\n case null:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var sections = _sectionData[1];\n\n this.root = [];\n this.sections = sections;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n\n // for the text renderer, a missing card is a no-op\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 3);\n\n var type = _ref32[0];\n var name = _ref32[1];\n var payload = _ref32[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 3);\n\n var text = _m[2];\n\n str += text;\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {};\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) {\n /**\n * runtime Text renderer\n * renders a mobiledoc to Text\n *\n * input: mobiledoc\n * output: Text (string)\n */\n 'use strict';\n\n var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\n var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var LINE_BREAK = '\\n';\n\n var MOBILEDOC_VERSION_0_3 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3 = MOBILEDOC_VERSION_0_3;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION_0_3 && version !== MOBILEDOC_VERSION_0_3_1 && version !== MOBILEDOC_VERSION_0_3_2) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n\n validateVersion(version);\n\n this.root = [];\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this = this;\n\n this.sections.forEach(function (section) {\n _this.root.push(_this.renderSection(section));\n });\n\n var result = this.root.join(LINE_BREAK);\n return { result: result, teardown: function teardown() {\n return _this.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Unimplemented renderer for type ' + type);\n }\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection() {\n return '';\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this2 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var items = _ref2[2];\n\n return items.map(function (li) {\n return _this2.renderListItem(li);\n }).join(LINE_BREAK);\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocTextRendererCardsImage['default'].name) {\n return _mobiledocTextRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var index = _ref32[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered || '';\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this3 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n onTeardown: function onTeardown(callback) {\n return _this3._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var tagName = _ref42[1];\n var markers = _ref42[2];\n\n return this.renderMarkers(markers);\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocTextRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this4 = this;\n\n var env = {\n name: atom.name,\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'string') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || '';\n }\n }, {\n key: 'renderMarkers',\n value: function renderMarkers(markers) {\n var _this5 = this;\n\n var str = '';\n markers.forEach(function (m) {\n var _m = _slicedToArray(m, 4);\n\n var type = _m[0];\n var value = _m[3];\n\n switch (type) {\n case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n str += value;\n break;\n case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n str += _this5._renderAtom(value);\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n });\n return str;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function () {\n // for the text renderer, a missing card is a no-op\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref5) {\n var value = _ref5.value;\n\n return value || '';\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-text-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'text';\n});","define(\"mobiledoc-text-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACp3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACl7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5WA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;","file":"mobiledoc-kit.js"} \ No newline at end of file diff --git a/website/tests/built-amd-tests.js b/website/tests/built-amd-tests.js index 818f9b09e..24e1c8f0d 100644 --- a/website/tests/built-amd-tests.js +++ b/website/tests/built-amd-tests.js @@ -32,37 +32,6 @@ define('tests/acceptance/basic-editor-test', ['exports', 'mobiledoc-kit', '../te assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); }); - test('#disableEditing before render is meaningful', function (assert) { - editor = new _mobiledocKit.Editor(); - editor.disableEditing(); - editor.render(editorElement); - - assert.ok(!editorElement.hasAttribute('contenteditable'), 'element is not contenteditable'); - editor.enableEditing(); - assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); - }); - - test('when editing is disabled, the placeholder is not shown', function (assert) { - editor = new _mobiledocKit.Editor({ placeholder: 'the placeholder' }); - editor.disableEditing(); - editor.render(editorElement); - - assert.ok(!$('#editor').data('placeholder'), 'no placeholder when disabled'); - editor.enableEditing(); - assert.equal($('#editor').data('placeholder'), 'the placeholder', 'placeholder is shown when editable'); - }); - - test('#disableEditing and #enableEditing toggle contenteditable', function (assert) { - editor = new _mobiledocKit.Editor(); - editor.render(editorElement); - - assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); - editor.disableEditing(); - assert.equal(editorElement.getAttribute('contenteditable'), 'false', 'element is not contenteditable'); - editor.enableEditing(); - assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); - }); - test('clicking outside the editor does not raise an error', function (assert) { var done = assert.async(); editor = new _mobiledocKit.Editor({ autofocus: false }); @@ -1568,6 +1537,71 @@ define('tests/acceptance/editor-atoms-test', ['exports', 'mobiledoc-kit', '../te assert.renderTreeIsEqual(editor._renderTree, expected); }); }); +define('tests/acceptance/editor-attributes-test', ['exports', '../test-helpers'], function (exports, _testHelpers) { + 'use strict'; + + var _module = _testHelpers['default'].module; + var test = _testHelpers['default'].test; + + var editor = undefined, + editorElement = undefined; + + function renderEditor() { + var _Helpers$mobiledoc; + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + editor = (_Helpers$mobiledoc = _testHelpers['default'].mobiledoc).renderInto.apply(_Helpers$mobiledoc, [editorElement].concat(args)); + editor.selectRange(editor.post.tailPosition()); + return editor; + } + + _module('Acceptance: Editor: Attributes', { + beforeEach: function beforeEach() { + editorElement = $('#editor')[0]; + }, + afterEach: function afterEach() { + if (editor) { + editor.destroy(); + } + } + }); + + test('pressing ENTER at the end of an aligned paragraph maintains the alignment (bug #694)', function (assert) { + renderEditor(function (_ref) { + var post = _ref.post; + var markupSection = _ref.markupSection; + var marker = _ref.marker; + + return post([markupSection('p', [marker('abc')], false, { 'data-md-text-align': 'center' })]); + }); + + _testHelpers['default'].dom.triggerEnter(editor); + + var firstParagraph = document.querySelector('#editor p:first-of-type'); + assert.equal(firstParagraph.getAttribute('data-md-text-align'), 'center'); + }); + + test('toggling the section inside an aligned list maintains the alignment of the list (bug #694)', function (assert) { + renderEditor(function (_ref2) { + var post = _ref2.post; + var listSection = _ref2.listSection; + var listItem = _ref2.listItem; + var marker = _ref2.marker; + + return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('123')])], { 'data-md-text-align': 'center' })]); + }); + + editor.run(function (postEditor) { + return postEditor.toggleSection('h1'); + }); + + var ul = document.querySelector('#editor ul'); + assert.equal(ul.getAttribute('data-md-text-align'), 'center'); + }); +}); define('tests/acceptance/editor-cards-test', ['exports', 'mobiledoc-kit/utils/key', '../test-helpers', 'mobiledoc-kit/models/card'], function (exports, _mobiledocKitUtilsKey, _testHelpers, _mobiledocKitModelsCard) { 'use strict'; @@ -2220,11 +2254,52 @@ define('tests/acceptance/editor-copy-paste-test', ['exports', 'mobiledoc-kit', ' assert.hasElement($('#editor ul:eq(0) li:contains(list)')); }); - test('copy sets html & text for pasting externally', function (assert) { + test('copy-paste can copy card following list section', function (assert) { var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref14) { var post = _ref14.post; var markupSection = _ref14.markupSection; var marker = _ref14.marker; + var listSection = _ref14.listSection; + var listItem = _ref14.listItem; + var cardSection = _ref14.cardSection; + + return post([markupSection('p', [marker('abc')]), listSection('ul', [listItem([marker('list')])]), cardSection('test-card', { foo: 'bar' }), markupSection('p', [marker('123')])]); + }); + var cards = [{ + name: 'test-card', + type: 'dom', + render: function render(_ref15) { + var payload = _ref15.payload; + + return $('
    ' + payload.foo + '
    ')[0]; + } + }]; + editor = new _mobiledocKit.Editor({ mobiledoc: mobiledoc, cards: cards }); + editor.render(editorElement); + + assert.hasElement('#editor .bar', 'precond - renders card'); + + _testHelpers['default'].dom.selectText(editor, 'c', editor.element, '3', editor.element); + + _testHelpers['default'].dom.triggerCopyEvent(editor); + + var textNode = $('#editor p')[1].childNodes[0]; + assert.equal(textNode.textContent, '123', 'precond - correct textNode'); + + _testHelpers['default'].dom.moveCursorTo(editor, textNode, 3); // end of node + _testHelpers['default'].dom.triggerPasteEvent(editor); + + assert.equal($('#editor ul').length, 2, 'pastes the list'); + assert.hasElement('#editor ul:eq(1) li:contains(list)'); + + assert.equal($('#editor .bar').length, 2, 'renders a second card'); + }); + + test('copy sets html & text for pasting externally', function (assert) { + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref16) { + var post = _ref16.post; + var markupSection = _ref16.markupSection; + var marker = _ref16.marker; return post([markupSection('h1', [marker('h1 heading')]), markupSection('h2', [marker('h2 subheader')]), markupSection('p', [marker('The text')])]); }); @@ -2247,11 +2322,11 @@ define('tests/acceptance/editor-copy-paste-test', ['exports', 'mobiledoc-kit', ' test('pasting when cursor is on left/right side of card adds content before/after card', function (assert) { var expected1 = undefined, expected2 = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref15) { - var post = _ref15.post; - var markupSection = _ref15.markupSection; - var cardSection = _ref15.cardSection; - var marker = _ref15.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref17) { + var post = _ref17.post; + var markupSection = _ref17.markupSection; + var cardSection = _ref17.cardSection; + var marker = _ref17.marker; expected1 = post([markupSection('p', [marker('abc')]), cardSection('my-card')]); @@ -2278,12 +2353,12 @@ define('tests/acceptance/editor-copy-paste-test', ['exports', 'mobiledoc-kit', ' // see https://github.com/bustle/mobiledoc-kit/issues/249 test('pasting when replacing a list item works', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref16) { - var post = _ref16.post; - var listSection = _ref16.listSection; - var listItem = _ref16.listItem; - var markupSection = _ref16.markupSection; - var marker = _ref16.marker; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref18) { + var post = _ref18.post; + var listSection = _ref18.listSection; + var listItem = _ref18.listItem; + var markupSection = _ref18.markupSection; + var marker = _ref18.marker; return post([markupSection('p', [marker('X')]), listSection('ul', [listItem([marker('Y')])])]); }); @@ -2305,11 +2380,11 @@ define('tests/acceptance/editor-copy-paste-test', ['exports', 'mobiledoc-kit', ' test('paste with shift key pastes plain text', function (assert) { var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref17) { - var post = _ref17.post; - var markupSection = _ref17.markupSection; - var marker = _ref17.marker; - var markup = _ref17.markup; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref19) { + var post = _ref19.post; + var markupSection = _ref19.markupSection; + var marker = _ref19.marker; + var markup = _ref19.markup; expected = post([markupSection('p', [marker('a'), marker('b', [markup('b')]), marker('cabc')])]); return post([markupSection('p', [marker('a'), marker('b', [markup('b')]), marker('c')])]); @@ -2324,6 +2399,102 @@ define('tests/acceptance/editor-copy-paste-test', ['exports', 'mobiledoc-kit', ' assert.postIsSimilar(editor.post, expected); }); + + test('paste with html that parses to blank doc doesn\'t error', function (assert) { + var expected = undefined; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref20) { + var post = _ref20.post; + var markupSection = _ref20.markupSection; + var marker = _ref20.marker; + + expected = post([markupSection('p', [])]); + + return post([markupSection('p', [marker('abcd')])]); + }); + + editor = new _mobiledocKit.Editor({ mobiledoc: mobiledoc, cards: cards }); + editor.render(editorElement); + + _testHelpers['default'].dom.setCopyData('text/html', '
    '); + editor.selectRange(editor.post.toRange()); + _testHelpers['default'].dom.triggerPasteEvent(editor); + + assert.postIsSimilar(editor.post, expected); + }); +}); +define('tests/acceptance/editor-disable-editing-test', ['exports', 'mobiledoc-kit', '../test-helpers', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/parse-utils'], function (exports, _mobiledocKit, _testHelpers, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsParseUtils) { + 'use strict'; + + var test = _testHelpers['default'].test; + var _module = _testHelpers['default'].module; + + var cards = [{ + name: 'my-card', + type: 'dom', + render: function render() {}, + edit: function edit() {} + }]; + + var editor = undefined, + editorElement = undefined; + + _module('Acceptance: editor: #disableEditing', { + beforeEach: function beforeEach() { + editorElement = $('#editor')[0]; + }, + afterEach: function afterEach() { + if (editor) { + editor.destroy(); + } + } + }); + + test('#disableEditing before render is meaningful', function (assert) { + editor = new _mobiledocKit.Editor(); + editor.disableEditing(); + editor.render(editorElement); + + assert.equal(editorElement.getAttribute('contenteditable'), 'false', 'element is not contenteditable'); + editor.enableEditing(); + assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); + }); + + test('when editing is disabled, the placeholder is not shown', function (assert) { + editor = new _mobiledocKit.Editor({ placeholder: 'the placeholder' }); + editor.disableEditing(); + editor.render(editorElement); + + assert.isBlank(_testHelpers['default'].dom.getData(editorElement, 'placeholder'), 'no placeholder when disabled'); + editor.enableEditing(); + assert.equal(_testHelpers['default'].dom.getData(editorElement, 'placeholder'), 'the placeholder', 'placeholder is shown when editable'); + }); + + test('#disableEditing and #enableEditing toggle contenteditable', function (assert) { + editor = new _mobiledocKit.Editor(); + editor.render(editorElement); + + assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); + editor.disableEditing(); + assert.equal(editorElement.getAttribute('contenteditable'), 'false', 'element is not contenteditable'); + editor.enableEditing(); + assert.equal(editorElement.getAttribute('contenteditable'), 'true', 'element is contenteditable'); + }); + + // https://github.com/bustle/mobiledoc-kit/issues/572 + test('pasting after #disableEditing does not insert text', function (assert) { + editor = _testHelpers['default'].editor.buildFromText('abc|', { element: editorElement }); + + _testHelpers['default'].dom.setCopyData(_mobiledocKitUtilsParseUtils.MIME_TEXT_PLAIN, 'def'); + _testHelpers['default'].dom.triggerPasteEvent(editor); + assert.hasElement('#editor:contains(abcdef)', 'precond - text is pasted'); + + editor.disableEditing(); + + _testHelpers['default'].dom.selectText(editor, 'def'); + _testHelpers['default'].dom.setCopyData(_mobiledocKitUtilsParseUtils.MIME_TEXT_PLAIN, 'ghi'); + _testHelpers['default'].dom.triggerPasteEvent(editor); + assert.hasNoElement('#editor:contains(ghi)', 'text is not pasted after #disableEditing'); + }); }); define('tests/acceptance/editor-drag-drop-test', ['exports', '../test-helpers'], function (exports, _testHelpers) { 'use strict'; @@ -2422,7 +2593,7 @@ define('tests/acceptance/editor-drag-drop-test', ['exports', '../test-helpers'], assert.postIsSimilar(editor.post, expected); }); }); -define('tests/acceptance/editor-input-handlers-test', ['exports', '../test-helpers', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/utils/characters'], function (exports, _testHelpers, _mobiledocKitUtilsCursorRange, _mobiledocKitRenderersEditorDom, _mobiledocKitUtilsCharacters) { +define('tests/acceptance/editor-input-handlers-test', ['exports', '../test-helpers', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/utils/characters', 'mobiledoc-kit/utils/key'], function (exports, _testHelpers, _mobiledocKitUtilsCursorRange, _mobiledocKitRenderersEditorDom, _mobiledocKitUtilsCharacters, _mobiledocKitUtilsKey) { 'use strict'; var _module = _testHelpers['default'].module; @@ -2753,6 +2924,32 @@ define('tests/acceptance/editor-input-handlers-test', ['exports', '../test-helpe assert.ok(didMatch); }); + test('input handler can be triggered by ENTER', function (assert) { + editor = _testHelpers['default'].editor.buildFromText('abc|', { element: editorElement }); + + var didMatch = undefined; + editor.onTextInput({ + name: 'test', + match: /abc\n/, + run: function run() { + didMatch = true; + } + }); + + _testHelpers['default'].dom.insertText(editor, _mobiledocKitUtilsCharacters.ENTER); + + assert.ok(didMatch); + }); + + // See https://github.com/bustle/mobiledoc-kit/issues/565 + test('typing ctrl-TAB does not insert TAB text', function (assert) { + editor = _testHelpers['default'].editor.buildFromText('abc|', { element: editorElement }); + + _testHelpers['default'].dom.triggerKeyCommand(editor, _mobiledocKitUtilsCharacters.TAB, [_mobiledocKitUtilsKey.MODIFIERS.CTRL]); + + assert.equal(editorElement.textContent, 'abc', 'no TAB is inserted'); + }); + test('can unregister all handlers', function (assert) { editor = _testHelpers['default'].editor.buildFromText(''); // there are 3 default helpers @@ -3819,15 +4016,31 @@ define('tests/acceptance/editor-list-test', ['exports', 'mobiledoc-kit', '../tes assert.hasNoElement('#editor li:contains(abc)', 'li text is removed'); assert.hasElement('#editor li:contains(X)', 'text is inserted'); }); -}); -define('tests/acceptance/editor-post-editor-test', ['exports', 'mobiledoc-kit', '../test-helpers', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKit, _testHelpers, _mobiledocKitUtilsCursorRange) { - 'use strict'; - var _module = _testHelpers['default'].module; - var test = _testHelpers['default'].test; + test('list sections may contain attributes', function (assert) { + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref2) { + var post = _ref2.post; + var listSection = _ref2.listSection; + var listItem = _ref2.listItem; + var marker = _ref2.marker; - var editor = undefined, - editorElement = undefined; + return post([listSection('ul', [listItem([marker('abc')]), listItem()], { 'data-md-text-align': 'center' })]); + }); + + editor = new _mobiledocKit.Editor({ mobiledoc: mobiledoc }); + editor.render(editorElement); + + assert.hasElement('#editor ul[data-md-text-align="center"]'); + }); +}); +define('tests/acceptance/editor-post-editor-test', ['exports', 'mobiledoc-kit', '../test-helpers', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKit, _testHelpers, _mobiledocKitUtilsCursorRange) { + 'use strict'; + + var _module = _testHelpers['default'].module; + var test = _testHelpers['default'].test; + + var editor = undefined, + editorElement = undefined; _module('Acceptance: Editor - PostEditor', { beforeEach: function beforeEach() { @@ -4152,6 +4365,21 @@ define('tests/acceptance/editor-post-editor-test', ['exports', 'mobiledoc-kit', assert.ok(editor.range.isEqual(newRange), 'newRange is rendered after run'); }); + + test('markup sections may contain attributes', function (assert) { + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref12) { + var post = _ref12.post; + var markupSection = _ref12.markupSection; + var marker = _ref12.marker; + + return post([markupSection('p', [marker('123')], false, { 'data-md-text-align': 'center' })]); + }); + + editor = new _mobiledocKit.Editor({ mobiledoc: mobiledoc }); + editor.render(editorElement); + + assert.hasElement('#editor p[data-md-text-align="center"]'); + }); }); define('tests/acceptance/editor-reparse-test', ['exports', '../test-helpers', 'mobiledoc-kit/renderers/editor-dom'], function (exports, _testHelpers, _mobiledocKitRenderersEditorDom) { 'use strict'; @@ -4450,7 +4678,7 @@ define('tests/acceptance/editor-reparse-test', ['exports', '../test-helpers', 'm }); }); }); -define('tests/acceptance/editor-sections-test', ['exports', 'mobiledoc-kit', '../test-helpers', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/browser'], function (exports, _mobiledocKit, _testHelpers, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersEditorDom, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsBrowser) { +define('tests/acceptance/editor-sections-test', ['exports', 'mobiledoc-kit', '../test-helpers', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/browser', 'mobiledoc-kit/utils/key'], function (exports, _mobiledocKit, _testHelpers, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersEditorDom, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsBrowser, _mobiledocKitUtilsKey) { 'use strict'; var test = _testHelpers['default'].test; @@ -5055,19 +5283,24 @@ define('tests/acceptance/editor-sections-test', ['exports', 'mobiledoc-kit', '.. editor.selectRange(new _mobiledocKitUtilsCursorRange['default'](editor.post.tailPosition())); - var keyCode = _mobiledocKitUtilsBrowser['default'].isMac() ? _mobiledocKitUtilsKeycodes['default'].ALT : _mobiledocKitUtilsKeycodes['default'].CTRL; + var altKey = undefined, + ctrlKey = undefined; + if (_mobiledocKitUtilsBrowser['default'].isMac()) { + /* Mac key codes for navigation by word */ + altKey = true; + ctrlKey = false; + } else { + /* PC key codes for navigation by word */ + altKey = false; + ctrlKey = true; + } - _testHelpers['default'].dom.triggerKeyEvent(editor, 'keydown', { keyCode: keyCode }); _testHelpers['default'].wait(function () { - _testHelpers['default'].dom.triggerDelete(editor); + _testHelpers['default'].dom.triggerDelete(editor, _mobiledocKitUtilsKey.DIRECTION.BACKWARD, { altKey: altKey, ctrlKey: ctrlKey }); _testHelpers['default'].wait(function () { - _testHelpers['default'].dom.triggerKeyEvent(editor, 'keyup', { keyCode: keyCode }); - - _testHelpers['default'].wait(function () { - assert.postIsSimilar(editor.post, expected); - done(); - }); + assert.postIsSimilar(editor.post, expected); + done(); }); }); }); @@ -6170,2338 +6403,2430 @@ define('tests/acceptance/editor-undo-redo-test', ['exports', 'mobiledoc-kit/util assert.postIsSimilar(editor.post, afterUndo, 'atom is restored'); }); }); -define('tests/fixtures/google-docs', ['exports'], function (exports) { - 'use strict'; +QUnit.module('ESLint | tests/eslint/acceptance/basic-editor-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/basic-editor-test.js should pass ESLint\n\n'); +}); - exports['default'] = { - 'simple paragraph as span': { - expected: "

    simple paragraph

    ", - raw: 'simple paragraph' - }, - 'simple paragraph as span (Chrome - Windows)': { - expected: "

    simple paragraph

    ", - raw: 'simple paragraph' - }, +QUnit.module('ESLint | tests/eslint/acceptance/cursor-movement-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/cursor-movement-test.js should pass ESLint\n\n'); +}); - // when selecting a line without including the end of the line, the html represention - // includes a or series of s - 'paragraph with bold as span': { - expected: "

    paragraph with bold

    ", - raw: 'paragraph with bold' - }, - 'paragraph with bold as span (Chrome - Windows)': { - expected: "

    paragraph with bold

    ", - raw: 'paragraph with bold' - }, +QUnit.module('ESLint | tests/eslint/acceptance/cursor-position-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/cursor-position-test.js should pass ESLint\n\n'); +}); - // when selecting a line that includes the end (using, e.g., shift+up to selection the entire line), - // the html representation includes a

    tag - 'paragraph with bold as p': { - expected: "

    A bold paragraph.

    ", - raw: '

    A bold paragraph.


    ' - }, - 'paragraph with italic as span': { - expected: "

    paragraph with italic

    ", - raw: 'paragraph with italic' - }, - 'paragraph with bold + italic as p': { - expected: "

    And a second bold italic paragraph.", - raw: '

    And a second bold italic paragraph.


    ' - }, - '2 paragraphs as p': { - expected: "

    Paragraph 1

    Paragraph 2

    ", - raw: '

    Paragraph 1


    Paragraph 2
    ' - }, - 'h1 with h1 tag': { - expected: "

    h1 text

    ", - raw: '

    h1 text

    ' - }, - 'paragraph with link as span': { - expected: "

    link to bustle

    ", - raw: 'link to bustle' - }, - 'paragraph with link as p': { - expected: "

    link to bustle

    ", - raw: '

    link to bustle


    ' - }, - 'img in span': { - expected: "

    ", - raw: '' - } - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-atoms-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-atoms-test.js should pass ESLint\n\n'); }); -define('tests/helpers/assertions', ['exports', './dom', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/models/types'], function (exports, _dom, _mobiledocKitRenderersMobiledoc, _mobiledocKitModelsTypes) { - /* global QUnit, $ */ - 'use strict'; +QUnit.module('ESLint | tests/eslint/acceptance/editor-attributes-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-attributes-test.js should pass ESLint\n\n'); +}); - exports['default'] = registerAssertions; +QUnit.module('ESLint | tests/eslint/acceptance/editor-cards-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-cards-test.js should pass ESLint\n\n'); +}); - /*jshint latedef: false */ - function compareMarkers(actual, expected, assert, path, deepCompare) { - if (actual.value !== expected.value) { - assert.equal(actual.value, expected.value, 'wrong value at ' + path); - } - if (actual.markups.length !== expected.markups.length) { - assert.equal(actual.markups.length, expected.markups.length, 'wrong markups at ' + path); - } - if (deepCompare) { - actual.markups.forEach(function (markup, index) { - comparePostNode(markup, expected.markups[index], assert, path + ':' + index, deepCompare); - }); - } - } +QUnit.module('ESLint | tests/eslint/acceptance/editor-copy-paste-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-copy-paste-test.js should pass ESLint\n\n'); +}); - function comparePostNode(actual, expected, assert) { - var path = arguments.length <= 3 || arguments[3] === undefined ? 'root' : arguments[3]; - var deepCompare = arguments.length <= 4 || arguments[4] === undefined ? false : arguments[4]; +QUnit.module('ESLint | tests/eslint/acceptance/editor-disable-editing-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-disable-editing-test.js should pass ESLint\n\n'); +}); - if (!actual || !expected) { - assert.ok(!!actual, 'missing actual post node at ' + path); - assert.ok(!!expected, 'missing expected post node at ' + path); - return; - } - if (actual.type !== expected.type) { - assert.pushResult({ - result: false, - actual: actual.type, - expected: expected.type, - message: 'wrong type at ' + path - }); - } +QUnit.module('ESLint | tests/eslint/acceptance/editor-drag-drop-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-drag-drop-test.js should pass ESLint\n\n'); +}); - switch (actual.type) { - case _mobiledocKitModelsTypes.POST_TYPE: - if (actual.sections.length !== expected.sections.length) { - assert.equal(actual.sections.length, expected.sections.length, 'wrong sections for post'); - } - if (deepCompare) { - actual.sections.forEach(function (section, index) { - comparePostNode(section, expected.sections.objectAt(index), assert, path + ':' + index, deepCompare); - }); - } - break; - case _mobiledocKitModelsTypes.ATOM_TYPE: - if (actual.name !== expected.name) { - assert.equal(actual.name, expected.name, 'wrong atom name at ' + path); - } - compareMarkers(actual, expected, assert, path, deepCompare); - break; - case _mobiledocKitModelsTypes.MARKER_TYPE: - compareMarkers(actual, expected, assert, path, deepCompare); - break; - case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE: - case _mobiledocKitModelsTypes.LIST_ITEM_TYPE: - if (actual.tagName !== expected.tagName) { - assert.equal(actual.tagName, expected.tagName, 'wrong tagName at ' + path); - } - if (actual.markers.length !== expected.markers.length) { - assert.equal(actual.markers.length, expected.markers.length, 'wrong markers at ' + path); - } - if (deepCompare) { - actual.markers.forEach(function (marker, index) { - comparePostNode(marker, expected.markers.objectAt(index), assert, path + ':' + index, deepCompare); - }); - } - break; - case _mobiledocKitModelsTypes.CARD_TYPE: - if (actual.name !== expected.name) { - assert.equal(actual.name, expected.name, 'wrong card name at ' + path); - } - if (!QUnit.equiv(actual.payload, expected.payload)) { - assert.deepEqual(actual.payload, expected.payload, 'wrong card payload at ' + path); - } - break; - case _mobiledocKitModelsTypes.LIST_SECTION_TYPE: - if (actual.items.length !== expected.items.length) { - assert.equal(actual.items.length, expected.items.length, 'wrong items at ' + path); - } - if (deepCompare) { - actual.items.forEach(function (item, index) { - comparePostNode(item, expected.items.objectAt(index), assert, path + ':' + index, deepCompare); - }); - } - break; - case _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE: - if (actual.src !== expected.src) { - assert.equal(actual.src, expected.src, 'wrong image src at ' + path); - } - break; - case _mobiledocKitModelsTypes.MARKUP_TYPE: - if (actual.tagName !== expected.tagName) { - assert.equal(actual.tagName, expected.tagName, 'wrong tagName at ' + path); - } - if (!QUnit.equiv(actual.attributes, expected.attributes)) { - assert.deepEqual(actual.attributes, expected.attributes, 'wrong attributes at ' + path); - } - break; - default: - throw new Error('wrong type :' + actual.type); - } - } +QUnit.module('ESLint | tests/eslint/acceptance/editor-input-handlers-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-input-handlers-test.js should pass ESLint\n\n'); +}); - function registerAssertions(QUnit) { - QUnit.assert.hasElement = function (selector) { - var message = arguments.length <= 1 || arguments[1] === undefined ? 'hasElement "' + selector + '"' : arguments[1]; - return (function () { - var found = $(selector); - this.pushResult({ - result: found.length > 0, - actual: found.length, - expected: selector, - message: message - }); - return found; - }).apply(this, arguments); - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-key-commands-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-key-commands-test.js should pass ESLint\n\n'); +}); - QUnit.assert.hasNoElement = function (selector) { - var message = arguments.length <= 1 || arguments[1] === undefined ? 'hasNoElement "' + selector + '"' : arguments[1]; - return (function () { - var found = $(selector); - this.pushResult({ - result: found.length === 0, - actual: found.length, - expected: selector, - message: message - }); - return found; - }).apply(this, arguments); - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-list-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-list-test.js should pass ESLint\n\n'); +}); - QUnit.assert.hasClass = function (element, className) { - var message = arguments.length <= 2 || arguments[2] === undefined ? 'element has class "' + className + '"' : arguments[2]; - return (function () { - this.pushResult({ - result: element.classList.contains(className), - actual: element.classList, - expected: className, - message: message - }); - }).apply(this, arguments); - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-post-editor-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-post-editor-test.js should pass ESLint\n\n'); +}); - QUnit.assert.notHasClass = function (element, className) { - var message = arguments.length <= 2 || arguments[2] === undefined ? 'element has class "' + className + '"' : arguments[2]; - return (function () { - this.pushResult({ - result: !element.classList.contains(className), - actual: element.classList, - expected: className, - message: message - }); - }).apply(this, arguments); - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-reparse-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-reparse-test.js should pass ESLint\n\n'); +}); - QUnit.assert.selectedText = function (text) { - var message = arguments.length <= 1 || arguments[1] === undefined ? 'selectedText "' + text + '"' : arguments[1]; - return (function () { - var selected = _dom['default'].getSelectedText(); - this.pushResult({ - result: selected === text, - actual: selected, - expected: text, - message: message - }); - }).apply(this, arguments); - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-sections-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-sections-test.js should pass ESLint\n\n'); +}); - QUnit.assert.inArray = function (element, array) { - var message = arguments.length <= 2 || arguments[2] === undefined ? 'has "' + element + '" in "' + array + '"' : arguments[2]; - return (function () { - QUnit.assert.ok(array.indexOf(element) !== -1, message); - })(); - }; +QUnit.module('ESLint | tests/eslint/acceptance/editor-selections-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-selections-test.js should pass ESLint\n\n'); +}); - QUnit.assert.postIsSimilar = function (post, expected) { - var postName = arguments.length <= 2 || arguments[2] === undefined ? 'post' : arguments[2]; +QUnit.module('ESLint | tests/eslint/acceptance/editor-undo-redo-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/acceptance/editor-undo-redo-test.js should pass ESLint\n\n'); +}); - comparePostNode(post, expected, this, postName, true); - var mobiledoc = _mobiledocKitRenderersMobiledoc['default'].render(post), - expectedMobiledoc = _mobiledocKitRenderersMobiledoc['default'].render(expected); - this.deepEqual(mobiledoc, expectedMobiledoc, postName + ' is similar to expected'); - }; +QUnit.module('ESLint | tests/eslint/fixtures/google-docs.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/fixtures/google-docs.js should pass ESLint\n\n'); +}); - QUnit.assert.renderTreeIsEqual = function (renderTree, expectedPost) { - var _this = this; +QUnit.module('ESLint | tests/eslint/helpers/assertions.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/assertions.js should pass ESLint\n\n'); +}); - if (renderTree.rootNode.isDirty) { - this.ok(false, 'renderTree is dirty'); - return; - } +QUnit.module('ESLint | tests/eslint/helpers/browsers.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/browsers.js should pass ESLint\n\n'); +}); - expectedPost.sections.forEach(function (section, index) { - var renderNode = renderTree.rootNode.childNodes.objectAt(index); - var path = 'post:' + index; +QUnit.module('ESLint | tests/eslint/helpers/dom.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/dom.js should pass ESLint\n\n'); +}); - var compareChildren = function compareChildren(parentPostNode, parentRenderNode, path) { - var children = parentPostNode.markers || parentPostNode.items || []; +QUnit.module('ESLint | tests/eslint/helpers/editor.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/editor.js should pass ESLint\n\n'); +}); - if (children.length !== parentRenderNode.childNodes.length) { - _this.equal(parentRenderNode.childNodes.length, children.length, 'wrong child render nodes at ' + path); - return; - } +QUnit.module('ESLint | tests/eslint/helpers/mobiledoc.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/mobiledoc.js should pass ESLint\n\n'); +}); - children.forEach(function (child, index) { - var renderNode = parentRenderNode.childNodes.objectAt(index); +QUnit.module('ESLint | tests/eslint/helpers/mock-editor.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/mock-editor.js should pass ESLint\n\n'); +}); - comparePostNode(child, renderNode && renderNode.postNode, _this, path + ':' + index, false); - compareChildren(child, renderNode, path + ':' + index); - }); - }; +QUnit.module('ESLint | tests/eslint/helpers/module-load-failure.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/module-load-failure.js should pass ESLint\n\n'); +}); - comparePostNode(section, renderNode.postNode, _this, path, false); - compareChildren(section, renderNode, path); - }); +QUnit.module('ESLint | tests/eslint/helpers/post-abstract.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/post-abstract.js should pass ESLint\n\n'); +}); - this.ok(true, 'renderNode is similar'); - }; +QUnit.module('ESLint | tests/eslint/helpers/post-editor-run.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/post-editor-run.js should pass ESLint\n\n'); +}); - QUnit.assert.positionIsEqual = function (position, expected) { - var message = arguments.length <= 2 || arguments[2] === undefined ? 'position is equal' : arguments[2]; +QUnit.module('ESLint | tests/eslint/helpers/render-built-abstract.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/render-built-abstract.js should pass ESLint\n\n'); +}); - if (position.section !== expected.section) { - this.pushResult({ - result: false, - actual: position.section.type + ':' + position.section.tagName, - expected: expected.section.type + ':' + expected.section.tagName, - message: 'incorrect position section (' + message + ')' - }); - } else if (position.offset !== expected.offset) { - this.pushResult({ - result: false, - actual: position.offset, - expected: expected.offset, - message: 'incorrect position offset (' + message + ')' - }); - } else { - this.pushResult({ - result: true, - actual: position, - expected: expected, - message: message - }); - } - }; +QUnit.module('ESLint | tests/eslint/helpers/sections.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/sections.js should pass ESLint\n\n'); +}); - QUnit.assert.rangeIsEqual = function (range, expected) { - var message = arguments.length <= 2 || arguments[2] === undefined ? 'range is equal' : arguments[2]; - var head = range.head; - var tail = range.tail; - var isCollapsed = range.isCollapsed; - var direction = range.direction; - var expectedHead = expected.head; - var expectedTail = expected.tail; - var expectedIsCollapsed = expected.isCollapsed; - var expectedDirection = expected.direction; +QUnit.module('ESLint | tests/eslint/helpers/wait.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/helpers/wait.js should pass ESLint\n\n'); +}); - var failed = false; +QUnit.module('ESLint | tests/eslint/js/cards/image.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/cards/image.js should pass ESLint\n\n'); +}); - if (!head.isEqual(expectedHead)) { - failed = true; - this.pushResult({ - result: false, - actual: head.section.type + ':' + head.section.tagName, - expected: expectedHead.section.type + ':' + expectedHead.section.tagName, - message: 'incorrect head position' - }); - } +QUnit.module('ESLint | tests/eslint/js/editor/edit-history.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/edit-history.js should pass ESLint\n\n'); +}); - if (!tail.isEqual(expectedTail)) { - failed = true; - this.pushResult({ - result: false, - actual: tail.section.type + ':' + tail.section.tagName, - expected: expectedTail.section.type + ':' + expectedTail.section.tagName, - message: 'incorrect tail position' - }); - } +QUnit.module('ESLint | tests/eslint/js/editor/edit-state.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/edit-state.js should pass ESLint\n\n'); +}); - if (isCollapsed !== expectedIsCollapsed) { - failed = true; - this.pushResult({ - result: false, - actual: isCollapsed, - expected: expectedIsCollapsed, - message: 'wrong value for isCollapsed' - }); - } +QUnit.module('ESLint | tests/eslint/js/editor/editor.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/editor.js should pass ESLint\n\n'); +}); - if (direction !== expectedDirection) { - failed = true; - this.pushResult({ - result: false, - actual: direction, - expected: expectedDirection, - message: 'wrong value for direction' - }); - } +QUnit.module('ESLint | tests/eslint/js/editor/event-manager.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/event-manager.js should pass ESLint\n\n'); +}); - if (!failed) { - this.pushResult({ - result: true, - actual: range, - expected: expected, - message: message - }); - } - }; - } +QUnit.module('ESLint | tests/eslint/js/editor/key-commands.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/key-commands.js should pass ESLint\n\n'); }); -define("tests/helpers/browsers", ["exports"], function (exports) { - "use strict"; - exports.detectIE = detectIE; - exports.detectIE11 = detectIE11; - exports.supportsSelectionExtend = supportsSelectionExtend; +QUnit.module('ESLint | tests/eslint/js/editor/mutation-handler.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/mutation-handler.js should pass ESLint\n\n'); +}); - function detectIE() { - var userAgent = navigator.userAgent; - return userAgent.indexOf("MSIE ") !== -1 || userAgent.indexOf("Trident/") !== -1 || userAgent.indexOf('Edge/') !== -1; - } +QUnit.module('ESLint | tests/eslint/js/editor/post.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/post.js should pass ESLint\n\n'); +}); - function detectIE11() { - return detectIE() && navigator.userAgent.indexOf("rv:11.0") !== -1; - } +QUnit.module('ESLint | tests/eslint/js/editor/post/post-inserter.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/post/post-inserter.js should pass ESLint\n\n'); +}); - function supportsSelectionExtend() { - var selection = window.getSelection(); - return !!selection.extend; - } +QUnit.module('ESLint | tests/eslint/js/editor/selection-change-observer.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/selection-change-observer.js should pass ESLint\n\n'); }); -define('tests/helpers/dom', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit', 'mobiledoc-kit/utils/parse-utils'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsMerge, _mobiledocKit, _mobiledocKitUtilsParseUtils) { - 'use strict'; - function assertEditor(editor) { - if (!(editor instanceof _mobiledocKit.Editor)) { - throw new Error('Must pass editor as first argument'); - } - } +QUnit.module('ESLint | tests/eslint/js/editor/selection-manager.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/selection-manager.js should pass ESLint\n\n'); +}); - // walks DOWN the dom from node to childNodes, returning the element - // for which `conditionFn(element)` is true - function walkDOMUntil(topNode) { - var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1]; +QUnit.module('ESLint | tests/eslint/js/editor/text-input-handler.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/text-input-handler.js should pass ESLint\n\n'); +}); - if (!topNode) { - throw new Error('Cannot call walkDOMUntil without a node'); - } - var stack = [topNode]; - var currentElement = undefined; +QUnit.module('ESLint | tests/eslint/js/editor/text-input-handlers.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/text-input-handlers.js should pass ESLint\n\n'); +}); - while (stack.length) { - currentElement = stack.pop(); +QUnit.module('ESLint | tests/eslint/js/editor/ui.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/editor/ui.js should pass ESLint\n\n'); +}); - if (conditionFn(currentElement)) { - return currentElement; - } +QUnit.module('ESLint | tests/eslint/js/index.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/index.js should pass ESLint\n\n'); +}); - // jshint -W083 - (0, _mobiledocKitUtilsArrayUtils.forEach)(currentElement.childNodes, function (el) { - return stack.push(el); - }); - // jshint +W083 - } - } +QUnit.module('ESLint | tests/eslint/js/models/_attributable.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/_attributable.js should pass ESLint\n\n'); +}); - function findTextNode(parentElement, text) { - return walkDOMUntil(parentElement, function (node) { - return (0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.textContent.indexOf(text) !== -1; - }); - } +QUnit.module('ESLint | tests/eslint/js/models/_markerable.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/_markerable.js should pass ESLint\n\n'); +}); - function selectRange(startNode, startOffset, endNode, endOffset) { - (0, _mobiledocKitUtilsSelectionUtils.clearSelection)(); +QUnit.module('ESLint | tests/eslint/js/models/_section.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/_section.js should pass ESLint\n\n'); +}); - var range = document.createRange(); - range.setStart(startNode, startOffset); - range.setEnd(endNode, endOffset); +QUnit.module('ESLint | tests/eslint/js/models/atom-node.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/atom-node.js should pass ESLint\n\n'); +}); - var selection = window.getSelection(); - selection.addRange(range); - } +QUnit.module('ESLint | tests/eslint/js/models/atom.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/atom.js should pass ESLint\n\n'); +}); - function selectText(editor, startText, startContainingElement) { - var endText = arguments.length <= 3 || arguments[3] === undefined ? startText : arguments[3]; - var endContainingElement = arguments.length <= 4 || arguments[4] === undefined ? startContainingElement : arguments[4]; - return (function () { +QUnit.module('ESLint | tests/eslint/js/models/card-node.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/card-node.js should pass ESLint\n\n'); +}); - assertEditor(editor); - var startTextNode = findTextNode(startContainingElement, startText); - var endTextNode = findTextNode(endContainingElement, endText); +QUnit.module('ESLint | tests/eslint/js/models/card.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/card.js should pass ESLint\n\n'); +}); - if (!startTextNode) { - throw new Error('Could not find a starting textNode containing "' + startText + '"'); - } - if (!endTextNode) { - throw new Error('Could not find an ending textNode containing "' + endText + '"'); - } +QUnit.module('ESLint | tests/eslint/js/models/image.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/image.js should pass ESLint\n\n'); +}); - var startOffset = startTextNode.textContent.indexOf(startText), - endOffset = endTextNode.textContent.indexOf(endText) + endText.length; - selectRange(startTextNode, startOffset, endTextNode, endOffset); - editor._readRangeFromDOM(); - })(); - } +QUnit.module('ESLint | tests/eslint/js/models/lifecycle-callbacks.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/lifecycle-callbacks.js should pass ESLint\n\n'); +}); - function moveCursorWithoutNotifyingEditorTo(editor, node) { - var offset = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2]; - var endNode = arguments.length <= 3 || arguments[3] === undefined ? node : arguments[3]; - var endOffset = arguments.length <= 4 || arguments[4] === undefined ? offset : arguments[4]; - return (function () { - selectRange(node, offset, endNode, endOffset); - })(); - } +QUnit.module('ESLint | tests/eslint/js/models/list-item.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/list-item.js should pass ESLint\n\n'); +}); - function moveCursorTo(editor, node) { - var offset = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2]; - var endNode = arguments.length <= 3 || arguments[3] === undefined ? node : arguments[3]; - var endOffset = arguments.length <= 4 || arguments[4] === undefined ? offset : arguments[4]; - return (function () { - assertEditor(editor); - if (!node) { - throw new Error('Cannot moveCursorTo node without node'); - } - moveCursorWithoutNotifyingEditorTo(editor, node, offset, endNode, endOffset); - editor._readRangeFromDOM(); - })(); - } +QUnit.module('ESLint | tests/eslint/js/models/list-section.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/list-section.js should pass ESLint\n\n'); +}); - function triggerEvent(node, eventType) { - if (!node) { - throw new Error('Attempted to trigger event "' + eventType + '" on undefined node'); - } +QUnit.module('ESLint | tests/eslint/js/models/marker.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/marker.js should pass ESLint\n\n'); +}); - var clickEvent = document.createEvent('MouseEvents'); - clickEvent.initEvent(eventType, true, true); - return node.dispatchEvent(clickEvent); - } +QUnit.module('ESLint | tests/eslint/js/models/markup-section.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/markup-section.js should pass ESLint\n\n'); +}); - function _triggerEditorEvent(editor, event) { - editor.triggerEvent(editor.element, event.type, event); - } +QUnit.module('ESLint | tests/eslint/js/models/markup.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/markup.js should pass ESLint\n\n'); +}); - function _buildDOM(tagName) { - var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - var children = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/models/post-node-builder.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/post-node-builder.js should pass ESLint\n\n'); +}); - var el = document.createElement(tagName); - Object.keys(attributes).forEach(function (k) { - return el.setAttribute(k, attributes[k]); - }); - children.forEach(function (child) { - return el.appendChild(child); - }); - return el; - } +QUnit.module('ESLint | tests/eslint/js/models/post.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/post.js should pass ESLint\n\n'); +}); - _buildDOM.text = function (string) { - return document.createTextNode(string); - }; +QUnit.module('ESLint | tests/eslint/js/models/render-node.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/render-node.js should pass ESLint\n\n'); +}); - /** - * Usage: - * build(t => - * t('div', attributes={}, children=[ - * t('b', {}, [ - * t.text('I am a bold text node') - * ]) - * ]) - * ); - */ - function build(tree) { - return tree(_buildDOM); - } +QUnit.module('ESLint | tests/eslint/js/models/render-tree.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/render-tree.js should pass ESLint\n\n'); +}); - function getSelectedText() { - var selection = window.getSelection(); - if (selection.rangeCount === 0) { - return null; - } else if (selection.rangeCount > 1) { - // FIXME? - throw new Error('Unable to get selected text for multiple ranges'); - } else { - return selection.toString(); - } - } +QUnit.module('ESLint | tests/eslint/js/models/types.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/models/types.js should pass ESLint\n\n'); +}); - // returns the node and the offset that the cursor is on - function getCursorPosition() { - var selection = window.getSelection(); - return { - node: selection.anchorNode, - offset: selection.anchorOffset - }; - } +QUnit.module('ESLint | tests/eslint/js/parsers/dom.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/dom.js should pass ESLint\n\n'); +}); - function createMockEvent(eventName, element) { - var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/parsers/html.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/html.js should pass ESLint\n\n'); +}); - var event = { - type: eventName, - preventDefault: function preventDefault() {}, - target: element - }; - (0, _mobiledocKitUtilsMerge.merge)(event, options); - return event; - } +QUnit.module('ESLint | tests/eslint/js/parsers/mobiledoc/0-2.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/mobiledoc/0-2.js should pass ESLint\n\n'); +}); - function triggerDelete(editor) { - var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1]; +QUnit.module('ESLint | tests/eslint/js/parsers/mobiledoc/0-3-1.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/mobiledoc/0-3-1.js should pass ESLint\n\n'); +}); - assertEditor(editor); - var keyCode = direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? _mobiledocKitUtilsKeycodes['default'].BACKSPACE : _mobiledocKitUtilsKeycodes['default'].DELETE; - var event = createMockEvent('keydown', editor.element, { - keyCode: keyCode - }); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/parsers/mobiledoc/0-3-2.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/mobiledoc/0-3-2.js should pass ESLint\n\n'); +}); - function triggerForwardDelete(editor) { - return triggerDelete(editor, _mobiledocKitUtilsKey.DIRECTION.FORWARD); - } +QUnit.module('ESLint | tests/eslint/js/parsers/mobiledoc/0-3.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/mobiledoc/0-3.js should pass ESLint\n\n'); +}); - function triggerEnter(editor) { - assertEditor(editor); - var event = createMockEvent('keydown', editor.element, { keyCode: _mobiledocKitUtilsKeycodes['default'].ENTER }); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/parsers/mobiledoc/index.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/mobiledoc/index.js should pass ESLint\n\n'); +}); - // keyCodes and charCodes are similar but not the same. - function keyCodeForChar(letter) { - var keyCode = undefined; - switch (letter) { - case '.': - keyCode = _mobiledocKitUtilsKeycodes['default']['.']; - break; - case '\n': - keyCode = _mobiledocKitUtilsKeycodes['default'].ENTER; - break; - default: - keyCode = letter.charCodeAt(0); - } - return keyCode; - } +QUnit.module('ESLint | tests/eslint/js/parsers/section.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/section.js should pass ESLint\n\n'); +}); - function insertText(editor, string) { - if (!string && editor) { - throw new Error('Must pass `editor` to `insertText`'); - } +QUnit.module('ESLint | tests/eslint/js/parsers/text.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/parsers/text.js should pass ESLint\n\n'); +}); - string.split('').forEach(function (letter) { - var stop = false; - var keyCode = keyCodeForChar(letter); - var charCode = letter.charCodeAt(0); - var preventDefault = function preventDefault() { - return stop = true; - }; - var keydown = createMockEvent('keydown', editor.element, { - keyCode: keyCode, - charCode: charCode, - preventDefault: preventDefault - }); - var keypress = createMockEvent('keypress', editor.element, { - keyCode: keyCode, - charCode: charCode - }); - var keyup = createMockEvent('keyup', editor.element, { - keyCode: keyCode, - charCode: charCode, - preventDefault: preventDefault - }); +QUnit.module('ESLint | tests/eslint/js/renderers/editor-dom.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/renderers/editor-dom.js should pass ESLint\n\n'); +}); - _triggerEditorEvent(editor, keydown); - if (stop) { - return; - } - _triggerEditorEvent(editor, keypress); - if (stop) { - return; - } - _triggerEditorEvent(editor, keyup); - }); - } +QUnit.module('ESLint | tests/eslint/js/renderers/mobiledoc/0-2.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/renderers/mobiledoc/0-2.js should pass ESLint\n\n'); +}); - function triggerKeyEvent(editor, eventName) { - var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/renderers/mobiledoc/0-3-1.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/renderers/mobiledoc/0-3-1.js should pass ESLint\n\n'); +}); - var event = createMockEvent(eventName, editor.element, options); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/renderers/mobiledoc/0-3-2.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/renderers/mobiledoc/0-3-2.js should pass ESLint\n\n'); +}); - // triggers a key sequence like cmd-B on the editor, to test out - // registered keyCommands - function triggerKeyCommand(editor, string) { - var modifiers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/renderers/mobiledoc/0-3.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/renderers/mobiledoc/0-3.js should pass ESLint\n\n'); +}); - if (typeof modifiers === "number") { - modifiers = [modifiers]; // convert singular to array - } - var charCode = _mobiledocKitUtilsKeycodes['default'][string] || string.toUpperCase().charCodeAt(0); - var keyCode = charCode; - var keyEvent = createMockEvent('keydown', editor.element, { - charCode: charCode, - keyCode: keyCode, - shiftKey: (0, _mobiledocKitUtilsArrayUtils.contains)(modifiers, _mobiledocKitUtilsKey.MODIFIERS.SHIFT), - metaKey: (0, _mobiledocKitUtilsArrayUtils.contains)(modifiers, _mobiledocKitUtilsKey.MODIFIERS.META), - ctrlKey: (0, _mobiledocKitUtilsArrayUtils.contains)(modifiers, _mobiledocKitUtilsKey.MODIFIERS.CTRL) - }); - _triggerEditorEvent(editor, keyEvent); - } +QUnit.module('ESLint | tests/eslint/js/renderers/mobiledoc/index.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/renderers/mobiledoc/index.js should pass ESLint\n\n'); +}); - function triggerKeyEvent(editor, type, options) { - var event = createMockEvent(type, editor.element, options); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/utils/array-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/array-utils.js should pass ESLint\n\n'); +}); - function triggerRightArrowKey(editor, modifier) { - if (!(editor instanceof _mobiledocKit.Editor)) { - throw new Error('Must pass editor to triggerRightArrowKey'); - } - var keydown = createMockEvent('keydown', editor.element, { - keyCode: _mobiledocKitUtilsKeycodes['default'].RIGHT, - shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT - }); - var keyup = createMockEvent('keyup', editor.element, { - keyCode: _mobiledocKitUtilsKeycodes['default'].RIGHT, - shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT - }); - _triggerEditorEvent(editor, keydown); - _triggerEditorEvent(editor, keyup); - } +QUnit.module('ESLint | tests/eslint/js/utils/assert.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/assert.js should pass ESLint\n\n'); +}); - function triggerLeftArrowKey(editor, modifier) { - assertEditor(editor); - var keydown = createMockEvent('keydown', editor.element, { - keyCode: _mobiledocKitUtilsKeycodes['default'].LEFT, - shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT - }); - var keyup = createMockEvent('keyup', editor.element, { - keyCode: _mobiledocKitUtilsKeycodes['default'].LEFT, - shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT - }); - _triggerEditorEvent(editor, keydown); - _triggerEditorEvent(editor, keyup); - } +QUnit.module('ESLint | tests/eslint/js/utils/browser.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/browser.js should pass ESLint\n\n'); +}); - // Allows our fake copy and paste events to communicate with each other. - var lastCopyData = {}; - function triggerCopyEvent(editor) { - var eventData = { - clipboardData: { - setData: function setData(type, value) { - lastCopyData[type] = value; - } - } - }; +QUnit.module('ESLint | tests/eslint/js/utils/characters.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/characters.js should pass ESLint\n\n'); +}); - var event = createMockEvent('copy', editor.element, eventData); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/utils/compiler.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/compiler.js should pass ESLint\n\n'); +}); - function triggerCutEvent(editor) { - var event = createMockEvent('cut', editor.element, { - clipboardData: { - setData: function setData(type, value) { - lastCopyData[type] = value; - } - } - }); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/utils/copy.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/copy.js should pass ESLint\n\n'); +}); - function triggerPasteEvent(editor) { - var eventData = { - clipboardData: { - getData: function getData(type) { - return lastCopyData[type]; - } - } - }; +QUnit.module('ESLint | tests/eslint/js/utils/cursor.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/cursor.js should pass ESLint\n\n'); +}); - var event = createMockEvent('paste', editor.element, eventData); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/utils/cursor/position.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/cursor/position.js should pass ESLint\n\n'); +}); - function triggerDropEvent(editor, _ref) { - var html = _ref.html; - var text = _ref.text; - var clientX = _ref.clientX; - var clientY = _ref.clientY; +QUnit.module('ESLint | tests/eslint/js/utils/cursor/range.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/cursor/range.js should pass ESLint\n\n'); +}); - if (!clientX || !clientY) { - throw new Error('Must pass clientX, clientY'); - } - var event = createMockEvent('drop', editor.element, { - clientX: clientX, - clientY: clientY, - dataTransfer: { - getData: function getData(mimeType) { - switch (mimeType) { - case _mobiledocKitUtilsParseUtils.MIME_TEXT_HTML: - return html; - case _mobiledocKitUtilsParseUtils.MIME_TEXT_PLAIN: - return text; - default: - throw new Error('invalid mime type ' + mimeType); - } - } - } - }); +QUnit.module('ESLint | tests/eslint/js/utils/deprecate.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/deprecate.js should pass ESLint\n\n'); +}); - _triggerEditorEvent(editor, event); - } +QUnit.module('ESLint | tests/eslint/js/utils/dom-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/dom-utils.js should pass ESLint\n\n'); +}); - function getCopyData(type) { - return lastCopyData[type]; - } +QUnit.module('ESLint | tests/eslint/js/utils/element-map.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/element-map.js should pass ESLint\n\n'); +}); - function setCopyData(type, value) { - lastCopyData[type] = value; - } +QUnit.module('ESLint | tests/eslint/js/utils/element-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/element-utils.js should pass ESLint\n\n'); +}); - function clearCopyData() { - Object.keys(lastCopyData).forEach(function (key) { - delete lastCopyData[key]; - }); - } +QUnit.module('ESLint | tests/eslint/js/utils/environment.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/environment.js should pass ESLint\n\n'); +}); - function fromHTML(html) { - html = $.trim(html); - var div = document.createElement('div'); - div.innerHTML = html; - return div; - } +QUnit.module('ESLint | tests/eslint/js/utils/fixed-queue.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/fixed-queue.js should pass ESLint\n\n'); +}); - /** - * Tests fail in IE when using `element.blur`, so remove focus by refocusing - * on another item instead of blurring the editor element - */ - function blur() { - var input = $(''); - input.appendTo('#qunit-fixture'); - input.focus(); - } +QUnit.module('ESLint | tests/eslint/js/utils/key.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/key.js should pass ESLint\n\n'); +}); - var DOMHelper = { - moveCursorTo: moveCursorTo, - moveCursorWithoutNotifyingEditorTo: moveCursorWithoutNotifyingEditorTo, - selectRange: selectRange, - selectText: selectText, - clearSelection: _mobiledocKitUtilsSelectionUtils.clearSelection, - triggerEvent: triggerEvent, - build: build, - fromHTML: fromHTML, - KEY_CODES: _mobiledocKitUtilsKeycodes['default'], - getCursorPosition: getCursorPosition, - getSelectedText: getSelectedText, - triggerDelete: triggerDelete, - triggerForwardDelete: triggerForwardDelete, - triggerEnter: triggerEnter, - insertText: insertText, - triggerKeyEvent: triggerKeyEvent, - triggerKeyCommand: triggerKeyCommand, - triggerRightArrowKey: triggerRightArrowKey, - triggerLeftArrowKey: triggerLeftArrowKey, - triggerCopyEvent: triggerCopyEvent, - triggerCutEvent: triggerCutEvent, - triggerPasteEvent: triggerPasteEvent, - triggerDropEvent: triggerDropEvent, - getCopyData: getCopyData, - setCopyData: setCopyData, - clearCopyData: clearCopyData, - createMockEvent: createMockEvent, - findTextNode: findTextNode, - blur: blur - }; +QUnit.module('ESLint | tests/eslint/js/utils/keycodes.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/keycodes.js should pass ESLint\n\n'); +}); - exports.triggerEvent = triggerEvent; - exports['default'] = DOMHelper; +QUnit.module('ESLint | tests/eslint/js/utils/keys.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/keys.js should pass ESLint\n\n'); }); -define('tests/helpers/editor', ['exports', './post-abstract', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/renderers/mobiledoc/0-3-1'], function (exports, _postAbstract, _mobiledocKitEditorEditor, _mobiledocKitRenderersMobiledoc031) { - 'use strict'; - function retargetPosition(position, toPost) { - var fromPost = position.section.post; - var sectionIndex = undefined; - var retargetedPosition = undefined; - fromPost.walkAllLeafSections(function (section, index) { - if (sectionIndex !== undefined) { - return; - } - if (section === position.section) { - sectionIndex = index; - } - }); - if (sectionIndex === undefined) { - throw new Error('`retargetPosition` could not find section index'); - } - toPost.walkAllLeafSections(function (section, index) { - if (retargetedPosition) { - return; - } - if (index === sectionIndex) { - retargetedPosition = section.toPosition(position.offset); - } - }); - if (!retargetedPosition) { - throw new Error('`retargetPosition` could not find target section'); - } - return retargetedPosition; - } +QUnit.module('ESLint | tests/eslint/js/utils/linked-item.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/linked-item.js should pass ESLint\n\n'); +}); - function retargetRange(range, toPost) { - var newHead = retargetPosition(range.head, toPost); - var newTail = retargetPosition(range.tail, toPost); +QUnit.module('ESLint | tests/eslint/js/utils/linked-list.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/linked-list.js should pass ESLint\n\n'); +}); - return newHead.toRange(newTail); - } +QUnit.module('ESLint | tests/eslint/js/utils/log-manager.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/log-manager.js should pass ESLint\n\n'); +}); - function buildFromText(texts) { - var editorOptions = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; +QUnit.module('ESLint | tests/eslint/js/utils/markuperable.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/markuperable.js should pass ESLint\n\n'); +}); - var renderElement = editorOptions.element; - delete editorOptions.element; +QUnit.module('ESLint | tests/eslint/js/utils/merge.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/merge.js should pass ESLint\n\n'); +}); - var beforeRender = editorOptions.beforeRender || function () {}; - delete editorOptions.beforeRender; +QUnit.module('ESLint | tests/eslint/js/utils/mixin.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/mixin.js should pass ESLint\n\n'); +}); - var _PostAbstractHelpers$buildFromText = _postAbstract['default'].buildFromText(texts); +QUnit.module('ESLint | tests/eslint/js/utils/mobiledoc-error.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/mobiledoc-error.js should pass ESLint\n\n'); +}); - var post = _PostAbstractHelpers$buildFromText.post; - var range = _PostAbstractHelpers$buildFromText.range; +QUnit.module('ESLint | tests/eslint/js/utils/object-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/object-utils.js should pass ESLint\n\n'); +}); - var mobiledoc = _mobiledocKitRenderersMobiledoc031['default'].render(post); - editorOptions.mobiledoc = mobiledoc; - var editor = new _mobiledocKitEditorEditor['default'](editorOptions); - if (renderElement) { - beforeRender(editor); - editor.render(renderElement); - if (range) { - range = retargetRange(range, editor.post); - editor.selectRange(range); - } - } - return editor; - } +QUnit.module('ESLint | tests/eslint/js/utils/parse-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/parse-utils.js should pass ESLint\n\n'); +}); - exports.buildFromText = buildFromText; - exports.retargetRange = retargetRange; - exports.retargetPosition = retargetPosition; +QUnit.module('ESLint | tests/eslint/js/utils/placeholder-image-src.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/placeholder-image-src.js should pass ESLint\n\n'); }); -define('tests/helpers/mobiledoc', ['exports', './post-abstract', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/merge'], function (exports, _postAbstract, _mobiledocKitRenderersMobiledoc, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitEditorEditor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsMerge) { - 'use strict'; - /* - * usage: - * build(({post, section, marker, markup}) => - * post([ - * section('P', [ - * marker('some text', [markup('B')]) - * ]) - * }) - * ) - * @return Mobiledoc - */ - function build(treeFn, version) { - var post = _postAbstract['default'].build(treeFn); - switch (version) { - case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION: - return _mobiledocKitRenderersMobiledoc02['default'].render(post); - case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION: - return _mobiledocKitRenderersMobiledoc03['default'].render(post); - case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION: - return _mobiledocKitRenderersMobiledoc031['default'].render(post); - case undefined: - case null: - return _mobiledocKitRenderersMobiledoc['default'].render(post); - default: - throw new Error('Unknown version of mobiledoc renderer requested: ' + version); - } - } +QUnit.module('ESLint | tests/eslint/js/utils/selection-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/selection-utils.js should pass ESLint\n\n'); +}); - function renderPostInto(element, post) { - var editorOptions = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/utils/set.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/set.js should pass ESLint\n\n'); +}); - var mobiledoc = _mobiledocKitRenderersMobiledoc['default'].render(post); - (0, _mobiledocKitUtilsMerge.mergeWithOptions)(editorOptions, { mobiledoc: mobiledoc }); - var editor = new _mobiledocKitEditorEditor['default'](editorOptions); - editor.render(element); - return editor; - } +QUnit.module('ESLint | tests/eslint/js/utils/string-utils.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/string-utils.js should pass ESLint\n\n'); +}); - function renderInto(element, treeFn) { - var editorOptions = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/utils/to-range.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/utils/to-range.js should pass ESLint\n\n'); +}); - var mobiledoc = build(treeFn); - (0, _mobiledocKitUtilsMerge.mergeWithOptions)(editorOptions, { mobiledoc: mobiledoc }); - var editor = new _mobiledocKitEditorEditor['default'](editorOptions); - editor.render(element); - return editor; - } +QUnit.module('ESLint | tests/eslint/js/version.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/version.js should pass ESLint\n\n'); +}); - // In Firefox, if the window isn't active (which can happen when running tests - // at SauceLabs), the editor element won't have the selection. This helper method - // ensures that it has a cursor selection. - // See https://github.com/bustle/mobiledoc-kit/issues/388 - function renderIntoAndFocusTail(editorElement, treeFn) { - var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; +QUnit.module('ESLint | tests/eslint/js/views/tooltip.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/views/tooltip.js should pass ESLint\n\n'); +}); - var editor = renderInto(editorElement, treeFn, options); - editor.selectRange(new _mobiledocKitUtilsCursorRange['default'](editor.post.tailPosition())); - return editor; - } +QUnit.module('ESLint | tests/eslint/js/views/view.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/js/views/view.js should pass ESLint\n\n'); +}); - exports['default'] = { - build: build, - renderInto: renderInto, - renderPostInto: renderPostInto, - renderIntoAndFocusTail: renderIntoAndFocusTail - }; +QUnit.module('ESLint | tests/eslint/test-helpers.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/test-helpers.js should pass ESLint\n\n'); }); -define('tests/helpers/mock-editor', ['exports', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitEditorPost, _mobiledocKitUtilsCursorRange) { - 'use strict'; - var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); +QUnit.module('ESLint | tests/eslint/unit/editor/atom-lifecycle-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/atom-lifecycle-test.js should pass ESLint\n\n'); +}); - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } +QUnit.module('ESLint | tests/eslint/unit/editor/card-lifecycle-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/card-lifecycle-test.js should pass ESLint\n\n'); +}); - var MockEditor = (function () { - function MockEditor(builder) { - _classCallCheck(this, MockEditor); +QUnit.module('ESLint | tests/eslint/unit/editor/editor-events-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/editor-events-test.js should pass ESLint\n\n'); +}); - this.builder = builder; - this.range = _mobiledocKitUtilsCursorRange['default'].blankRange(); - } +QUnit.module('ESLint | tests/eslint/unit/editor/editor-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/editor-test.js should pass ESLint\n\n'); +}); - _createClass(MockEditor, [{ - key: 'run', - value: function run(callback) { - var postEditor = new _mobiledocKitEditorPost['default'](this); - postEditor.begin(); - var result = callback(postEditor); - postEditor.end(); - return result; - } - }, { - key: 'rerender', - value: function rerender() {} - }, { - key: '_postDidChange', - value: function _postDidChange() {} - }, { - key: 'selectRange', - value: function selectRange(range) { - this._renderedRange = range; - } - }, { - key: '_readRangeFromDOM', - value: function _readRangeFromDOM() {} - }]); +QUnit.module('ESLint | tests/eslint/unit/editor/key-commands-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/key-commands-test.js should pass ESLint\n\n'); +}); - return MockEditor; - })(); +QUnit.module('ESLint | tests/eslint/unit/editor/post-delete-at-position-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/post-delete-at-position-test.js should pass ESLint\n\n'); +}); - exports['default'] = MockEditor; +QUnit.module('ESLint | tests/eslint/unit/editor/post-delete-range-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/post-delete-range-test.js should pass ESLint\n\n'); }); -define('tests/helpers/module-load-failure', ['exports', 'ember-cli/test-loader'], function (exports, _emberCliTestLoader) { - 'use strict'; - /** - * Ensures that when the TestLoader failures to load a test module, the error - * is reported. Without this the rest of the full test suite still passes and there is an - * error printed in the console only. - * The technique is from: https://github.com/ember-cli/ember-cli-qunit/blob/master/vendor/ember-cli-qunit/test-loader.js#L55 - */ +QUnit.module('ESLint | tests/eslint/unit/editor/post-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/post-test.js should pass ESLint\n\n'); +}); - exports['default'] = function (QUnit) { - var moduleLoadFailures = []; +QUnit.module('ESLint | tests/eslint/unit/editor/post/insert-post-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/post/insert-post-test.js should pass ESLint\n\n'); +}); - _emberCliTestLoader['default'].prototype.moduleLoadFailure = function (moduleName, error) { - moduleLoadFailures.push(error); - QUnit.module('TestLoader Failures'); - QUnit.test(moduleName + ': could not be loaded', function () { - throw error; - }); - }; +QUnit.module('ESLint | tests/eslint/unit/editor/ui-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/editor/ui-test.js should pass ESLint\n\n'); +}); - QUnit.done(function () { - if (moduleLoadFailures.length) { - throw new Error('\n' + moduleLoadFailures.join('\n')); - } - }); - }; +QUnit.module('ESLint | tests/eslint/unit/models/atom-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/atom-test.js should pass ESLint\n\n'); }); -define('tests/helpers/post-abstract', ['exports', 'mobiledoc-kit/models/post-node-builder'], function (exports, _mobiledocKitModelsPostNodeBuilder) { - /* jshint latedef:nofunc */ - 'use strict'; - var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); +QUnit.module('ESLint | tests/eslint/unit/models/card-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/card-test.js should pass ESLint\n\n'); +}); - /* - * usage: - * Helpers.postAbstract.build(({post, section, marker, markup}) => - * post([ - * section('P', [ - * marker('some text', [markup('B')]) - * ]) - * }) - * ) - */ - function build(treeFn) { - var builder = new _mobiledocKitModelsPostNodeBuilder['default'](); +QUnit.module('ESLint | tests/eslint/unit/models/lifecycle-callbacks-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/lifecycle-callbacks-test.js should pass ESLint\n\n'); +}); - var simpleBuilder = { - post: function post() { - return builder.createPost.apply(builder, arguments); - }, - markupSection: function markupSection() { - return builder.createMarkupSection.apply(builder, arguments); - }, - markup: function markup() { - return builder.createMarkup.apply(builder, arguments); - }, - marker: function marker() { - return builder.createMarker.apply(builder, arguments); - }, - listSection: function listSection() { - return builder.createListSection.apply(builder, arguments); - }, - listItem: function listItem() { - return builder.createListItem.apply(builder, arguments); - }, - cardSection: function cardSection() { - return builder.createCardSection.apply(builder, arguments); - }, - imageSection: function imageSection() { - return builder.createImageSection.apply(builder, arguments); - }, - atom: function atom() { - return builder.createAtom.apply(builder, arguments); - } - }; +QUnit.module('ESLint | tests/eslint/unit/models/list-section-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/list-section-test.js should pass ESLint\n\n'); +}); - return treeFn(simpleBuilder); - } +QUnit.module('ESLint | tests/eslint/unit/models/marker-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/marker-test.js should pass ESLint\n\n'); +}); - var cardRegex = /\[(.*)\]/; - var markupRegex = /\*/g; - var listStartRegex = /^\* /; - var cursorRegex = /<|>|\|/g; +QUnit.module('ESLint | tests/eslint/unit/models/markup-section-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/markup-section-test.js should pass ESLint\n\n'); +}); - function parsePositionOffsets(text) { - var offsets = {}; +QUnit.module('ESLint | tests/eslint/unit/models/post-node-builder-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/post-node-builder-test.js should pass ESLint\n\n'); +}); - if (cardRegex.test(text)) { - [['|', 'solo'], ['<', 'start'], ['>', 'end']].forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2); +QUnit.module('ESLint | tests/eslint/unit/models/post-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/models/post-test.js should pass ESLint\n\n'); +}); - var char = _ref2[0]; - var type = _ref2[1]; +QUnit.module('ESLint | tests/eslint/unit/parsers/dom-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/dom-test.js should pass ESLint\n\n'); +}); - if (text.indexOf(char) !== -1) { - offsets[type] = text.indexOf(char) === 0 ? 0 : 1; - } - }); - } else { - if (listStartRegex.test(text)) { - text = text.replace(listStartRegex, ''); - } - text = text.replace(markupRegex, ''); - if (text.indexOf('|') !== -1) { - offsets.solo = text.indexOf('|'); - } else if (text.indexOf('<') !== -1 || text.indexOf('>') !== -1) { - var hasStart = text.indexOf('<') !== -1; - var hasEnd = text.indexOf('>') !== -1; - if (hasStart) { - offsets.start = text.indexOf('<'); - text = text.replace(/'); - } - } - } - - return offsets; - } +QUnit.module('ESLint | tests/eslint/unit/parsers/html-google-docs-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/html-google-docs-test.js should pass ESLint\n\n'); +}); - var DEFAULT_ATOM_NAME = 'some-atom'; - var DEFAULT_ATOM_VALUE = '@atom'; +QUnit.module('ESLint | tests/eslint/unit/parsers/html-google-sheets-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/html-google-sheets-test.js should pass ESLint\n\n'); +}); - var MARKUP_CHARS = { - '*': 'b', - '_': 'em' - }; +QUnit.module('ESLint | tests/eslint/unit/parsers/html-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/html-test.js should pass ESLint\n\n'); +}); - function parseTextIntoAtom(text, builder) { - var markers = []; - var atomIndex = text.indexOf('@'); - var afterAtomIndex = atomIndex + 1; - var atomName = DEFAULT_ATOM_NAME, - atomValue = DEFAULT_ATOM_VALUE, - atomPayload = {}; +QUnit.module('ESLint | tests/eslint/unit/parsers/mobiledoc-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/mobiledoc-test.js should pass ESLint\n\n'); +}); - // If "@" is followed by "( ... json ... )", parse the json data - if (text[atomIndex + 1] === "(") { - var jsonStartIndex = atomIndex + 1; - var jsonEndIndex = text.indexOf(")", jsonStartIndex); - afterAtomIndex = jsonEndIndex + 1; - if (jsonEndIndex === -1) { - throw new Error('Atom JSON data had unmatched "(": ' + text); - } - var jsonString = text.slice(jsonStartIndex + 1, jsonEndIndex); - jsonString = "{" + jsonString + "}"; - try { - var json = JSON.parse(jsonString); - if (json.name) { - atomName = json.name; - } - if (json.value) { - atomValue = json.value; - } - if (json.payload) { - atomPayload = json.payload; - } - } catch (e) { - throw new Error('Failed to parse atom JSON data string: ' + jsonString + ', ' + e); - } - } +QUnit.module('ESLint | tests/eslint/unit/parsers/mobiledoc/0-2-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/mobiledoc/0-2-test.js should pass ESLint\n\n'); +}); - // create the atom - var atom = builder.atom(atomName, atomValue, atomPayload); +QUnit.module('ESLint | tests/eslint/unit/parsers/mobiledoc/0-3-2-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/mobiledoc/0-3-2-test.js should pass ESLint\n\n'); +}); - // recursively parse the remaining text pieces - var pieces = [text.slice(0, atomIndex), atom, text.slice(afterAtomIndex)]; +QUnit.module('ESLint | tests/eslint/unit/parsers/mobiledoc/0-3-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/mobiledoc/0-3-test.js should pass ESLint\n\n'); +}); - // join the markers together - pieces.forEach(function (piece, index) { - if (index === 1) { - // atom - markers.push(piece); - } else if (piece.length) { - markers = markers.concat(parseTextIntoMarkers(piece, builder)); - } - }); +QUnit.module('ESLint | tests/eslint/unit/parsers/section-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/section-test.js should pass ESLint\n\n'); +}); - return markers; - } +QUnit.module('ESLint | tests/eslint/unit/parsers/text-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/parsers/text-test.js should pass ESLint\n\n'); +}); - function parseTextWithMarkup(text, builder) { - var markers = []; - var markup = undefined, - char = undefined; - Object.keys(MARKUP_CHARS).forEach(function (key) { - if (markup) { - return; - } - if (text.indexOf(key) !== -1) { - markup = builder.markup(MARKUP_CHARS[key]); - char = key; - } - }); - if (!markup) { - throw new Error('Failed to find markup in text: ' + text); - } +QUnit.module('ESLint | tests/eslint/unit/renderers/editor-dom-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/renderers/editor-dom-test.js should pass ESLint\n\n'); +}); - var startIndex = text.indexOf(char); - var endIndex = text.indexOf(char, startIndex + 1); - if (endIndex === -1) { - throw new Error('Malformed text: char ' + char + ' do not match'); - } +QUnit.module('ESLint | tests/eslint/unit/renderers/mobiledoc-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/renderers/mobiledoc-test.js should pass ESLint\n\n'); +}); - var pieces = [text.slice(0, startIndex), text.slice(startIndex + 1, endIndex), text.slice(endIndex + 1)]; - pieces.forEach(function (piece, index) { - if (index === 1) { - // marked-up text - markers.push(builder.marker(piece, [markup])); - } else { - markers = markers.concat(parseTextIntoMarkers(piece, builder)); - } - }); +QUnit.module('ESLint | tests/eslint/unit/renderers/mobiledoc/0-2-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/renderers/mobiledoc/0-2-test.js should pass ESLint\n\n'); +}); - return markers; - } +QUnit.module('ESLint | tests/eslint/unit/renderers/mobiledoc/0-3-2-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/renderers/mobiledoc/0-3-2-test.js should pass ESLint\n\n'); +}); - function parseTextIntoMarkers(text, builder) { - text = text.replace(cursorRegex, ''); - var markers = []; +QUnit.module('ESLint | tests/eslint/unit/renderers/mobiledoc/0-3-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/renderers/mobiledoc/0-3-test.js should pass ESLint\n\n'); +}); - var hasAtom = text.indexOf('@') !== -1; - var hasMarkup = false; - Object.keys(MARKUP_CHARS).forEach(function (key) { - if (text.indexOf(key) !== -1) { - hasMarkup = true; - } - }); +QUnit.module('ESLint | tests/eslint/unit/utils/array-utils-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/array-utils-test.js should pass ESLint\n\n'); +}); - if (hasAtom) { - markers = markers.concat(parseTextIntoAtom(text, builder)); - } else if (hasMarkup) { - markers = markers.concat(parseTextWithMarkup(text, builder)); - } else if (text.length) { - markers.push(builder.marker(text)); - } +QUnit.module('ESLint | tests/eslint/unit/utils/assert-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/assert-test.js should pass ESLint\n\n'); +}); - return markers; - } +QUnit.module('ESLint | tests/eslint/unit/utils/copy-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/copy-test.js should pass ESLint\n\n'); +}); - function parseSingleText(text, builder) { - var section = undefined, - positions = {}; +QUnit.module('ESLint | tests/eslint/unit/utils/cursor-position-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/cursor-position-test.js should pass ESLint\n\n'); +}); - var offsets = parsePositionOffsets(text); +QUnit.module('ESLint | tests/eslint/unit/utils/cursor-range-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/cursor-range-test.js should pass ESLint\n\n'); +}); - if (cardRegex.test(text)) { - section = builder.cardSection(cardRegex.exec(text)[1]); - } else { - var type = 'p'; - if (listStartRegex.test(text)) { - text = text.replace(listStartRegex, ''); - type = 'ul'; - } +QUnit.module('ESLint | tests/eslint/unit/utils/fixed-queue-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/fixed-queue-test.js should pass ESLint\n\n'); +}); - var markers = parseTextIntoMarkers(text, builder); +QUnit.module('ESLint | tests/eslint/unit/utils/key-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/key-test.js should pass ESLint\n\n'); +}); - switch (type) { - case 'p': - section = builder.markupSection('p', markers); - break; - case 'ul': - section = builder.listItem(markers); - break; - } - } +QUnit.module('ESLint | tests/eslint/unit/utils/linked-list-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/linked-list-test.js should pass ESLint\n\n'); +}); - ['start', 'end', 'solo'].forEach(function (type) { - if (offsets[type] !== undefined) { - positions[type] = section.toPosition(offsets[type]); - } - }); +QUnit.module('ESLint | tests/eslint/unit/utils/object-utils-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/object-utils-test.js should pass ESLint\n\n'); +}); - return { section: section, positions: positions }; - } +QUnit.module('ESLint | tests/eslint/unit/utils/parse-utils-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/parse-utils-test.js should pass ESLint\n\n'); +}); - /** - * Shorthand to create a mobiledoc simply. - * Pass a string or an array of strings. - * - * Returns { post, range }, a post built from the mobiledoc and a range. - * - * Use "|" to indicate the cursor position or "<" and ">" to indicate a range. - * Use "[card-name]" to indicate a card - * Use asterisks to indicate bold text: "abc *bold* def" - * Use "@" to indicate an atom, default values for name,value,payload are DEFAULT_ATOM_NAME,DEFAULT_ATOM_VALUE,{} - * Use "@(name, value, payload)" to specify name,value and/or payload for an atom. The string from `(` to `)` is parsed as - * JSON, e.g.: '@("name": "my-atom", "value": "abc", "payload": {"foo": "bar"})' -> atom named "my-atom" with value 'abc', payload {foo: 'bar'} - * Use "* " at the start of the string to indicate a list item ("ul") - * - * Examples: - * buildFromText("abc") -> { post } with 1 markup section ("p") with text "abc" - * buildFromText(["abc","def"]) -> { post } with 2 markups sections ("p") with texts "abc" and "def" - * buildFromText("abc|def") -> { post, range } where range is collapsed at offset 3 (after the "c") - * buildFromText(["abcdef","[some-card]","def"]) -> { post } with [MarkupSection, Card, MarkupSection] sections - * buildFromText(["* item 1", "* item 2"]) -> { post } with a ListSection with 2 ListItems - * buildFromText([""]) -> { post, range } where range is the entire post (before the "a" to after the "i") - */ - function buildFromText(texts) { - if (!Array.isArray(texts)) { - texts = [texts]; - } - var positions = {}; +QUnit.module('ESLint | tests/eslint/unit/utils/selection-utils-test.js'); +QUnit.test('should pass ESLint', function(assert) { + assert.expect(1); + assert.ok(true, 'tests/eslint/unit/utils/selection-utils-test.js should pass ESLint\n\n'); +}); - var post = build(function (builder) { - var sections = []; - var curList = undefined; - texts.forEach(function (text, index) { - var _parseSingleText = parseSingleText(text, builder); +define('tests/fixtures/google-docs', ['exports'], function (exports) { + 'use strict'; - var section = _parseSingleText.section; - var _positions = _parseSingleText.positions; + exports['default'] = { + 'simple paragraph as span': { + expected: "

    simple paragraph

    ", + raw: 'simple paragraph' + }, + 'simple paragraph as span (Chrome - Windows)': { + expected: "

    simple paragraph

    ", + raw: 'simple paragraph' + }, - var lastText = index === texts.length - 1; + // when selecting a line without including the end of the line, the html represention + // includes a or series of s + 'paragraph with bold as span': { + expected: "

    paragraph with bold

    ", + raw: 'paragraph with bold' + }, + 'paragraph with bold as span (Chrome - Windows)': { + expected: "

    paragraph with bold

    ", + raw: 'paragraph with bold' + }, - if (curList) { - if (section.isListItem) { - curList.items.append(section); - } else { - sections.push(curList); - sections.push(section); - curList = null; - } - } else if (section.isListItem) { - curList = builder.listSection('ul', [section]); - } else { - sections.push(section); - } + // when selecting a line that includes the end (using, e.g., shift+up to selection the entire line), + // the html representation includes a

    tag + 'paragraph with bold as p': { + expected: "

    A bold paragraph.

    ", + raw: '

    A bold paragraph.


    ' + }, + 'paragraph with italic as span': { + expected: "

    paragraph with italic

    ", + raw: 'paragraph with italic' + }, + 'paragraph with bold + italic as p': { + expected: "

    And a second bold italic paragraph.", + raw: '

    And a second bold italic paragraph.


    ' + }, + '2 paragraphs as p': { + expected: "

    Paragraph 1

    Paragraph 2

    ", + raw: '

    Paragraph 1


    Paragraph 2
    ' + }, + 'h1 with h1 tag': { + expected: "

    h1 text

    ", + raw: '

    h1 text

    ' + }, + 'paragraph with link as span': { + expected: "

    link to bustle

    ", + raw: 'link to bustle' + }, + 'paragraph with link as p': { + expected: "

    link to bustle

    ", + raw: '

    link to bustle


    ' + }, + 'img in span': { + expected: "

    ", + raw: '' + } + }; +}); +define('tests/helpers/assertions', ['exports', './dom', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/models/types'], function (exports, _dom, _mobiledocKitRenderersMobiledoc, _mobiledocKitModelsTypes) { + /* global QUnit, $ */ - if (lastText && curList) { - sections.push(curList); - } + 'use strict'; - if (_positions.start) { - positions.start = _positions.start; + exports['default'] = registerAssertions; + + function compareMarkers(actual, expected, assert, path, deepCompare) { + if (actual.value !== expected.value) { + assert.equal(actual.value, expected.value, 'wrong value at ' + path); + } + if (actual.markups.length !== expected.markups.length) { + assert.equal(actual.markups.length, expected.markups.length, 'wrong markups at ' + path); + } + if (deepCompare) { + actual.markups.forEach(function (markup, index) { + comparePostNode(markup, expected.markups[index], assert, path + ':' + index, deepCompare); + }); + } + } + + /* eslint-disable complexity */ + function comparePostNode(actual, expected, assert) { + var path = arguments.length <= 3 || arguments[3] === undefined ? 'root' : arguments[3]; + var deepCompare = arguments.length <= 4 || arguments[4] === undefined ? false : arguments[4]; + + if (!actual || !expected) { + assert.ok(!!actual, 'missing actual post node at ' + path); + assert.ok(!!expected, 'missing expected post node at ' + path); + return; + } + if (actual.type !== expected.type) { + assert.pushResult({ + result: false, + actual: actual.type, + expected: expected.type, + message: 'wrong type at ' + path + }); + } + + switch (actual.type) { + case _mobiledocKitModelsTypes.POST_TYPE: + if (actual.sections.length !== expected.sections.length) { + assert.equal(actual.sections.length, expected.sections.length, 'wrong sections for post'); } - if (_positions.end) { - positions.end = _positions.end; + if (deepCompare) { + actual.sections.forEach(function (section, index) { + comparePostNode(section, expected.sections.objectAt(index), assert, path + ':' + index, deepCompare); + }); } - if (_positions.solo) { - positions.solo = _positions.solo; + break; + case _mobiledocKitModelsTypes.ATOM_TYPE: + if (actual.name !== expected.name) { + assert.equal(actual.name, expected.name, 'wrong atom name at ' + path); + } + compareMarkers(actual, expected, assert, path, deepCompare); + break; + case _mobiledocKitModelsTypes.MARKER_TYPE: + compareMarkers(actual, expected, assert, path, deepCompare); + break; + case _mobiledocKitModelsTypes.MARKUP_SECTION_TYPE: + case _mobiledocKitModelsTypes.LIST_ITEM_TYPE: + if (actual.tagName !== expected.tagName) { + assert.equal(actual.tagName, expected.tagName, 'wrong tagName at ' + path); + } + if (actual.markers.length !== expected.markers.length) { + assert.equal(actual.markers.length, expected.markers.length, 'wrong markers at ' + path); + } + if (deepCompare) { + actual.markers.forEach(function (marker, index) { + comparePostNode(marker, expected.markers.objectAt(index), assert, path + ':' + index, deepCompare); + }); + } + break; + case _mobiledocKitModelsTypes.CARD_TYPE: + if (actual.name !== expected.name) { + assert.equal(actual.name, expected.name, 'wrong card name at ' + path); } + if (!QUnit.equiv(actual.payload, expected.payload)) { + assert.deepEqual(actual.payload, expected.payload, 'wrong card payload at ' + path); + } + break; + case _mobiledocKitModelsTypes.LIST_SECTION_TYPE: + if (actual.items.length !== expected.items.length) { + assert.equal(actual.items.length, expected.items.length, 'wrong items at ' + path); + } + if (deepCompare) { + actual.items.forEach(function (item, index) { + comparePostNode(item, expected.items.objectAt(index), assert, path + ':' + index, deepCompare); + }); + } + break; + case _mobiledocKitModelsTypes.IMAGE_SECTION_TYPE: + if (actual.src !== expected.src) { + assert.equal(actual.src, expected.src, 'wrong image src at ' + path); + } + break; + case _mobiledocKitModelsTypes.MARKUP_TYPE: + if (actual.tagName !== expected.tagName) { + assert.equal(actual.tagName, expected.tagName, 'wrong tagName at ' + path); + } + if (!QUnit.equiv(actual.attributes, expected.attributes)) { + assert.deepEqual(actual.attributes, expected.attributes, 'wrong attributes at ' + path); + } + break; + default: + throw new Error('wrong type :' + actual.type); + } + } + /* eslint-enable complexity */ + + function registerAssertions(QUnit) { + QUnit.assert.isBlank = function (val) { + var message = arguments.length <= 1 || arguments[1] === undefined ? 'value is blank' : arguments[1]; + + this.pushResult({ + result: val === null || val === undefined || val === '' || val === false, + actual: val + ' (typeof ' + typeof val + ')', + expected: 'null|undefined|\'\'|false', + message: message }); + }; - return builder.post(sections); - }); + QUnit.assert.hasElement = function (selector) { + var message = arguments.length <= 1 || arguments[1] === undefined ? 'hasElement "' + selector + '"' : arguments[1]; + return (function () { + var found = $(selector); + this.pushResult({ + result: found.length > 0, + actual: found.length + ' matches for \'' + selector + '\'', + expected: '>0 matches for \'' + selector + '\'', + message: message + }); + return found; + }).apply(this, arguments); + }; - var range = undefined; - if (positions.start) { - if (!positions.end) { - throw new Error('startPos but no endPos ' + texts.join('\n')); + QUnit.assert.hasNoElement = function (selector) { + var message = arguments.length <= 1 || arguments[1] === undefined ? 'hasNoElement "' + selector + '"' : arguments[1]; + return (function () { + var found = $(selector); + this.pushResult({ + result: found.length === 0, + actual: found.length + ' matches for \'' + selector + '\'', + expected: '0 matches for \'' + selector + '\'', + message: message + }); + return found; + }).apply(this, arguments); + }; + + QUnit.assert.hasClass = function (element, className) { + var message = arguments.length <= 2 || arguments[2] === undefined ? 'element has class "' + className + '"' : arguments[2]; + return (function () { + this.pushResult({ + result: element.classList.contains(className), + actual: element.classList, + expected: className, + message: message + }); + }).apply(this, arguments); + }; + + QUnit.assert.notHasClass = function (element, className) { + var message = arguments.length <= 2 || arguments[2] === undefined ? 'element has class "' + className + '"' : arguments[2]; + return (function () { + this.pushResult({ + result: !element.classList.contains(className), + actual: element.classList, + expected: className, + message: message + }); + }).apply(this, arguments); + }; + + QUnit.assert.selectedText = function (text) { + var message = arguments.length <= 1 || arguments[1] === undefined ? 'selectedText "' + text + '"' : arguments[1]; + return (function () { + var selected = _dom['default'].getSelectedText(); + this.pushResult({ + result: selected === text, + actual: selected, + expected: text, + message: message + }); + }).apply(this, arguments); + }; + + QUnit.assert.inArray = function (element, array) { + var message = arguments.length <= 2 || arguments[2] === undefined ? 'has "' + element + '" in "' + array + '"' : arguments[2]; + return (function () { + QUnit.assert.ok(array.indexOf(element) !== -1, message); + })(); + }; + + QUnit.assert.postIsSimilar = function (post, expected) { + var postName = arguments.length <= 2 || arguments[2] === undefined ? 'post' : arguments[2]; + + comparePostNode(post, expected, this, postName, true); + var mobiledoc = _mobiledocKitRenderersMobiledoc['default'].render(post), + expectedMobiledoc = _mobiledocKitRenderersMobiledoc['default'].render(expected); + this.deepEqual(mobiledoc, expectedMobiledoc, postName + ' is similar to expected'); + }; + + QUnit.assert.renderTreeIsEqual = function (renderTree, expectedPost) { + var _this = this; + + if (renderTree.rootNode.isDirty) { + this.ok(false, 'renderTree is dirty'); + return; } - range = positions.start.toRange(positions.end); - } else if (positions.solo) { - range = positions.solo.toRange(); - } - return { post: post, range: range }; - } + expectedPost.sections.forEach(function (section, index) { + var renderNode = renderTree.rootNode.childNodes.objectAt(index); + var path = 'post:' + index; - exports['default'] = { - build: build, - buildFromText: buildFromText, - DEFAULT_ATOM_NAME: DEFAULT_ATOM_NAME - }; -}); -define('tests/helpers/post-editor-run', ['exports', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/post', './mock-editor', './render-built-abstract'], function (exports, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorPost, _mockEditor, _renderBuiltAbstract) { - 'use strict'; + var compareChildren = function compareChildren(parentPostNode, parentRenderNode, path) { + var children = parentPostNode.markers || parentPostNode.items || []; - exports['default'] = run; + if (children.length !== parentRenderNode.childNodes.length) { + _this.equal(parentRenderNode.childNodes.length, children.length, 'wrong child render nodes at ' + path); + return; + } - function run(post, callback) { - var builder = new _mobiledocKitModelsPostNodeBuilder['default'](); - var editor = new _mockEditor['default'](builder); + children.forEach(function (child, index) { + var renderNode = parentRenderNode.childNodes.objectAt(index); - (0, _renderBuiltAbstract['default'])(post, editor); + comparePostNode(child, renderNode && renderNode.postNode, _this, path + ':' + index, false); + compareChildren(child, renderNode, path + ':' + index); + }); + }; - var postEditor = new _mobiledocKitEditorPost['default'](editor); - postEditor.begin(); - var result = callback(postEditor); - postEditor.complete(); - return result; - } -}); -define('tests/helpers/render-built-abstract', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree) { - 'use strict'; + comparePostNode(section, renderNode.postNode, _this, path, false); + compareChildren(section, renderNode, path); + }); - exports['default'] = renderBuiltAbstract; + this.ok(true, 'renderNode is similar'); + }; - function renderBuiltAbstract(post, editor) { - editor.post = post; - var unknownCardHandler = function unknownCardHandler() {}; - var unknownAtomHandler = function unknownAtomHandler() {}; - var renderer = new _mobiledocKitRenderersEditorDom['default'](editor, [], [], unknownCardHandler, unknownAtomHandler); - var renderTree = new _mobiledocKitModelsRenderTree['default'](post); - renderer.render(renderTree); - return editor; - } -}); -define("tests/helpers/wait", ["exports"], function (exports) { - "use strict"; + QUnit.assert.positionIsEqual = function (position, expected) { + var message = arguments.length <= 2 || arguments[2] === undefined ? 'position is equal' : arguments[2]; - var wait = function wait(callback) { - window.requestAnimationFrame(callback); - }; + if (position.section !== expected.section) { + this.pushResult({ + result: false, + actual: position.section.type + ':' + position.section.tagName, + expected: expected.section.type + ':' + expected.section.tagName, + message: 'incorrect position section (' + message + ')' + }); + } else if (position.offset !== expected.offset) { + this.pushResult({ + result: false, + actual: position.offset, + expected: expected.offset, + message: 'incorrect position offset (' + message + ')' + }); + } else { + this.pushResult({ + result: true, + actual: position, + expected: expected, + message: message + }); + } + }; - exports["default"] = wait; -}); -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/basic-editor-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/basic-editor-test.js should pass jshint.'); -}); + QUnit.assert.rangeIsEqual = function (range, expected) { + var message = arguments.length <= 2 || arguments[2] === undefined ? 'range is equal' : arguments[2]; + var head = range.head; + var tail = range.tail; + var isCollapsed = range.isCollapsed; + var direction = range.direction; + var expectedHead = expected.head; + var expectedTail = expected.tail; + var expectedIsCollapsed = expected.isCollapsed; + var expectedDirection = expected.direction; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/cursor-movement-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/cursor-movement-test.js should pass jshint.'); -}); + var failed = false; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/cursor-position-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/cursor-position-test.js should pass jshint.'); -}); + if (!head.isEqual(expectedHead)) { + failed = true; + this.pushResult({ + result: false, + actual: head.section.type + ':' + head.section.tagName, + expected: expectedHead.section.type + ':' + expectedHead.section.tagName, + message: 'incorrect head position' + }); + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-atoms-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-atoms-test.js should pass jshint.'); -}); + if (!tail.isEqual(expectedTail)) { + failed = true; + this.pushResult({ + result: false, + actual: tail.section.type + ':' + tail.section.tagName, + expected: expectedTail.section.type + ':' + expectedTail.section.tagName, + message: 'incorrect tail position' + }); + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-cards-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-cards-test.js should pass jshint.'); -}); + if (isCollapsed !== expectedIsCollapsed) { + failed = true; + this.pushResult({ + result: false, + actual: isCollapsed, + expected: expectedIsCollapsed, + message: 'wrong value for isCollapsed' + }); + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-copy-paste-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-copy-paste-test.js should pass jshint.'); -}); + if (direction !== expectedDirection) { + failed = true; + this.pushResult({ + result: false, + actual: direction, + expected: expectedDirection, + message: 'wrong value for direction' + }); + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-drag-drop-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-drag-drop-test.js should pass jshint.'); + if (!failed) { + this.pushResult({ + result: true, + actual: range, + expected: expected, + message: message + }); + } + }; + } }); +define("tests/helpers/browsers", ["exports"], function (exports) { + "use strict"; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-input-handlers-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-input-handlers-test.js should pass jshint.'); -}); + exports.detectIE = detectIE; + exports.detectIE11 = detectIE11; + exports.supportsSelectionExtend = supportsSelectionExtend; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-key-commands-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-key-commands-test.js should pass jshint.'); -}); + function detectIE() { + var userAgent = navigator.userAgent; + return userAgent.indexOf("MSIE ") !== -1 || userAgent.indexOf("Trident/") !== -1 || userAgent.indexOf('Edge/') !== -1; + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-list-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-list-test.js should pass jshint.'); -}); + function detectIE11() { + return detectIE() && navigator.userAgent.indexOf("rv:11.0") !== -1; + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-post-editor-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-post-editor-test.js should pass jshint.'); + function supportsSelectionExtend() { + var selection = window.getSelection(); + return !!selection.extend; + } }); +define('tests/helpers/dom', ['exports', 'mobiledoc-kit/utils/selection-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/keycodes', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit', 'mobiledoc-kit/utils/parse-utils', 'mobiledoc-kit/utils/string-utils'], function (exports, _mobiledocKitUtilsSelectionUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsKeycodes, _mobiledocKitUtilsKey, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsMerge, _mobiledocKit, _mobiledocKitUtilsParseUtils, _mobiledocKitUtilsStringUtils) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-reparse-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-reparse-test.js should pass jshint.'); -}); + function assertEditor(editor) { + if (!(editor instanceof _mobiledocKit.Editor)) { + throw new Error('Must pass editor as first argument'); + } + } -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-sections-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-sections-test.js should pass jshint.'); -}); + // walks DOWN the dom from node to childNodes, returning the element + // for which `conditionFn(element)` is true + function walkDOMUntil(topNode) { + var conditionFn = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1]; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-selections-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-selections-test.js should pass jshint.'); -}); + if (!topNode) { + throw new Error('Cannot call walkDOMUntil without a node'); + } + var stack = [topNode]; + var currentElement = undefined; -QUnit.module('JSHint - tests/jshint/acceptance'); -QUnit.test('tests/jshint/acceptance/editor-undo-redo-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/acceptance/editor-undo-redo-test.js should pass jshint.'); -}); + while (stack.length) { + currentElement = stack.pop(); + + if (conditionFn(currentElement)) { + return currentElement; + } -QUnit.module('JSHint - tests/jshint/fixtures'); -QUnit.test('tests/jshint/fixtures/google-docs.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/fixtures/google-docs.js should pass jshint.'); -}); + (0, _mobiledocKitUtilsArrayUtils.forEach)(currentElement.childNodes, function (el) { + return stack.push(el); + }); + } + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/assertions.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/assertions.js should pass jshint.'); -}); + function findTextNode(parentElement, text) { + return walkDOMUntil(parentElement, function (node) { + return (0, _mobiledocKitUtilsDomUtils.isTextNode)(node) && node.textContent.indexOf(text) !== -1; + }); + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/browsers.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/browsers.js should pass jshint.'); -}); + function selectRange(startNode, startOffset, endNode, endOffset) { + (0, _mobiledocKitUtilsSelectionUtils.clearSelection)(); -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/dom.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/dom.js should pass jshint.'); -}); + var range = document.createRange(); + range.setStart(startNode, startOffset); + range.setEnd(endNode, endOffset); -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/editor.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/editor.js should pass jshint.'); -}); + var selection = window.getSelection(); + selection.addRange(range); + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/mobiledoc.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/mobiledoc.js should pass jshint.'); -}); + function selectText(editor, startText) { + var startContainingElement = arguments.length <= 2 || arguments[2] === undefined ? editor.element : arguments[2]; + var endText = arguments.length <= 3 || arguments[3] === undefined ? startText : arguments[3]; + var endContainingElement = arguments.length <= 4 || arguments[4] === undefined ? startContainingElement : arguments[4]; + return (function () { -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/mock-editor.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/mock-editor.js should pass jshint.'); -}); + assertEditor(editor); + var startTextNode = findTextNode(startContainingElement, startText); + var endTextNode = findTextNode(endContainingElement, endText); -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/module-load-failure.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/module-load-failure.js should pass jshint.'); -}); + if (!startTextNode) { + throw new Error('Could not find a starting textNode containing "' + startText + '"'); + } + if (!endTextNode) { + throw new Error('Could not find an ending textNode containing "' + endText + '"'); + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/post-abstract.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/post-abstract.js should pass jshint.'); -}); + var startOffset = startTextNode.textContent.indexOf(startText), + endOffset = endTextNode.textContent.indexOf(endText) + endText.length; + selectRange(startTextNode, startOffset, endTextNode, endOffset); + editor._readRangeFromDOM(); + })(); + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/post-editor-run.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/post-editor-run.js should pass jshint.'); -}); + function moveCursorWithoutNotifyingEditorTo(editor, node) { + var offset = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2]; + var endNode = arguments.length <= 3 || arguments[3] === undefined ? node : arguments[3]; + var endOffset = arguments.length <= 4 || arguments[4] === undefined ? offset : arguments[4]; + return (function () { + selectRange(node, offset, endNode, endOffset); + })(); + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/render-built-abstract.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/render-built-abstract.js should pass jshint.'); -}); + function moveCursorTo(editor, node) { + var offset = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2]; + var endNode = arguments.length <= 3 || arguments[3] === undefined ? node : arguments[3]; + var endOffset = arguments.length <= 4 || arguments[4] === undefined ? offset : arguments[4]; + return (function () { + assertEditor(editor); + if (!node) { + throw new Error('Cannot moveCursorTo node without node'); + } + moveCursorWithoutNotifyingEditorTo(editor, node, offset, endNode, endOffset); + editor._readRangeFromDOM(); + })(); + } -QUnit.module('JSHint - tests/jshint/helpers'); -QUnit.test('tests/jshint/helpers/wait.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/helpers/wait.js should pass jshint.'); -}); + function triggerEvent(node, eventType) { + if (!node) { + throw new Error('Attempted to trigger event "' + eventType + '" on undefined node'); + } -QUnit.module('JSHint - tests/jshint/js/cards'); -QUnit.test('tests/jshint/js/cards/image.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/cards/image.js should pass jshint.'); -}); + var clickEvent = document.createEvent('MouseEvents'); + clickEvent.initEvent(eventType, true, true); + return node.dispatchEvent(clickEvent); + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/edit-history.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/edit-history.js should pass jshint.'); -}); + function _triggerEditorEvent(editor, event) { + editor.triggerEvent(editor.element, event.type, event); + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/edit-state.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/edit-state.js should pass jshint.'); -}); + function _buildDOM(tagName) { + var attributes = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + var children = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/editor.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/editor.js should pass jshint.'); -}); + var el = document.createElement(tagName); + Object.keys(attributes).forEach(function (k) { + return el.setAttribute(k, attributes[k]); + }); + children.forEach(function (child) { + return el.appendChild(child); + }); + return el; + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/event-manager.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/event-manager.js should pass jshint.'); -}); + _buildDOM.text = function (string) { + return document.createTextNode(string); + }; -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/key-commands.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/key-commands.js should pass jshint.'); -}); + /** + * Usage: + * build(t => + * t('div', attributes={}, children=[ + * t('b', {}, [ + * t.text('I am a bold text node') + * ]) + * ]) + * ); + */ + function build(tree) { + return tree(_buildDOM); + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/mutation-handler.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/mutation-handler.js should pass jshint.'); -}); + function getSelectedText() { + var selection = window.getSelection(); + if (selection.rangeCount === 0) { + return null; + } else if (selection.rangeCount > 1) { + // FIXME? + throw new Error('Unable to get selected text for multiple ranges'); + } else { + return selection.toString(); + } + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/post.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/post.js should pass jshint.'); -}); + // returns the node and the offset that the cursor is on + function getCursorPosition() { + var selection = window.getSelection(); + return { + node: selection.anchorNode, + offset: selection.anchorOffset + }; + } -QUnit.module('JSHint - tests/jshint/js/editor/post'); -QUnit.test('tests/jshint/js/editor/post/post-inserter.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/post/post-inserter.js should pass jshint.'); -}); + function createMockEvent(eventName, element) { + var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/selection-change-observer.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/selection-change-observer.js should pass jshint.'); -}); + var event = { + type: eventName, + preventDefault: function preventDefault() {}, + target: element + }; + (0, _mobiledocKitUtilsMerge.merge)(event, options); + return event; + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/selection-manager.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/selection-manager.js should pass jshint.'); -}); + // options is merged into the mocked `KeyboardEvent` data. + // Useful for simulating modifier keys, eg: + // triggerDelete(editor, DIRECTION.BACKWARD, {altKey: true}) + function triggerDelete(editor) { + var direction = arguments.length <= 1 || arguments[1] === undefined ? _mobiledocKitUtilsKey.DIRECTION.BACKWARD : arguments[1]; + var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/text-input-handler.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/text-input-handler.js should pass jshint.'); -}); + assertEditor(editor); + var keyCode = direction === _mobiledocKitUtilsKey.DIRECTION.BACKWARD ? _mobiledocKitUtilsKeycodes['default'].BACKSPACE : _mobiledocKitUtilsKeycodes['default'].DELETE; + var eventOptions = (0, _mobiledocKitUtilsMerge.merge)({ keyCode: keyCode }, options); + var event = createMockEvent('keydown', editor.element, eventOptions); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/text-input-handlers.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/text-input-handlers.js should pass jshint.'); -}); + function triggerForwardDelete(editor, options) { + return triggerDelete(editor, _mobiledocKitUtilsKey.DIRECTION.FORWARD, options); + } -QUnit.module('JSHint - tests/jshint/js/editor'); -QUnit.test('tests/jshint/js/editor/ui.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/editor/ui.js should pass jshint.'); -}); + function triggerEnter(editor) { + assertEditor(editor); + var event = createMockEvent('keydown', editor.element, { keyCode: _mobiledocKitUtilsKeycodes['default'].ENTER }); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js'); -QUnit.test('tests/jshint/js/index.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/index.js should pass jshint.'); -}); + // keyCodes and charCodes are similar but not the same. + function keyCodeForChar(letter) { + var keyCode = undefined; + switch (letter) { + case '.': + keyCode = _mobiledocKitUtilsKeycodes['default']['.']; + break; + case '\n': + keyCode = _mobiledocKitUtilsKeycodes['default'].ENTER; + break; + default: + keyCode = letter.charCodeAt(0); + } + return keyCode; + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/_markerable.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/_markerable.js should pass jshint.'); -}); + function insertText(editor, string) { + if (!string && editor) { + throw new Error('Must pass `editor` to `insertText`'); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/_section.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/_section.js should pass jshint.'); -}); + string.split('').forEach(function (letter) { + var stop = false; + var keyCode = keyCodeForChar(letter); + var charCode = letter.charCodeAt(0); + var preventDefault = function preventDefault() { + return stop = true; + }; + var keydown = createMockEvent('keydown', editor.element, { + keyCode: keyCode, + charCode: charCode, + preventDefault: preventDefault + }); + var keypress = createMockEvent('keypress', editor.element, { + keyCode: keyCode, + charCode: charCode + }); + var keyup = createMockEvent('keyup', editor.element, { + keyCode: keyCode, + charCode: charCode, + preventDefault: preventDefault + }); -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/atom-node.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/atom-node.js should pass jshint.'); -}); + _triggerEditorEvent(editor, keydown); + if (stop) { + return; + } + _triggerEditorEvent(editor, keypress); + if (stop) { + return; + } + _triggerEditorEvent(editor, keyup); + }); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/atom.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/atom.js should pass jshint.'); -}); + function triggerKeyEvent(editor, type, options) { + var event = createMockEvent(type, editor.element, options); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/card-node.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/card-node.js should pass jshint.'); -}); + // triggers a key sequence like cmd-B on the editor, to test out + // registered keyCommands + function triggerKeyCommand(editor, string) { + var modifiers = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/card.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/card.js should pass jshint.'); -}); + if (typeof modifiers === "number") { + modifiers = [modifiers]; // convert singular to array + } + var charCode = _mobiledocKitUtilsKeycodes['default'][string] || string.toUpperCase().charCodeAt(0); + var keyCode = charCode; + var keyEvent = createMockEvent('keydown', editor.element, { + charCode: charCode, + keyCode: keyCode, + shiftKey: (0, _mobiledocKitUtilsArrayUtils.contains)(modifiers, _mobiledocKitUtilsKey.MODIFIERS.SHIFT), + metaKey: (0, _mobiledocKitUtilsArrayUtils.contains)(modifiers, _mobiledocKitUtilsKey.MODIFIERS.META), + ctrlKey: (0, _mobiledocKitUtilsArrayUtils.contains)(modifiers, _mobiledocKitUtilsKey.MODIFIERS.CTRL) + }); + _triggerEditorEvent(editor, keyEvent); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/image.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/image.js should pass jshint.'); -}); + function triggerRightArrowKey(editor, modifier) { + if (!(editor instanceof _mobiledocKit.Editor)) { + throw new Error('Must pass editor to triggerRightArrowKey'); + } + var keydown = createMockEvent('keydown', editor.element, { + keyCode: _mobiledocKitUtilsKeycodes['default'].RIGHT, + shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT + }); + var keyup = createMockEvent('keyup', editor.element, { + keyCode: _mobiledocKitUtilsKeycodes['default'].RIGHT, + shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT + }); + _triggerEditorEvent(editor, keydown); + _triggerEditorEvent(editor, keyup); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/lifecycle-callbacks.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/lifecycle-callbacks.js should pass jshint.'); -}); + function triggerLeftArrowKey(editor, modifier) { + assertEditor(editor); + var keydown = createMockEvent('keydown', editor.element, { + keyCode: _mobiledocKitUtilsKeycodes['default'].LEFT, + shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT + }); + var keyup = createMockEvent('keyup', editor.element, { + keyCode: _mobiledocKitUtilsKeycodes['default'].LEFT, + shiftKey: modifier === _mobiledocKitUtilsKey.MODIFIERS.SHIFT + }); + _triggerEditorEvent(editor, keydown); + _triggerEditorEvent(editor, keyup); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/list-item.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/list-item.js should pass jshint.'); -}); + // Allows our fake copy and paste events to communicate with each other. + var lastCopyData = {}; + function triggerCopyEvent(editor) { + var eventData = { + clipboardData: { + setData: function setData(type, value) { + lastCopyData[type] = value; + } + } + }; -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/list-section.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/list-section.js should pass jshint.'); -}); + var event = createMockEvent('copy', editor.element, eventData); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/marker.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/marker.js should pass jshint.'); -}); + function triggerCutEvent(editor) { + var event = createMockEvent('cut', editor.element, { + clipboardData: { + setData: function setData(type, value) { + lastCopyData[type] = value; + } + } + }); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/markup-section.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/markup-section.js should pass jshint.'); -}); + function triggerPasteEvent(editor) { + var eventData = { + clipboardData: { + getData: function getData(type) { + return lastCopyData[type]; + } + } + }; -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/markup.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/markup.js should pass jshint.'); -}); + var event = createMockEvent('paste', editor.element, eventData); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/post-node-builder.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/post-node-builder.js should pass jshint.'); -}); + function triggerDropEvent(editor, _ref) { + var html = _ref.html; + var text = _ref.text; + var clientX = _ref.clientX; + var clientY = _ref.clientY; -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/post.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/post.js should pass jshint.'); -}); + if (!clientX || !clientY) { + throw new Error('Must pass clientX, clientY'); + } + var event = createMockEvent('drop', editor.element, { + clientX: clientX, + clientY: clientY, + dataTransfer: { + getData: function getData(mimeType) { + switch (mimeType) { + case _mobiledocKitUtilsParseUtils.MIME_TEXT_HTML: + return html; + case _mobiledocKitUtilsParseUtils.MIME_TEXT_PLAIN: + return text; + default: + throw new Error('invalid mime type ' + mimeType); + } + } + } + }); -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/render-node.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/render-node.js should pass jshint.'); -}); + _triggerEditorEvent(editor, event); + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/render-tree.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/render-tree.js should pass jshint.'); -}); + function getCopyData(type) { + return lastCopyData[type]; + } -QUnit.module('JSHint - tests/jshint/js/models'); -QUnit.test('tests/jshint/js/models/types.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/models/types.js should pass jshint.'); -}); + function setCopyData(type, value) { + lastCopyData[type] = value; + } -QUnit.module('JSHint - tests/jshint/js/parsers'); -QUnit.test('tests/jshint/js/parsers/dom.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/dom.js should pass jshint.'); -}); + function clearCopyData() { + Object.keys(lastCopyData).forEach(function (key) { + delete lastCopyData[key]; + }); + } -QUnit.module('JSHint - tests/jshint/js/parsers'); -QUnit.test('tests/jshint/js/parsers/html.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/html.js should pass jshint.'); -}); + function fromHTML(html) { + html = $.trim(html); + var div = document.createElement('div'); + div.innerHTML = html; + return div; + } -QUnit.module('JSHint - tests/jshint/js/parsers/mobiledoc'); -QUnit.test('tests/jshint/js/parsers/mobiledoc/0-2.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/mobiledoc/0-2.js should pass jshint.'); -}); + /** + * Tests fail in IE when using `element.blur`, so remove focus by refocusing + * on another item instead of blurring the editor element + */ + function blur() { + var input = $(''); + input.appendTo('#qunit-fixture'); + input.focus(); + } -QUnit.module('JSHint - tests/jshint/js/parsers/mobiledoc'); -QUnit.test('tests/jshint/js/parsers/mobiledoc/0-3-1.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/mobiledoc/0-3-1.js should pass jshint.'); -}); + function getData(element, name) { + if (element.dataset) { + return element.dataset[name]; + } else { + return element.getAttribute((0, _mobiledocKitUtilsStringUtils.dasherize)(name)); + } + } -QUnit.module('JSHint - tests/jshint/js/parsers/mobiledoc'); -QUnit.test('tests/jshint/js/parsers/mobiledoc/0-3.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/mobiledoc/0-3.js should pass jshint.'); -}); + var DOMHelper = { + moveCursorTo: moveCursorTo, + moveCursorWithoutNotifyingEditorTo: moveCursorWithoutNotifyingEditorTo, + selectRange: selectRange, + selectText: selectText, + clearSelection: _mobiledocKitUtilsSelectionUtils.clearSelection, + triggerEvent: triggerEvent, + build: build, + fromHTML: fromHTML, + KEY_CODES: _mobiledocKitUtilsKeycodes['default'], + getCursorPosition: getCursorPosition, + getSelectedText: getSelectedText, + triggerDelete: triggerDelete, + triggerForwardDelete: triggerForwardDelete, + triggerEnter: triggerEnter, + insertText: insertText, + triggerKeyEvent: triggerKeyEvent, + triggerKeyCommand: triggerKeyCommand, + triggerRightArrowKey: triggerRightArrowKey, + triggerLeftArrowKey: triggerLeftArrowKey, + triggerCopyEvent: triggerCopyEvent, + triggerCutEvent: triggerCutEvent, + triggerPasteEvent: triggerPasteEvent, + triggerDropEvent: triggerDropEvent, + getCopyData: getCopyData, + setCopyData: setCopyData, + clearCopyData: clearCopyData, + createMockEvent: createMockEvent, + findTextNode: findTextNode, + blur: blur, + getData: getData + }; -QUnit.module('JSHint - tests/jshint/js/parsers/mobiledoc'); -QUnit.test('tests/jshint/js/parsers/mobiledoc/index.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/mobiledoc/index.js should pass jshint.'); + exports.triggerEvent = triggerEvent; + exports['default'] = DOMHelper; }); +define('tests/helpers/editor', ['exports', './post-abstract', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/renderers/mobiledoc/0-3-1'], function (exports, _postAbstract, _mobiledocKitEditorEditor, _mobiledocKitRenderersMobiledoc031) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/js/parsers'); -QUnit.test('tests/jshint/js/parsers/section.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/section.js should pass jshint.'); -}); + function retargetPosition(position, toPost) { + var fromPost = position.section.post; + var sectionIndex = undefined; + var retargetedPosition = undefined; + fromPost.walkAllLeafSections(function (section, index) { + if (sectionIndex !== undefined) { + return; + } + if (section === position.section) { + sectionIndex = index; + } + }); + if (sectionIndex === undefined) { + throw new Error('`retargetPosition` could not find section index'); + } + toPost.walkAllLeafSections(function (section, index) { + if (retargetedPosition) { + return; + } + if (index === sectionIndex) { + retargetedPosition = section.toPosition(position.offset); + } + }); + if (!retargetedPosition) { + throw new Error('`retargetPosition` could not find target section'); + } + return retargetedPosition; + } -QUnit.module('JSHint - tests/jshint/js/parsers'); -QUnit.test('tests/jshint/js/parsers/text.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/parsers/text.js should pass jshint.'); -}); + function retargetRange(range, toPost) { + var newHead = retargetPosition(range.head, toPost); + var newTail = retargetPosition(range.tail, toPost); -QUnit.module('JSHint - tests/jshint/js/renderers'); -QUnit.test('tests/jshint/js/renderers/editor-dom.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/renderers/editor-dom.js should pass jshint.'); -}); + return newHead.toRange(newTail); + } -QUnit.module('JSHint - tests/jshint/js/renderers/mobiledoc'); -QUnit.test('tests/jshint/js/renderers/mobiledoc/0-2.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/renderers/mobiledoc/0-2.js should pass jshint.'); -}); + function buildFromText(texts) { + var editorOptions = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; -QUnit.module('JSHint - tests/jshint/js/renderers/mobiledoc'); -QUnit.test('tests/jshint/js/renderers/mobiledoc/0-3-1.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/renderers/mobiledoc/0-3-1.js should pass jshint.'); -}); + var renderElement = editorOptions.element; + delete editorOptions.element; -QUnit.module('JSHint - tests/jshint/js/renderers/mobiledoc'); -QUnit.test('tests/jshint/js/renderers/mobiledoc/0-3.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/renderers/mobiledoc/0-3.js should pass jshint.'); -}); + var beforeRender = editorOptions.beforeRender || function () {}; + delete editorOptions.beforeRender; -QUnit.module('JSHint - tests/jshint/js/renderers/mobiledoc'); -QUnit.test('tests/jshint/js/renderers/mobiledoc/index.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/renderers/mobiledoc/index.js should pass jshint.'); -}); + var _PostAbstractHelpers$buildFromText = _postAbstract['default'].buildFromText(texts); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/array-utils.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/array-utils.js should pass jshint.'); -}); + var post = _PostAbstractHelpers$buildFromText.post; + var range = _PostAbstractHelpers$buildFromText.range; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/assert.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/assert.js should pass jshint.'); -}); + var mobiledoc = _mobiledocKitRenderersMobiledoc031['default'].render(post); + editorOptions.mobiledoc = mobiledoc; + var editor = new _mobiledocKitEditorEditor['default'](editorOptions); + if (renderElement) { + beforeRender(editor); + editor.render(renderElement); + if (range) { + range = retargetRange(range, editor.post); + editor.selectRange(range); + } + } + return editor; + } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/browser.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/browser.js should pass jshint.'); + exports.buildFromText = buildFromText; + exports.retargetRange = retargetRange; + exports.retargetPosition = retargetPosition; }); +define('tests/helpers/mobiledoc', ['exports', './post-abstract', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/renderers/mobiledoc/0-2', 'mobiledoc-kit/renderers/mobiledoc/0-3', 'mobiledoc-kit/renderers/mobiledoc/0-3-1', 'mobiledoc-kit/renderers/mobiledoc/0-3-2', 'mobiledoc-kit/editor/editor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/merge'], function (exports, _postAbstract, _mobiledocKitRenderersMobiledoc, _mobiledocKitRenderersMobiledoc02, _mobiledocKitRenderersMobiledoc03, _mobiledocKitRenderersMobiledoc031, _mobiledocKitRenderersMobiledoc032, _mobiledocKitEditorEditor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsMerge) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/characters.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/characters.js should pass jshint.'); -}); + /* + * usage: + * build(({post, section, marker, markup}) => + * post([ + * section('P', [ + * marker('some text', [markup('B')]) + * ]) + * }) + * ) + * @return Mobiledoc + */ + function build(treeFn, version) { + var post = _postAbstract['default'].build(treeFn); + switch (version) { + case _mobiledocKitRenderersMobiledoc02.MOBILEDOC_VERSION: + return _mobiledocKitRenderersMobiledoc02['default'].render(post); + case _mobiledocKitRenderersMobiledoc03.MOBILEDOC_VERSION: + return _mobiledocKitRenderersMobiledoc03['default'].render(post); + case _mobiledocKitRenderersMobiledoc031.MOBILEDOC_VERSION: + return _mobiledocKitRenderersMobiledoc031['default'].render(post); + case _mobiledocKitRenderersMobiledoc032.MOBILEDOC_VERSION: + return _mobiledocKitRenderersMobiledoc032['default'].render(post); + case undefined: + case null: + return _mobiledocKitRenderersMobiledoc['default'].render(post); + default: + throw new Error('Unknown version of mobiledoc renderer requested: ' + version); + } + } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/compiler.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/compiler.js should pass jshint.'); -}); + function renderPostInto(element, post) { + var editorOptions = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/copy.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/copy.js should pass jshint.'); -}); + var mobiledoc = _mobiledocKitRenderersMobiledoc['default'].render(post); + (0, _mobiledocKitUtilsMerge.mergeWithOptions)(editorOptions, { mobiledoc: mobiledoc }); + var editor = new _mobiledocKitEditorEditor['default'](editorOptions); + editor.render(element); + return editor; + } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/cursor.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/cursor.js should pass jshint.'); -}); + function renderInto(element, treeFn) { + var editorOptions = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/utils/cursor'); -QUnit.test('tests/jshint/js/utils/cursor/position.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/cursor/position.js should pass jshint.'); -}); + var mobiledoc = build(treeFn); + (0, _mobiledocKitUtilsMerge.mergeWithOptions)(editorOptions, { mobiledoc: mobiledoc }); + var editor = new _mobiledocKitEditorEditor['default'](editorOptions); + editor.render(element); + return editor; + } -QUnit.module('JSHint - tests/jshint/js/utils/cursor'); -QUnit.test('tests/jshint/js/utils/cursor/range.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/cursor/range.js should pass jshint.'); -}); + // In Firefox, if the window isn't active (which can happen when running tests + // at SauceLabs), the editor element won't have the selection. This helper method + // ensures that it has a cursor selection. + // See https://github.com/bustle/mobiledoc-kit/issues/388 + function renderIntoAndFocusTail(editorElement, treeFn) { + var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/deprecate.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/deprecate.js should pass jshint.'); -}); + var editor = renderInto(editorElement, treeFn, options); + editor.selectRange(new _mobiledocKitUtilsCursorRange['default'](editor.post.tailPosition())); + return editor; + } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/dom-utils.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/dom-utils.js should pass jshint.'); + exports['default'] = { + build: build, + renderInto: renderInto, + renderPostInto: renderPostInto, + renderIntoAndFocusTail: renderIntoAndFocusTail + }; }); +define('tests/helpers/mock-editor', ['exports', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitEditorPost, _mobiledocKitUtilsCursorRange) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/element-map.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/element-map.js should pass jshint.'); -}); + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/element-utils.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/element-utils.js should pass jshint.'); -}); + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/environment.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/environment.js should pass jshint.'); -}); + var MockEditor = (function () { + function MockEditor(builder) { + _classCallCheck(this, MockEditor); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/fixed-queue.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/fixed-queue.js should pass jshint.'); -}); + this.builder = builder; + this.range = _mobiledocKitUtilsCursorRange['default'].blankRange(); + } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/key.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/key.js should pass jshint.'); -}); + _createClass(MockEditor, [{ + key: 'run', + value: function run(callback) { + var postEditor = new _mobiledocKitEditorPost['default'](this); + postEditor.begin(); + var result = callback(postEditor); + postEditor.end(); + return result; + } + }, { + key: 'rerender', + value: function rerender() {} + }, { + key: '_postDidChange', + value: function _postDidChange() {} + }, { + key: 'selectRange', + value: function selectRange(range) { + this._renderedRange = range; + } + }, { + key: '_readRangeFromDOM', + value: function _readRangeFromDOM() {} + }]); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/keycodes.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/keycodes.js should pass jshint.'); -}); + return MockEditor; + })(); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/linked-item.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/linked-item.js should pass jshint.'); + exports['default'] = MockEditor; }); +define('tests/helpers/module-load-failure', ['exports', 'ember-cli/test-loader'], function (exports, _emberCliTestLoader) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/linked-list.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/linked-list.js should pass jshint.'); -}); + /** + * Ensures that when the TestLoader failures to load a test module, the error + * is reported. Without this the rest of the full test suite still passes and there is an + * error printed in the console only. + * The technique is from: https://github.com/ember-cli/ember-cli-qunit/blob/master/vendor/ember-cli-qunit/test-loader.js#L55 + */ -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/log-manager.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/log-manager.js should pass jshint.'); -}); + exports['default'] = function (QUnit) { + var moduleLoadFailures = []; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/markuperable.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/markuperable.js should pass jshint.'); -}); + _emberCliTestLoader['default'].prototype.moduleLoadFailure = function (moduleName, error) { + moduleLoadFailures.push(error); + QUnit.module('TestLoader Failures'); + QUnit.test(moduleName + ': could not be loaded', function () { + throw error; + }); + }; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/merge.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/merge.js should pass jshint.'); + QUnit.done(function () { + if (moduleLoadFailures.length) { + throw new Error('\n' + moduleLoadFailures.join('\n')); + } + }); + }; }); +define('tests/helpers/post-abstract', ['exports', 'mobiledoc-kit/models/post-node-builder'], function (exports, _mobiledocKitModelsPostNodeBuilder) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/mixin.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/mixin.js should pass jshint.'); -}); + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/mobiledoc-error.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/mobiledoc-error.js should pass jshint.'); -}); + /* + * usage: + * Helpers.postAbstract.build(({post, section, marker, markup}) => + * post([ + * section('P', [ + * marker('some text', [markup('B')]) + * ]) + * }) + * ) + */ + function build(treeFn) { + var builder = new _mobiledocKitModelsPostNodeBuilder['default'](); -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/parse-utils.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/parse-utils.js should pass jshint.'); -}); + var simpleBuilder = { + post: function post() { + return builder.createPost.apply(builder, arguments); + }, + markupSection: function markupSection() { + return builder.createMarkupSection.apply(builder, arguments); + }, + markup: function markup() { + return builder.createMarkup.apply(builder, arguments); + }, + marker: function marker() { + return builder.createMarker.apply(builder, arguments); + }, + listSection: function listSection() { + return builder.createListSection.apply(builder, arguments); + }, + listItem: function listItem() { + return builder.createListItem.apply(builder, arguments); + }, + cardSection: function cardSection() { + return builder.createCardSection.apply(builder, arguments); + }, + imageSection: function imageSection() { + return builder.createImageSection.apply(builder, arguments); + }, + atom: function atom() { + return builder.createAtom.apply(builder, arguments); + } + }; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/placeholder-image-src.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/placeholder-image-src.js should pass jshint.'); -}); + return treeFn(simpleBuilder); + } -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/selection-utils.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/selection-utils.js should pass jshint.'); -}); + var cardRegex = /\[(.*)\]/; + var markupRegex = /\*/g; + var listStartRegex = /^\* /; + var cursorRegex = /<|>|\|/g; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/set.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/set.js should pass jshint.'); -}); + function parsePositionOffsets(text) { + var offsets = {}; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/string-utils.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/string-utils.js should pass jshint.'); -}); + if (cardRegex.test(text)) { + [['|', 'solo'], ['<', 'start'], ['>', 'end']].forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2); + + var char = _ref2[0]; + var type = _ref2[1]; -QUnit.module('JSHint - tests/jshint/js/utils'); -QUnit.test('tests/jshint/js/utils/to-range.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/utils/to-range.js should pass jshint.'); -}); + if (text.indexOf(char) !== -1) { + offsets[type] = text.indexOf(char) === 0 ? 0 : 1; + } + }); + } else { + if (listStartRegex.test(text)) { + text = text.replace(listStartRegex, ''); + } + text = text.replace(markupRegex, ''); + if (text.indexOf('|') !== -1) { + offsets.solo = text.indexOf('|'); + } else if (text.indexOf('<') !== -1 || text.indexOf('>') !== -1) { + var hasStart = text.indexOf('<') !== -1; + var hasEnd = text.indexOf('>') !== -1; + if (hasStart) { + offsets.start = text.indexOf('<'); + text = text.replace(/'); + } + } + } -QUnit.module('JSHint - tests/jshint/js'); -QUnit.test('tests/jshint/js/version.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/version.js should pass jshint.'); -}); + return offsets; + } -QUnit.module('JSHint - tests/jshint/js/views'); -QUnit.test('tests/jshint/js/views/tooltip.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/views/tooltip.js should pass jshint.'); -}); + var DEFAULT_ATOM_NAME = 'some-atom'; + var DEFAULT_ATOM_VALUE = '@atom'; -QUnit.module('JSHint - tests/jshint/js/views'); -QUnit.test('tests/jshint/js/views/view.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/js/views/view.js should pass jshint.'); -}); + var MARKUP_CHARS = { + '*': 'b', + '_': 'em' + }; -QUnit.module('JSHint - tests/jshint'); -QUnit.test('tests/jshint/test-helpers.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/test-helpers.js should pass jshint.'); -}); + function parseTextIntoAtom(text, builder) { + var markers = []; + var atomIndex = text.indexOf('@'); + var afterAtomIndex = atomIndex + 1; + var atomName = DEFAULT_ATOM_NAME, + atomValue = DEFAULT_ATOM_VALUE, + atomPayload = {}; -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/atom-lifecycle-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/atom-lifecycle-test.js should pass jshint.'); -}); + // If "@" is followed by "( ... json ... )", parse the json data + if (text[atomIndex + 1] === "(") { + var jsonStartIndex = atomIndex + 1; + var jsonEndIndex = text.indexOf(")", jsonStartIndex); + afterAtomIndex = jsonEndIndex + 1; + if (jsonEndIndex === -1) { + throw new Error('Atom JSON data had unmatched "(": ' + text); + } + var jsonString = text.slice(jsonStartIndex + 1, jsonEndIndex); + jsonString = "{" + jsonString + "}"; + try { + var json = JSON.parse(jsonString); + if (json.name) { + atomName = json.name; + } + if (json.value) { + atomValue = json.value; + } + if (json.payload) { + atomPayload = json.payload; + } + } catch (e) { + throw new Error('Failed to parse atom JSON data string: ' + jsonString + ', ' + e); + } + } -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/card-lifecycle-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/card-lifecycle-test.js should pass jshint.'); -}); + // create the atom + var atom = builder.atom(atomName, atomValue, atomPayload); -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/editor-events-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/editor-events-test.js should pass jshint.'); -}); + // recursively parse the remaining text pieces + var pieces = [text.slice(0, atomIndex), atom, text.slice(afterAtomIndex)]; -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/editor-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/editor-test.js should pass jshint.'); -}); + // join the markers together + pieces.forEach(function (piece, index) { + if (index === 1) { + // atom + markers.push(piece); + } else if (piece.length) { + markers = markers.concat(parseTextIntoMarkers(piece, builder)); + } + }); -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/key-commands-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/key-commands-test.js should pass jshint.'); -}); + return markers; + } -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/post-delete-at-position-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/post-delete-at-position-test.js should pass jshint.'); -}); + function parseTextWithMarkup(text, builder) { + var markers = []; + var markup = undefined, + char = undefined; + Object.keys(MARKUP_CHARS).forEach(function (key) { + if (markup) { + return; + } + if (text.indexOf(key) !== -1) { + markup = builder.markup(MARKUP_CHARS[key]); + char = key; + } + }); + if (!markup) { + throw new Error('Failed to find markup in text: ' + text); + } -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/post-delete-range-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/post-delete-range-test.js should pass jshint.'); -}); + var startIndex = text.indexOf(char); + var endIndex = text.indexOf(char, startIndex + 1); + if (endIndex === -1) { + throw new Error('Malformed text: char ' + char + ' do not match'); + } -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/post-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/post-test.js should pass jshint.'); -}); + var pieces = [text.slice(0, startIndex), text.slice(startIndex + 1, endIndex), text.slice(endIndex + 1)]; + pieces.forEach(function (piece, index) { + if (index === 1) { + // marked-up text + markers.push(builder.marker(piece, [markup])); + } else { + markers = markers.concat(parseTextIntoMarkers(piece, builder)); + } + }); -QUnit.module('JSHint - tests/jshint/unit/editor/post'); -QUnit.test('tests/jshint/unit/editor/post/insert-post-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/post/insert-post-test.js should pass jshint.'); -}); + return markers; + } -QUnit.module('JSHint - tests/jshint/unit/editor'); -QUnit.test('tests/jshint/unit/editor/ui-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/editor/ui-test.js should pass jshint.'); -}); + function parseTextIntoMarkers(text, builder) { + text = text.replace(cursorRegex, ''); + var markers = []; -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/atom-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/atom-test.js should pass jshint.'); -}); + var hasAtom = text.indexOf('@') !== -1; + var hasMarkup = false; + Object.keys(MARKUP_CHARS).forEach(function (key) { + if (text.indexOf(key) !== -1) { + hasMarkup = true; + } + }); -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/card-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/card-test.js should pass jshint.'); -}); + if (hasAtom) { + markers = markers.concat(parseTextIntoAtom(text, builder)); + } else if (hasMarkup) { + markers = markers.concat(parseTextWithMarkup(text, builder)); + } else if (text.length) { + markers.push(builder.marker(text)); + } -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/lifecycle-callbacks-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/lifecycle-callbacks-test.js should pass jshint.'); -}); + return markers; + } -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/list-section-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/list-section-test.js should pass jshint.'); -}); + function parseSingleText(text, builder) { + var section = undefined, + positions = {}; -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/marker-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/marker-test.js should pass jshint.'); -}); + var offsets = parsePositionOffsets(text); -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/markup-section-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/markup-section-test.js should pass jshint.'); -}); + if (cardRegex.test(text)) { + section = builder.cardSection(cardRegex.exec(text)[1]); + } else { + var type = 'p'; + if (listStartRegex.test(text)) { + text = text.replace(listStartRegex, ''); + type = 'ul'; + } -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/post-node-builder-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/post-node-builder-test.js should pass jshint.'); -}); + var markers = parseTextIntoMarkers(text, builder); -QUnit.module('JSHint - tests/jshint/unit/models'); -QUnit.test('tests/jshint/unit/models/post-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/models/post-test.js should pass jshint.'); -}); + switch (type) { + case 'p': + section = builder.markupSection('p', markers); + break; + case 'ul': + section = builder.listItem(markers); + break; + } + } -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/dom-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/dom-test.js should pass jshint.'); -}); + ['start', 'end', 'solo'].forEach(function (type) { + if (offsets[type] !== undefined) { + positions[type] = section.toPosition(offsets[type]); + } + }); -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/html-google-docs-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/html-google-docs-test.js should pass jshint.'); -}); + return { section: section, positions: positions }; + } -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/html-google-sheets-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/html-google-sheets-test.js should pass jshint.'); -}); + /** + * Shorthand to create a mobiledoc simply. + * Pass a string or an array of strings. + * + * Returns { post, range }, a post built from the mobiledoc and a range. + * + * Use "|" to indicate the cursor position or "<" and ">" to indicate a range. + * Use "[card-name]" to indicate a card + * Use asterisks to indicate bold text: "abc *bold* def" + * Use "@" to indicate an atom, default values for name,value,payload are DEFAULT_ATOM_NAME,DEFAULT_ATOM_VALUE,{} + * Use "@(name, value, payload)" to specify name,value and/or payload for an atom. The string from `(` to `)` is parsed as + * JSON, e.g.: '@("name": "my-atom", "value": "abc", "payload": {"foo": "bar"})' -> atom named "my-atom" with value 'abc', payload {foo: 'bar'} + * Use "* " at the start of the string to indicate a list item ("ul") + * + * Examples: + * buildFromText("abc") -> { post } with 1 markup section ("p") with text "abc" + * buildFromText(["abc","def"]) -> { post } with 2 markups sections ("p") with texts "abc" and "def" + * buildFromText("abc|def") -> { post, range } where range is collapsed at offset 3 (after the "c") + * buildFromText(["abcdef","[some-card]","def"]) -> { post } with [MarkupSection, Card, MarkupSection] sections + * buildFromText(["* item 1", "* item 2"]) -> { post } with a ListSection with 2 ListItems + * buildFromText([""]) -> { post, range } where range is the entire post (before the "a" to after the "i") + */ + function buildFromText(texts) { + if (!Array.isArray(texts)) { + texts = [texts]; + } + var positions = {}; -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/html-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/html-test.js should pass jshint.'); -}); + var post = build(function (builder) { + var sections = []; + var curList = undefined; + texts.forEach(function (text, index) { + var _parseSingleText = parseSingleText(text, builder); -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/mobiledoc-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/mobiledoc-test.js should pass jshint.'); -}); + var section = _parseSingleText.section; + var _positions = _parseSingleText.positions; -QUnit.module('JSHint - tests/jshint/unit/parsers/mobiledoc'); -QUnit.test('tests/jshint/unit/parsers/mobiledoc/0-2-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/mobiledoc/0-2-test.js should pass jshint.'); -}); + var lastText = index === texts.length - 1; -QUnit.module('JSHint - tests/jshint/unit/parsers/mobiledoc'); -QUnit.test('tests/jshint/unit/parsers/mobiledoc/0-3-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/mobiledoc/0-3-test.js should pass jshint.'); -}); + if (curList) { + if (section.isListItem) { + curList.items.append(section); + } else { + sections.push(curList); + sections.push(section); + curList = null; + } + } else if (section.isListItem) { + curList = builder.listSection('ul', [section]); + } else { + sections.push(section); + } -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/section-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/section-test.js should pass jshint.'); -}); + if (lastText && curList) { + sections.push(curList); + } -QUnit.module('JSHint - tests/jshint/unit/parsers'); -QUnit.test('tests/jshint/unit/parsers/text-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/parsers/text-test.js should pass jshint.'); -}); + if (_positions.start) { + positions.start = _positions.start; + } + if (_positions.end) { + positions.end = _positions.end; + } + if (_positions.solo) { + positions.solo = _positions.solo; + } + }); -QUnit.module('JSHint - tests/jshint/unit/renderers'); -QUnit.test('tests/jshint/unit/renderers/editor-dom-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/renderers/editor-dom-test.js should pass jshint.'); -}); + return builder.post(sections); + }); -QUnit.module('JSHint - tests/jshint/unit/renderers'); -QUnit.test('tests/jshint/unit/renderers/mobiledoc-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/renderers/mobiledoc-test.js should pass jshint.'); -}); + var range = undefined; + if (positions.start) { + if (!positions.end) { + throw new Error('startPos but no endPos ' + texts.join('\n')); + } + range = positions.start.toRange(positions.end); + } else if (positions.solo) { + range = positions.solo.toRange(); + } -QUnit.module('JSHint - tests/jshint/unit/renderers/mobiledoc'); -QUnit.test('tests/jshint/unit/renderers/mobiledoc/0-2-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/renderers/mobiledoc/0-2-test.js should pass jshint.'); -}); + return { post: post, range: range }; + } -QUnit.module('JSHint - tests/jshint/unit/renderers/mobiledoc'); -QUnit.test('tests/jshint/unit/renderers/mobiledoc/0-3-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/renderers/mobiledoc/0-3-test.js should pass jshint.'); + exports['default'] = { + build: build, + buildFromText: buildFromText, + DEFAULT_ATOM_NAME: DEFAULT_ATOM_NAME + }; }); +define('tests/helpers/post-editor-run', ['exports', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/post', './mock-editor', './render-built-abstract'], function (exports, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorPost, _mockEditor, _renderBuiltAbstract) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/array-utils-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/array-utils-test.js should pass jshint.'); -}); + exports['default'] = run; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/assert-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/assert-test.js should pass jshint.'); -}); + function run(post, callback) { + var builder = new _mobiledocKitModelsPostNodeBuilder['default'](); + var editor = new _mockEditor['default'](builder); -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/copy-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/copy-test.js should pass jshint.'); -}); + (0, _renderBuiltAbstract['default'])(post, editor); -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/cursor-position-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/cursor-position-test.js should pass jshint.'); + var postEditor = new _mobiledocKitEditorPost['default'](editor); + postEditor.begin(); + var result = callback(postEditor); + postEditor.complete(); + return result; + } }); +define('tests/helpers/render-built-abstract', ['exports', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree'], function (exports, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/cursor-range-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/cursor-range-test.js should pass jshint.'); -}); + exports['default'] = renderBuiltAbstract; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/fixed-queue-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/fixed-queue-test.js should pass jshint.'); + function renderBuiltAbstract(post, editor) { + editor.post = post; + var unknownCardHandler = function unknownCardHandler() {}; + var unknownAtomHandler = function unknownAtomHandler() {}; + var renderer = new _mobiledocKitRenderersEditorDom['default'](editor, [], [], unknownCardHandler, unknownAtomHandler); + var renderTree = new _mobiledocKitModelsRenderTree['default'](post); + renderer.render(renderTree); + return editor; + } }); +define('tests/helpers/sections', ['exports'], function (exports) { + 'use strict'; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/key-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/key-test.js should pass jshint.'); -}); + var VALID_ATTRIBUTES = [{ key: 'data-md-text-align', value: 'center' }, { key: 'data-md-text-align', value: 'justify' }, { key: 'data-md-text-align', value: 'left' }, { key: 'data-md-text-align', value: 'right' }]; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/linked-list-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/linked-list-test.js should pass jshint.'); + exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES; + var INVALID_ATTRIBUTES = [{ key: 'data-foo', value: 'baz' }]; + exports.INVALID_ATTRIBUTES = INVALID_ATTRIBUTES; }); +define("tests/helpers/wait", ["exports"], function (exports) { + "use strict"; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/parse-utils-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/parse-utils-test.js should pass jshint.'); -}); + var wait = function wait(callback) { + window.requestAnimationFrame(callback); + }; -QUnit.module('JSHint - tests/jshint/unit/utils'); -QUnit.test('tests/jshint/unit/utils/selection-utils-test.js should pass jshint', function(assert) { - assert.expect(1); - assert.ok(true, 'tests/jshint/unit/utils/selection-utils-test.js should pass jshint.'); + exports["default"] = wait; }); - define('tests/test-helpers', ['exports', './helpers/assertions', './helpers/module-load-failure', './helpers/dom', './helpers/mobiledoc', './helpers/post-abstract', './helpers/browsers', './helpers/wait', './helpers/mock-editor', './helpers/render-built-abstract', './helpers/post-editor-run', './helpers/editor'], function (exports, _helpersAssertions, _helpersModuleLoadFailure, _helpersDom, _helpersMobiledoc, _helpersPostAbstract, _helpersBrowsers, _helpersWait, _helpersMockEditor, _helpersRenderBuiltAbstract, _helpersPostEditorRun, _helpersEditor) { /* global QUnit */ 'use strict'; @@ -8524,7 +8849,8 @@ define('tests/test-helpers', ['exports', './helpers/assertions', './helpers/modu var originalCallback = callback; callback = function () { if (QUnit.config.debugTest) { - debugger; // jshint ignore:line + // eslint-disable-next-line no-debugger + debugger; } originalCallback.apply(undefined, arguments); }; @@ -10370,19 +10696,27 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor return post([markupSection('p', [marker('abc')])]); }, '0.3.1'); - - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref7) { + var mobiledoc3_2 = _testHelpers['default'].mobiledoc.build(function (_ref7) { var post = _ref7.post; var markupSection = _ref7.markupSection; var marker = _ref7.marker; + return post([markupSection('p', [marker('abc')])]); + }, '0.3.2'); + + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref8) { + var post = _ref8.post; + var markupSection = _ref8.markupSection; + var marker = _ref8.marker; + return post([markupSection('p', [marker('abc')])]); }); assert.deepEqual(editor.serialize('0.2.0'), mobiledoc2, 'serializes 0.2.0'); assert.deepEqual(editor.serialize('0.3.0'), mobiledoc3, 'serializes 0.3.0'); assert.deepEqual(editor.serialize('0.3.1'), mobiledoc3_1, 'serializes 0.3.1'); - assert.deepEqual(editor.serialize(), mobiledoc3_1, 'serializes 0.3.1 by default'); + assert.deepEqual(editor.serialize('0.3.2'), mobiledoc3_2, 'serializes 0.3.2'); + assert.deepEqual(editor.serialize(), mobiledoc3_2, 'serializes 0.3.2 by default'); assert.throws(function () { return editor.serialize('unknown'); @@ -10440,20 +10774,20 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor sections: [[], ["incorrect"]] }; assert.throws(function () { - new _mobiledocKitEditorEditor['default']({ mobiledoc: badMobiledoc }); // jshint ignore:line + new _mobiledocKitEditorEditor['default']({ mobiledoc: badMobiledoc }); }, /unable to parse.*mobiledoc/i); }); test('useful error message when given bad version of mobiledoc', function (assert) { var verybadMobiledoc = "not mobiledoc"; assert.throws(function () { - new _mobiledocKitEditorEditor['default']({ mobiledoc: verybadMobiledoc }); // jshint ignore:line + new _mobiledocKitEditorEditor['default']({ mobiledoc: verybadMobiledoc }); }, /Unknown version of mobiledoc parser requested/i); }); test('activeSections of a rendered blank mobiledoc is an empty array', function (assert) { - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref8) { - var post = _ref8.post; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref9) { + var post = _ref9.post; return post(); }); @@ -10463,10 +10797,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }); test('activeSections is empty when the editor has no cursor', function (assert) { - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref9) { - var post = _ref9.post; - var markupSection = _ref9.markupSection; - var marker = _ref9.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref10) { + var post = _ref10.post; + var markupSection = _ref10.markupSection; + var marker = _ref10.marker; return post([markupSection('p', [marker('abc')])]); }, { autofocus: false }); @@ -10475,9 +10809,37 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor assert.equal(editor.activeSections.length, 0, 'empty activeSections'); }); + test('activeSectionAttributes of a rendered blank mobiledoc is an empty array', function (assert) { + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref11) { + var post = _ref11.post; + + return post(); + }); + + assert.ok(editor.hasRendered, 'editor has rendered'); + assert.deepEqual(editor.activeSectionAttributes, {}, 'empty activeSectionAttributes'); + }); + + test('activeSectionAttributes is updated based on the selection', function (assert) { + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref12) { + var post = _ref12.post; + var markupSection = _ref12.markupSection; + var marker = _ref12.marker; + + return post([markupSection('p', [marker('abc')], false, { 'data-md-text-align': 'center' })]); + }, { autofocus: false }); + + assert.ok(!editor.hasCursor(), 'precond - no cursor'); + assert.deepEqual(editor.activeSectionAttributes, {}, 'empty activeSectionAttributes'); + + var head = editor.post.sections.head; + editor.selectRange(_mobiledocKitUtilsCursorRange['default'].create(head, 'abc'.length)); + assert.deepEqual(editor.activeSectionAttributes['text-align'], ['center'], 'active section attributes captured'); + }); + test('editor.cursor.hasCursor() is false before rendering', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref10) { - var post = _ref10.post; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref13) { + var post = _ref13.post; return post(); }); editor = new _mobiledocKitEditorEditor['default']({ mobiledoc: mobiledoc }); @@ -10490,8 +10852,8 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }); test('#destroy clears selection if it has one', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref11) { - var post = _ref11.post; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref14) { + var post = _ref14.post; return post(); }); editor = new _mobiledocKitEditorEditor['default']({ mobiledoc: mobiledoc }); @@ -10506,8 +10868,8 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }); test('#destroy does not clear selection if it is outside the editor element', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref12) { - var post = _ref12.post; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref15) { + var post = _ref15.post; return post(); }); editor = new _mobiledocKitEditorEditor['default']({ mobiledoc: mobiledoc }); @@ -10531,15 +10893,15 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor editor = new _mobiledocKitEditorEditor['default']({ html: html, parserPlugins: [parserPlugin] }); assert.ok(!!editor.post, 'editor loads post'); - assert.deepEqual(seenTagNames, ['TEXTAREA', 'IMG']); + assert.deepEqual(seenTagNames, ['P', 'TEXTAREA', 'IMG']); }); test('#activeMarkups returns the markups at cursor when range is collapsed', function (assert) { - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref13) { - var post = _ref13.post; - var markupSection = _ref13.markupSection; - var marker = _ref13.marker; - var markup = _ref13.markup; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref16) { + var post = _ref16.post; + var markupSection = _ref16.markupSection; + var marker = _ref16.marker; + var markup = _ref16.markup; return post([markupSection('p', [marker('abc'), marker('def', [markup('b')]), marker('ghi')])]); }); @@ -10561,11 +10923,11 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }); test('#hasActiveMarkup returns true for complex markups', function (assert) { - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref14) { - var post = _ref14.post; - var markupSection = _ref14.markupSection; - var marker = _ref14.marker; - var markup = _ref14.markup; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref17) { + var post = _ref17.post; + var markupSection = _ref17.markupSection; + var marker = _ref17.marker; + var markup = _ref17.markup; return post([markupSection('p', [marker('abc '), marker('def', [markup('a', { href: 'http://bustle.com' })]), marker(' ghi')])]); }); @@ -10586,10 +10948,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }); test('#insertText inserts text at cursor position, replacing existing range if non-collapsed', function (assert) { - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref15) { - var post = _ref15.post; - var markupSection = _ref15.markupSection; - var marker = _ref15.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref18) { + var post = _ref18.post; + var markupSection = _ref18.markupSection; + var marker = _ref18.marker; return post([markupSection('p', [marker('b')])]); }); @@ -10612,11 +10974,11 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }); test('#insertText inserts text at cursor position, inheriting active markups', function (assert) { - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref16) { - var post = _ref16.post; - var markupSection = _ref16.markupSection; - var marker = _ref16.marker; - var markup = _ref16.markup; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref19) { + var post = _ref19.post; + var markupSection = _ref19.markupSection; + var marker = _ref19.marker; + var markup = _ref19.markup; return post([markupSection('p', [marker('a'), marker('b', [markup('b')])])]); }); @@ -10636,10 +10998,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor test('#insertText is no-op when editor does not have cursor', function (assert) { var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref17) { - var post = _ref17.post; - var markupSection = _ref17.markupSection; - var marker = _ref17.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref20) { + var post = _ref20.post; + var markupSection = _ref20.markupSection; + var marker = _ref20.marker; expected = post([markupSection('p', [marker('abc')])]); return post([markupSection('p', [marker('abc')])]); @@ -10653,10 +11015,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor test('#insertText when post is blank', function (assert) { var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref18) { - var post = _ref18.post; - var markupSection = _ref18.markupSection; - var marker = _ref18.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref21) { + var post = _ref21.post; + var markupSection = _ref21.markupSection; + var marker = _ref21.marker; expected = post([markupSection('p', [marker('blah blah')])]); return post(); @@ -10679,10 +11041,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor render: function render() {} }; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref19) { - var post = _ref19.post; - var markupSection = _ref19.markupSection; - var marker = _ref19.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref22) { + var post = _ref22.post; + var markupSection = _ref22.markupSection; + var marker = _ref22.marker; return post([markupSection('p', [marker('b')])]); }, { atoms: [atom] }); @@ -10709,10 +11071,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }; var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref20) { - var post = _ref20.post; - var markupSection = _ref20.markupSection; - var marker = _ref20.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref23) { + var post = _ref23.post; + var markupSection = _ref23.markupSection; + var marker = _ref23.marker; expected = post([markupSection('p', [marker('abc')])]); return post([markupSection('p', [marker('abc')])]); @@ -10732,10 +11094,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }; var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref21) { - var post = _ref21.post; - var atom = _ref21.atom; - var markupSection = _ref21.markupSection; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref24) { + var post = _ref24.post; + var atom = _ref24.atom; + var markupSection = _ref24.markupSection; expected = post([markupSection('p', [atom('the-atom', 'THEATOMTEXT')])]); return post(); @@ -10757,8 +11119,8 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor render: function render() {} }; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref22) { - var post = _ref22.post; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref25) { + var post = _ref25.post; return post(); }, { atoms: [atom] }); @@ -10781,10 +11143,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor render: function render() {} }; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref23) { - var post = _ref23.post; - var markupSection = _ref23.markupSection; - var marker = _ref23.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref26) { + var post = _ref26.post; + var markupSection = _ref26.markupSection; + var marker = _ref26.marker; return post([markupSection('p', [marker('b')])]); }, { cards: [card] }); @@ -10825,12 +11187,12 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor render: function render() {} }; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref24) { - var post = _ref24.post; - var markupSection = _ref24.markupSection; - var marker = _ref24.marker; - var listItem = _ref24.listItem; - var listSection = _ref24.listSection; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref27) { + var post = _ref27.post; + var markupSection = _ref27.markupSection; + var marker = _ref27.marker; + var listItem = _ref27.listItem; + var listSection = _ref27.listSection; return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('def')])])]); }, { cards: [card] }); @@ -10850,10 +11212,10 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }; var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref25) { - var post = _ref25.post; - var markupSection = _ref25.markupSection; - var marker = _ref25.marker; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref28) { + var post = _ref28.post; + var markupSection = _ref28.markupSection; + var marker = _ref28.marker; expected = post([markupSection('p', [marker('abc')])]); return post([markupSection('p', [marker('abc')])]); @@ -10873,9 +11235,9 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor }; var expected = undefined; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref26) { - var post = _ref26.post; - var cardSection = _ref26.cardSection; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref29) { + var post = _ref29.post; + var cardSection = _ref29.cardSection; expected = post([cardSection('the-card')]); return post(); @@ -10898,8 +11260,8 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor render: function render() {} }; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref27) { - var post = _ref27.post; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref30) { + var post = _ref30.post; return post(); }, { cards: [card] }); @@ -10922,8 +11284,8 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor render: function render() {} }; - editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref28) { - var post = _ref28.post; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref31) { + var post = _ref31.post; return post(); }, { cards: [card] }); @@ -10937,6 +11299,104 @@ define('tests/unit/editor/editor-test', ['exports', 'mobiledoc-kit/editor/editor assert.positionIsEqual(range.tail, insertedCard.tailPosition(), 'range tail on card tail'); assert.ok(document.activeElement === editorElement, 'editor element retains focus'); }); + + test('#toggleMarkup removes A tag when no attributes given', function (assert) { + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref32) { + var post = _ref32.post; + var markupSection = _ref32.markupSection; + var marker = _ref32.marker; + var markup = _ref32.markup; + + return post([markupSection('p', [marker('^'), marker('link', [markup('a', { href: 'google.com' })]), marker('$')])]); + }); + _testHelpers['default'].dom.selectText(editor, 'link'); + editor.toggleMarkup('a'); + + assert.selectedText('link', 'text "link" still selected'); + assert.ok(editor.hasCursor(), 'editor has cursor'); + assert.hasElement('#editor p:contains(^link$)'); + assert.hasNoElement('#editor a', 'a tag is removed'); + }); + + test('#toggleMarkup adds A tag with attributes', function (assert) { + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref33) { + var post = _ref33.post; + var markupSection = _ref33.markupSection; + var marker = _ref33.marker; + var markup = _ref33.markup; + + return post([markupSection('p', [marker('^link$')])]); + }); + _testHelpers['default'].dom.selectText(editor, 'link'); + editor.toggleMarkup('a', { href: 'google.com' }); + + assert.selectedText('link', 'text "link" still selected'); + assert.ok(editor.hasCursor(), 'editor has cursor'); + assert.hasElement('#editor a:contains(link)'); + assert.hasElement('#editor a[href="google.com"]:contains(link)'); + }); + + test('#toggleMarkup calls #beforeToggleMarkup hooks', function (assert) { + assert.expect(5 * 3 + 2); + + var callbackCount = 0; + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref34) { + var post = _ref34.post; + var markupSection = _ref34.markupSection; + var marker = _ref34.marker; + var markup = _ref34.markup; + + return post([markupSection('p', [marker('^link$')])]); + }); + _testHelpers['default'].dom.selectText(editor, 'link'); + var callback = function callback(_ref35) { + var markup = _ref35.markup; + var range = _ref35.range; + var willAdd = _ref35.willAdd; + + assert.ok(true, 'calls #beforeToggleMarkup'); + assert.equal(markup.tagName, 'a', 'passes markup'); + assert.equal(markup.getAttribute('href'), 'google.com', 'passes markup with attrs'); + assert.ok(!!range, 'passes a range'); + assert.ok(willAdd, 'correct value for willAdd'); + callbackCount++; + }; + + // 3 times + editor.beforeToggleMarkup(callback); + editor.beforeToggleMarkup(callback); + editor.beforeToggleMarkup(callback); + + editor.toggleMarkup('a', { href: 'google.com' }); + assert.equal(callbackCount, 3, 'calls once for each callback'); + assert.hasElement('#editor a[href="google.com"]:contains(link)', 'adds link'); + }); + + test('#toggleMarkup is canceled if #beforeToggleMarkup hook returns false', function (assert) { + assert.expect(2); + editor = _testHelpers['default'].mobiledoc.renderInto(editorElement, function (_ref36) { + var post = _ref36.post; + var markupSection = _ref36.markupSection; + var marker = _ref36.marker; + var markup = _ref36.markup; + + return post([markupSection('p', [marker('^link$')])]); + }); + _testHelpers['default'].dom.selectText(editor, 'link'); + var callback = function callback(_ref37) { + var markup = _ref37.markup; + var range = _ref37.range; + var willAdd = _ref37.willAdd; + + assert.ok(true, 'calls #beforeToggleMarkup'); + return false; + }; + + editor.beforeToggleMarkup(callback); + + editor.toggleMarkup('a', { href: 'google.com' }); + assert.hasNoElement('#editor a', 'not adds link'); + }); }); define('tests/unit/editor/key-commands-test', ['exports', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/utils/keycodes', '../../test-helpers'], function (exports, _mobiledocKitEditorKeyCommands, _mobiledocKitUtilsKey, _mobiledocKitUtilsKeycodes, _testHelpers) { 'use strict'; @@ -10944,6 +11404,24 @@ define('tests/unit/editor/key-commands-test', ['exports', 'mobiledoc-kit/editor/ var _module = _testHelpers['default'].module; var test = _testHelpers['default'].test; + var SPECIAL_KEYS = { + BACKSPACE: _mobiledocKitUtilsKeycodes['default'].BACKSPACE, + TAB: _mobiledocKitUtilsKeycodes['default'].TAB, + ENTER: _mobiledocKitUtilsKeycodes['default'].ENTER, + ESC: _mobiledocKitUtilsKeycodes['default'].ESC, + SPACE: _mobiledocKitUtilsKeycodes['default'].SPACE, + PAGEUP: _mobiledocKitUtilsKeycodes['default'].PAGEUP, + PAGEDOWN: _mobiledocKitUtilsKeycodes['default'].PAGEDOWN, + END: _mobiledocKitUtilsKeycodes['default'].END, + HOME: _mobiledocKitUtilsKeycodes['default'].HOME, + LEFT: _mobiledocKitUtilsKeycodes['default'].LEFT, + UP: _mobiledocKitUtilsKeycodes['default'].UP, + RIGHT: _mobiledocKitUtilsKeycodes['default'].RIGHT, + DOWN: _mobiledocKitUtilsKeycodes['default'].DOWN, + INS: _mobiledocKitUtilsKeycodes['default'].INS, + DEL: _mobiledocKitUtilsKeycodes['default'].DELETE + }; + _module('Unit: Editor key commands'); test('leaves modifier, code and run in place if they exist', function (assert) { @@ -11033,22 +11511,22 @@ define('tests/unit/editor/key-commands-test', ['exports', 'mobiledoc-kit/editor/ }); test('translates uppercase special key names to codes', function (assert) { - Object.keys(_mobiledocKitUtilsKey.SPECIAL_KEYS).forEach(function (name) { + Object.keys(SPECIAL_KEYS).forEach(function (name) { var _buildKeyCommand7 = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)({ str: name.toUpperCase() }); var code = _buildKeyCommand7.code; - assert.equal(code, _mobiledocKitUtilsKey.SPECIAL_KEYS[name], 'translates ' + name + ' string to code'); + assert.equal(code, SPECIAL_KEYS[name], 'translates ' + name + ' string to code'); }); }); test('translates lowercase special key names to codes', function (assert) { - Object.keys(_mobiledocKitUtilsKey.SPECIAL_KEYS).forEach(function (name) { + Object.keys(SPECIAL_KEYS).forEach(function (name) { var _buildKeyCommand8 = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)({ str: name.toLowerCase() }); var code = _buildKeyCommand8.code; - assert.equal(code, _mobiledocKitUtilsKey.SPECIAL_KEYS[name], 'translates ' + name + ' string to code'); + assert.equal(code, SPECIAL_KEYS[name], 'translates ' + name + ' string to code'); }); }); @@ -12052,11 +12530,165 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' assert.equal(tailSection.name, 'listicle-card', 'moveSectionDown is no-op when card is at bottom'); }); - test('#toggleSection changes single section to and from tag name', function (assert) { + test('#setAttribute on empty Mobiledoc does nothing', function (assert) { var post = _testHelpers['default'].postAbstract.build(function (_ref26) { var post = _ref26.post; var markupSection = _ref26.markupSection; + return post([]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].blankRange(); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.setAttribute('text-align', 'center', range); + postEditor.complete(); + + assert.postIsSimilar(postEditor.editor.post, post); + }); + + test('#setAttribute sets attribute of a single section', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref27) { + var post = _ref27.post; + var markupSection = _ref27.markupSection; + + return post([markupSection('p')]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].create(post.sections.head, 0); + + assert.deepEqual(post.sections.head.attributes, {}); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.setAttribute('text-align', 'center', range); + postEditor.complete(); + + assert.deepEqual(post.sections.head.attributes, { + 'data-md-text-align': 'center' + }); + }); + + test('#removeAttribute removes attribute of a single section', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref28) { + var post = _ref28.post; + var markupSection = _ref28.markupSection; + + return post([markupSection('p', [], false, { 'data-md-text-align': 'center' })]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].create(post.sections.head, 0); + + assert.deepEqual(post.sections.head.attributes, { + 'data-md-text-align': 'center' + }); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.removeAttribute('text-align', range); + postEditor.complete(); + + assert.deepEqual(post.sections.head.attributes, {}); + }); + + test('#setAttribute sets attribute of multiple sections', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref29) { + var post = _ref29.post; + var markupSection = _ref29.markupSection; + var marker = _ref29.marker; + var cardSection = _ref29.cardSection; + + return post([markupSection('p', [marker('abc')]), cardSection('my-card'), markupSection('p', [marker('123')])]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].create(post.sections.head, 0, post.sections.tail, 2); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.setAttribute('text-align', 'center', range); + postEditor.complete(); + + assert.deepEqual(post.sections.head.attributes, { + 'data-md-text-align': 'center' + }); + assert.ok(post.sections.objectAt(1).isCardSection); + assert.deepEqual(post.sections.tail.attributes, { + 'data-md-text-align': 'center' + }); + }); + + test('#removeAttribute removes attribute of multiple sections', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref30) { + var post = _ref30.post; + var markupSection = _ref30.markupSection; + var marker = _ref30.marker; + var cardSection = _ref30.cardSection; + + return post([markupSection('p', [marker('abc')], false, { 'data-md-text-align': 'center' }), cardSection('my-card'), markupSection('p', [marker('123')], { 'data-md-text-align': 'left' })]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].create(post.sections.head, 0, post.sections.tail, 2); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.removeAttribute('text-align', range); + postEditor.complete(); + + assert.deepEqual(post.sections.head.attributes, {}); + assert.ok(post.sections.objectAt(1).isCardSection); + assert.deepEqual(post.sections.tail.attributes, {}); + }); + + test('#setAttribute sets attribute of a single list', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref31) { + var post = _ref31.post; + var listSection = _ref31.listSection; + var listItem = _ref31.listItem; + var marker = _ref31.marker; + var markup = _ref31.markup; + + return post([listSection('ul', [listItem([marker('a')]), listItem([marker('def')])])]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].create(post.sections.head.items.head, 0); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.setAttribute('text-align', 'center', range); + postEditor.complete(); + + assert.deepEqual(post.sections.head.attributes, { + 'data-md-text-align': 'center' + }); + }); + + test('#setAttribute when cursor is in non-markerable section changes nothing', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref32) { + var post = _ref32.post; + var markupSection = _ref32.markupSection; + var marker = _ref32.marker; + var cardSection = _ref32.cardSection; + + return post([cardSection('my-card')]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = post.sections.head.headPosition().toRange(); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.setAttribute('text-align', 'center', range); + postEditor.complete(); + + assert.ok(post.sections.head.isCardSection, 'card section not changed'); + assert.positionIsEqual(mockEditor._renderedRange.head, post.sections.head.headPosition()); + }); + + test('#toggleSection changes single section to and from tag name', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref33) { + var post = _ref33.post; + var markupSection = _ref33.markupSection; + return post([markupSection('p')]); }); @@ -12078,10 +12710,10 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection changes multiple sections to and from tag name', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref27) { - var post = _ref27.post; - var markupSection = _ref27.markupSection; - var marker = _ref27.marker; + var post = _testHelpers['default'].postAbstract.build(function (_ref34) { + var post = _ref34.post; + var markupSection = _ref34.markupSection; + var marker = _ref34.marker; return post([markupSection('p', [marker('abc')]), markupSection('p', [marker('123')])]); }); @@ -12103,15 +12735,16 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' assert.equal(post.sections.head.tagName, 'p'); assert.equal(post.sections.tail.tagName, 'p'); - assert.positionIsEqual(mockEditor._renderedRange.head, post.sections.head.headPosition()); + assert.positionIsEqual(mockEditor._renderedRange.head, post.sections.head.toPosition(2), 'Maintains the selection'); + assert.positionIsEqual(mockEditor._renderedRange.tail, post.sections.tail.toPosition(2), 'Maintains the selection'); }); test('#toggleSection skips over non-markerable sections', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref28) { - var post = _ref28.post; - var markupSection = _ref28.markupSection; - var marker = _ref28.marker; - var cardSection = _ref28.cardSection; + var post = _testHelpers['default'].postAbstract.build(function (_ref35) { + var post = _ref35.post; + var markupSection = _ref35.markupSection; + var marker = _ref35.marker; + var cardSection = _ref35.cardSection; return post([markupSection('p', [marker('abc')]), cardSection('my-card'), markupSection('p', [marker('123')])]); }); @@ -12131,11 +12764,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection when cursor is in non-markerable section changes nothing', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref29) { - var post = _ref29.post; - var markupSection = _ref29.markupSection; - var marker = _ref29.marker; - var cardSection = _ref29.cardSection; + var post = _testHelpers['default'].postAbstract.build(function (_ref36) { + var post = _ref36.post; + var markupSection = _ref36.markupSection; + var marker = _ref36.marker; + var cardSection = _ref36.cardSection; return post([cardSection('my-card')]); }); @@ -12155,17 +12788,17 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' assert.expect(6); var done = assert.async(); - editor = buildEditorWithMobiledoc(function (_ref30) { - var post = _ref30.post; - var markupSection = _ref30.markupSection; - var marker = _ref30.marker; + editor = buildEditorWithMobiledoc(function (_ref37) { + var post = _ref37.post; + var markupSection = _ref37.markupSection; + var marker = _ref37.marker; return post([markupSection('p', [marker('abc')])]); }, false); - var expected = _testHelpers['default'].postAbstract.build(function (_ref31) { - var post = _ref31.post; - var markupSection = _ref31.markupSection; - var marker = _ref31.marker; + var expected = _testHelpers['default'].postAbstract.build(function (_ref38) { + var post = _ref38.post; + var markupSection = _ref38.markupSection; + var marker = _ref38.marker; return post([markupSection('p', [marker('abc')])]); }); @@ -12188,11 +12821,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle single p -> list item', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref32) { - var post = _ref32.post; - var markupSection = _ref32.markupSection; - var marker = _ref32.marker; - var markup = _ref32.markup; + var post = _testHelpers['default'].postAbstract.build(function (_ref39) { + var post = _ref39.post; + var markupSection = _ref39.markupSection; + var marker = _ref39.marker; + var markup = _ref39.markup; return post([markupSection('p', [marker('a'), marker('b', [markup('b')]), marker('c')])]); }); @@ -12219,12 +12852,12 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle single list item -> p', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref33) { - var post = _ref33.post; - var listSection = _ref33.listSection; - var listItem = _ref33.listItem; - var marker = _ref33.marker; - var markup = _ref33.markup; + var post = _testHelpers['default'].postAbstract.build(function (_ref40) { + var post = _ref40.post; + var listSection = _ref40.listSection; + var listItem = _ref40.listItem; + var marker = _ref40.marker; + var markup = _ref40.markup; return post([listSection('ul', [listItem([marker('a'), marker('b', [markup('b')]), marker('c')])])]); }); @@ -12249,10 +12882,10 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle multiple ps -> list and list -> multiple ps', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref34) { - var post = _ref34.post; - var markupSection = _ref34.markupSection; - var marker = _ref34.marker; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref41) { + var post = _ref41.post; + var markupSection = _ref41.markupSection; + var marker = _ref41.marker; return post([markupSection('p', [marker('abc')]), markupSection('p', [marker('123')])]); }); @@ -12292,12 +12925,12 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection untoggle first list item changes it to markup section, retains markup', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref35) { - var post = _ref35.post; - var listSection = _ref35.listSection; - var listItem = _ref35.listItem; - var marker = _ref35.marker; - var markup = _ref35.markup; + var post = _testHelpers['default'].postAbstract.build(function (_ref42) { + var post = _ref42.post; + var listSection = _ref42.listSection; + var listItem = _ref42.listItem; + var marker = _ref42.marker; + var markup = _ref42.markup; return post([listSection('ul', [listItem([marker('a'), marker('b', [markup('b')]), marker('c')]), listItem([marker('def')]), listItem([marker('ghi')])])]); }); @@ -12325,12 +12958,12 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection untoggle middle list item changes it to markup section, retaining markup', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref36) { - var post = _ref36.post; - var listSection = _ref36.listSection; - var listItem = _ref36.listItem; - var marker = _ref36.marker; - var markup = _ref36.markup; + var post = _testHelpers['default'].postAbstract.build(function (_ref43) { + var post = _ref43.post; + var listSection = _ref43.listSection; + var listItem = _ref43.listItem; + var marker = _ref43.marker; + var markup = _ref43.markup; return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('d'), marker('e', [markup('b')]), marker('f')]), listItem([marker('ghi')])])]); }); @@ -12361,12 +12994,12 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle markup section -> ul between lists joins the lists', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref37) { - var post = _ref37.post; - var listSection = _ref37.listSection; - var listItem = _ref37.listItem; - var marker = _ref37.marker; - var markupSection = _ref37.markupSection; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref44) { + var post = _ref44.post; + var listSection = _ref44.listSection; + var listItem = _ref44.listItem; + var marker = _ref44.marker; + var markupSection = _ref44.markupSection; return post([listSection('ul', [listItem([marker('abc')])]), markupSection('p', [marker('123')]), listSection('ul', [listItem([marker('def')])])]); }); @@ -12395,11 +13028,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection untoggle multiple items at end of list changes them to markup sections', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref38) { - var post = _ref38.post; - var listSection = _ref38.listSection; - var listItem = _ref38.listItem; - var marker = _ref38.marker; + var post = _testHelpers['default'].postAbstract.build(function (_ref45) { + var post = _ref45.post; + var listSection = _ref45.listSection; + var listItem = _ref45.listItem; + var marker = _ref45.marker; return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('def')]), listItem([marker('ghi')])])]); }); @@ -12424,11 +13057,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection untoggle multiple items at start of list changes them to markup sections', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref39) { - var post = _ref39.post; - var listSection = _ref39.listSection; - var listItem = _ref39.listItem; - var marker = _ref39.marker; + var post = _testHelpers['default'].postAbstract.build(function (_ref46) { + var post = _ref46.post; + var listSection = _ref46.listSection; + var listItem = _ref46.listItem; + var marker = _ref46.marker; return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('def')]), listItem([marker('ghi')])])]); }); @@ -12454,12 +13087,12 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection untoggle items and overflowing markup sections changes the overflow to items', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref40) { - var post = _ref40.post; - var listSection = _ref40.listSection; - var listItem = _ref40.listItem; - var markupSection = _ref40.markupSection; - var marker = _ref40.marker; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref47) { + var post = _ref47.post; + var listSection = _ref47.listSection; + var listItem = _ref47.listItem; + var markupSection = _ref47.markupSection; + var marker = _ref47.marker; return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('def')]), listItem([marker('ghi')])]), markupSection('p', [marker('123')])]); }); @@ -12488,11 +13121,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection untoggle last list item changes it to markup section', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref41) { - var post = _ref41.post; - var listSection = _ref41.listSection; - var listItem = _ref41.listItem; - var marker = _ref41.marker; + var post = _testHelpers['default'].postAbstract.build(function (_ref48) { + var post = _ref48.post; + var listSection = _ref48.listSection; + var listItem = _ref48.listItem; + var marker = _ref48.marker; return post([listSection('ul', [listItem([marker('abc')]), listItem([marker('def')]), listItem([marker('ghi')])])]); }); @@ -12516,11 +13149,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle list item to different type of list item', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref42) { - var post = _ref42.post; - var listSection = _ref42.listSection; - var listItem = _ref42.listItem; - var marker = _ref42.marker; + var post = _testHelpers['default'].postAbstract.build(function (_ref49) { + var post = _ref49.post; + var listSection = _ref49.listSection; + var listItem = _ref49.listItem; + var marker = _ref49.marker; return post([listSection('ul', [listItem([marker('abc')])])]); }); @@ -12542,12 +13175,12 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle list item to different type of list item when other sections precede it', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref43) { - var post = _ref43.post; - var listSection = _ref43.listSection; - var listItem = _ref43.listItem; - var marker = _ref43.marker; - var markupSection = _ref43.markupSection; + var post = _testHelpers['default'].postAbstract.build(function (_ref50) { + var post = _ref50.post; + var listSection = _ref50.listSection; + var listItem = _ref50.listItem; + var marker = _ref50.marker; + var markupSection = _ref50.markupSection; return post([markupSection('p', [marker('123')]), listSection('ul', [listItem([marker('abc')])])]); }); @@ -12571,9 +13204,9 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection toggle when cursor on card section is no-op', function (assert) { - var post = _testHelpers['default'].postAbstract.build(function (_ref44) { - var post = _ref44.post; - var cardSection = _ref44.cardSection; + var post = _testHelpers['default'].postAbstract.build(function (_ref51) { + var post = _ref51.post; + var cardSection = _ref51.cardSection; return post([cardSection('my-card')]); }); @@ -12593,11 +13226,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleSection joins contiguous list items', function (assert) { - var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref45) { - var post = _ref45.post; - var listSection = _ref45.listSection; - var listItem = _ref45.listItem; - var marker = _ref45.marker; + var mobiledoc = _testHelpers['default'].mobiledoc.build(function (_ref52) { + var post = _ref52.post; + var listSection = _ref52.listSection; + var listItem = _ref52.listItem; + var marker = _ref52.marker; return post([listSection('ul', [listItem([marker('abc')])]), listSection('ol', [listItem([marker('123')])]), listSection('ul', [listItem([marker('def')])])]); }); @@ -12620,12 +13253,32 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }), ['abc', '123', 'def']); }); + test('#toggleSection maintains the selection when the sections in the selected range are still there', function (assert) { + var post = _testHelpers['default'].postAbstract.build(function (_ref53) { + var post = _ref53.post; + var markupSection = _ref53.markupSection; + var marker = _ref53.marker; + + return post([markupSection('p', [marker('abc')])]); + }); + + mockEditor = renderBuiltAbstract(post, mockEditor); + var range = _mobiledocKitUtilsCursorRange['default'].create(post.sections.head, 1, post.sections.head, 2); + + postEditor = new _mobiledocKitEditorPost['default'](mockEditor); + postEditor.toggleSection('h1', range); + postEditor.complete(); + + assert.positionIsEqual(mockEditor._renderedRange.head, post.sections.head.toPosition(1), 'Maintains the selection'); + assert.positionIsEqual(mockEditor._renderedRange.tail, post.sections.tail.toPosition(2), 'Maintains the selection'); + }); + test('#toggleMarkup when cursor is in non-markerable does nothing', function (assert) { - editor = buildEditorWithMobiledoc(function (_ref46) { - var post = _ref46.post; - var markupSection = _ref46.markupSection; - var marker = _ref46.marker; - var cardSection = _ref46.cardSection; + editor = buildEditorWithMobiledoc(function (_ref54) { + var post = _ref54.post; + var markupSection = _ref54.markupSection; + var marker = _ref54.marker; + var cardSection = _ref54.cardSection; return post([cardSection('my-card')]); }); @@ -12640,11 +13293,11 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleMarkup when cursor surrounds non-markerable does nothing', function (assert) { - editor = buildEditorWithMobiledoc(function (_ref47) { - var post = _ref47.post; - var markupSection = _ref47.markupSection; - var marker = _ref47.marker; - var cardSection = _ref47.cardSection; + editor = buildEditorWithMobiledoc(function (_ref55) { + var post = _ref55.post; + var markupSection = _ref55.markupSection; + var marker = _ref55.marker; + var cardSection = _ref55.cardSection; return post([cardSection('my-card')]); }); @@ -12659,18 +13312,18 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleMarkup when range has the markup removes it', function (assert) { - editor = buildEditorWithMobiledoc(function (_ref48) { - var post = _ref48.post; - var markupSection = _ref48.markupSection; - var marker = _ref48.marker; - var markup = _ref48.markup; + editor = buildEditorWithMobiledoc(function (_ref56) { + var post = _ref56.post; + var markupSection = _ref56.markupSection; + var marker = _ref56.marker; + var markup = _ref56.markup; return post([markupSection('p', [marker('abc', [markup('b')])])]); }); - var expected = _testHelpers['default'].postAbstract.build(function (_ref49) { - var post = _ref49.post; - var markupSection = _ref49.markupSection; - var marker = _ref49.marker; + var expected = _testHelpers['default'].postAbstract.build(function (_ref57) { + var post = _ref57.post; + var markupSection = _ref57.markupSection; + var marker = _ref57.marker; return post([markupSection('p', [marker('abc')])]); }); @@ -12686,18 +13339,18 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleMarkup when only some of the range has it removes it', function (assert) { - editor = buildEditorWithMobiledoc(function (_ref50) { - var post = _ref50.post; - var markupSection = _ref50.markupSection; - var marker = _ref50.marker; - var markup = _ref50.markup; + editor = buildEditorWithMobiledoc(function (_ref58) { + var post = _ref58.post; + var markupSection = _ref58.markupSection; + var marker = _ref58.marker; + var markup = _ref58.markup; return post([markupSection('p', [marker('a'), marker('b', [markup('b')]), marker('c')])]); }); - var expected = _testHelpers['default'].postAbstract.build(function (_ref51) { - var post = _ref51.post; - var markupSection = _ref51.markupSection; - var marker = _ref51.marker; + var expected = _testHelpers['default'].postAbstract.build(function (_ref59) { + var post = _ref59.post; + var markupSection = _ref59.markupSection; + var marker = _ref59.marker; return post([markupSection('p', [marker('abc')])]); }); @@ -12713,18 +13366,18 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#toggleMarkup when range does not have the markup adds it', function (assert) { - editor = buildEditorWithMobiledoc(function (_ref52) { - var post = _ref52.post; - var markupSection = _ref52.markupSection; - var marker = _ref52.marker; + editor = buildEditorWithMobiledoc(function (_ref60) { + var post = _ref60.post; + var markupSection = _ref60.markupSection; + var marker = _ref60.marker; return post([markupSection('p', [marker('abc')])]); }); - var expected = _testHelpers['default'].postAbstract.build(function (_ref53) { - var post = _ref53.post; - var markupSection = _ref53.markupSection; - var marker = _ref53.marker; - var markup = _ref53.markup; + var expected = _testHelpers['default'].postAbstract.build(function (_ref61) { + var post = _ref61.post; + var markupSection = _ref61.markupSection; + var marker = _ref61.marker; + var markup = _ref61.markup; return post([markupSection('p', [marker('abc', [markup('b')])])]); }); @@ -12742,17 +13395,17 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#toggleMarkup when the editor has no cursor', function (assert) { var done = assert.async(); - editor = buildEditorWithMobiledoc(function (_ref54) { - var post = _ref54.post; - var markupSection = _ref54.markupSection; - var marker = _ref54.marker; + editor = buildEditorWithMobiledoc(function (_ref62) { + var post = _ref62.post; + var markupSection = _ref62.markupSection; + var marker = _ref62.marker; return post([markupSection('p', [marker('abc')])]); }, false); - var expected = _testHelpers['default'].postAbstract.build(function (_ref55) { - var post = _ref55.post; - var markupSection = _ref55.markupSection; - var marker = _ref55.marker; + var expected = _testHelpers['default'].postAbstract.build(function (_ref63) { + var post = _ref63.post; + var markupSection = _ref63.markupSection; + var marker = _ref63.marker; return post([markupSection('p', [marker('abc')])]); }); @@ -12775,21 +13428,21 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertMarkers inserts an atom', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref56) { - var post = _ref56.post; - var markupSection = _ref56.markupSection; - var marker = _ref56.marker; - var markup = _ref56.markup; - var atom = _ref56.atom; + _testHelpers['default'].postAbstract.build(function (_ref64) { + var post = _ref64.post; + var markupSection = _ref64.markupSection; + var marker = _ref64.marker; + var markup = _ref64.markup; + var atom = _ref64.atom; toInsert = [atom('simple-atom', '123', [markup('b')])]; expected = post([markupSection('p', [marker('abc'), atom('simple-atom', '123', [markup('b')]), marker('def')])]); }); - editor = buildEditorWithMobiledoc(function (_ref57) { - var post = _ref57.post; - var markupSection = _ref57.markupSection; - var marker = _ref57.marker; + editor = buildEditorWithMobiledoc(function (_ref65) { + var post = _ref65.post; + var markupSection = _ref65.markupSection; + var marker = _ref65.marker; return post([markupSection('p', [marker('abcdef')])]); }); @@ -12806,20 +13459,20 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertMarkers inserts the markers in middle, merging markups', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref58) { - var post = _ref58.post; - var markupSection = _ref58.markupSection; - var marker = _ref58.marker; - var markup = _ref58.markup; + _testHelpers['default'].postAbstract.build(function (_ref66) { + var post = _ref66.post; + var markupSection = _ref66.markupSection; + var marker = _ref66.marker; + var markup = _ref66.markup; toInsert = [marker('123', [markup('b')]), marker('456')]; expected = post([markupSection('p', [marker('abc'), marker('123', [markup('b')]), marker('456def')])]); }); - editor = buildEditorWithMobiledoc(function (_ref59) { - var post = _ref59.post; - var markupSection = _ref59.markupSection; - var marker = _ref59.marker; + editor = buildEditorWithMobiledoc(function (_ref67) { + var post = _ref67.post; + var markupSection = _ref67.markupSection; + var marker = _ref67.marker; return post([markupSection('p', [marker('abcdef')])]); }); @@ -12836,19 +13489,19 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertMarkers inserts the markers when the markerable has no markers', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref60) { - var post = _ref60.post; - var markupSection = _ref60.markupSection; - var marker = _ref60.marker; - var markup = _ref60.markup; + _testHelpers['default'].postAbstract.build(function (_ref68) { + var post = _ref68.post; + var markupSection = _ref68.markupSection; + var marker = _ref68.marker; + var markup = _ref68.markup; toInsert = [marker('123', [markup('b')]), marker('456')]; expected = post([markupSection('p', [marker('123', [markup('b')]), marker('456')])]); }); - editor = buildEditorWithMobiledoc(function (_ref61) { - var post = _ref61.post; - var markupSection = _ref61.markupSection; + editor = buildEditorWithMobiledoc(function (_ref69) { + var post = _ref69.post; + var markupSection = _ref69.markupSection; return post([markupSection()]); }); @@ -12865,20 +13518,20 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertMarkers inserts the markers at start', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref62) { - var post = _ref62.post; - var markupSection = _ref62.markupSection; - var marker = _ref62.marker; - var markup = _ref62.markup; + _testHelpers['default'].postAbstract.build(function (_ref70) { + var post = _ref70.post; + var markupSection = _ref70.markupSection; + var marker = _ref70.marker; + var markup = _ref70.markup; toInsert = [marker('123', [markup('b')]), marker('456')]; expected = post([markupSection('p', [marker('123', [markup('b')]), marker('456abc')])]); }); - editor = buildEditorWithMobiledoc(function (_ref63) { - var post = _ref63.post; - var markupSection = _ref63.markupSection; - var marker = _ref63.marker; + editor = buildEditorWithMobiledoc(function (_ref71) { + var post = _ref71.post; + var markupSection = _ref71.markupSection; + var marker = _ref71.marker; return post([markupSection('p', [marker('abc')])]); }); @@ -12895,20 +13548,20 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertMarkers inserts the markers at end', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref64) { - var post = _ref64.post; - var markupSection = _ref64.markupSection; - var marker = _ref64.marker; - var markup = _ref64.markup; + _testHelpers['default'].postAbstract.build(function (_ref72) { + var post = _ref72.post; + var markupSection = _ref72.markupSection; + var marker = _ref72.marker; + var markup = _ref72.markup; toInsert = [marker('123', [markup('b')]), marker('456')]; expected = post([markupSection('p', [marker('abc'), marker('123', [markup('b')]), marker('456')])]); }); - editor = buildEditorWithMobiledoc(function (_ref65) { - var post = _ref65.post; - var markupSection = _ref65.markupSection; - var marker = _ref65.marker; + editor = buildEditorWithMobiledoc(function (_ref73) { + var post = _ref73.post; + var markupSection = _ref73.markupSection; + var marker = _ref73.marker; return post([markupSection('p', [marker('abc')])]); }); @@ -12924,18 +13577,18 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertMarkers throws if the position is not markerable', function (assert) { var toInsert = undefined; - _testHelpers['default'].postAbstract.build(function (_ref66) { - var post = _ref66.post; - var markupSection = _ref66.markupSection; - var marker = _ref66.marker; - var markup = _ref66.markup; + _testHelpers['default'].postAbstract.build(function (_ref74) { + var post = _ref74.post; + var markupSection = _ref74.markupSection; + var marker = _ref74.marker; + var markup = _ref74.markup; toInsert = [marker('123', [markup('b')]), marker('456')]; }); - editor = buildEditorWithMobiledoc(function (_ref67) { - var post = _ref67.post; - var cardSection = _ref67.cardSection; + editor = buildEditorWithMobiledoc(function (_ref75) { + var post = _ref75.post; + var cardSection = _ref75.cardSection; return post([cardSection('some-card')]); }); @@ -12949,15 +13602,15 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertText is no-op if the position section is not markerable', function (assert) { var toInsert = '123'; - var expected = _testHelpers['default'].postAbstract.build(function (_ref68) { - var post = _ref68.post; - var cardSection = _ref68.cardSection; + var expected = _testHelpers['default'].postAbstract.build(function (_ref76) { + var post = _ref76.post; + var cardSection = _ref76.cardSection; return post([cardSection('test-card')]); }); - editor = buildEditorWithMobiledoc(function (_ref69) { - var post = _ref69.post; - var cardSection = _ref69.cardSection; + editor = buildEditorWithMobiledoc(function (_ref77) { + var post = _ref77.post; + var cardSection = _ref77.cardSection; return post([cardSection('test-card')]); }); @@ -12974,21 +13627,21 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertText inserts the text at start', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref70) { - var post = _ref70.post; - var markupSection = _ref70.markupSection; - var marker = _ref70.marker; - var markup = _ref70.markup; + _testHelpers['default'].postAbstract.build(function (_ref78) { + var post = _ref78.post; + var markupSection = _ref78.markupSection; + var marker = _ref78.marker; + var markup = _ref78.markup; toInsert = '123'; expected = post([markupSection('p', [marker('123abc', [markup('b')])])]); }); - editor = buildEditorWithMobiledoc(function (_ref71) { - var post = _ref71.post; - var markupSection = _ref71.markupSection; - var marker = _ref71.marker; - var markup = _ref71.markup; + editor = buildEditorWithMobiledoc(function (_ref79) { + var post = _ref79.post; + var markupSection = _ref79.markupSection; + var marker = _ref79.marker; + var markup = _ref79.markup; return post([markupSection('p', [marker('abc', [markup('b')])])]); }); @@ -13005,21 +13658,21 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertText inserts text in the middle', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref72) { - var post = _ref72.post; - var markupSection = _ref72.markupSection; - var marker = _ref72.marker; - var markup = _ref72.markup; + _testHelpers['default'].postAbstract.build(function (_ref80) { + var post = _ref80.post; + var markupSection = _ref80.markupSection; + var marker = _ref80.marker; + var markup = _ref80.markup; toInsert = '123'; expected = post([markupSection('p', [marker('ab123c', [markup('b')])])]); }); - editor = buildEditorWithMobiledoc(function (_ref73) { - var post = _ref73.post; - var markupSection = _ref73.markupSection; - var marker = _ref73.marker; - var markup = _ref73.markup; + editor = buildEditorWithMobiledoc(function (_ref81) { + var post = _ref81.post; + var markupSection = _ref81.markupSection; + var marker = _ref81.marker; + var markup = _ref81.markup; return post([markupSection('p', [marker('abc', [markup('b')])])]); }); @@ -13036,21 +13689,21 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' test('#insertText inserts text at the end', function (assert) { var toInsert = undefined, expected = undefined; - _testHelpers['default'].postAbstract.build(function (_ref74) { - var post = _ref74.post; - var markupSection = _ref74.markupSection; - var marker = _ref74.marker; - var markup = _ref74.markup; + _testHelpers['default'].postAbstract.build(function (_ref82) { + var post = _ref82.post; + var markupSection = _ref82.markupSection; + var marker = _ref82.marker; + var markup = _ref82.markup; toInsert = '123'; expected = post([markupSection('p', [marker('abc123', [markup('b')])])]); }); - editor = buildEditorWithMobiledoc(function (_ref75) { - var post = _ref75.post; - var markupSection = _ref75.markupSection; - var marker = _ref75.marker; - var markup = _ref75.markup; + editor = buildEditorWithMobiledoc(function (_ref83) { + var post = _ref83.post; + var markupSection = _ref83.markupSection; + var marker = _ref83.marker; + var markup = _ref83.markup; return post([markupSection('p', [marker('abc', [markup('b')])])]); }); @@ -13065,21 +13718,21 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#_splitListItem creates two list items', function (assert) { - var expected = _testHelpers['default'].postAbstract.build(function (_ref76) { - var post = _ref76.post; - var listSection = _ref76.listSection; - var listItem = _ref76.listItem; - var marker = _ref76.marker; - var markup = _ref76.markup; + var expected = _testHelpers['default'].postAbstract.build(function (_ref84) { + var post = _ref84.post; + var listSection = _ref84.listSection; + var listItem = _ref84.listItem; + var marker = _ref84.marker; + var markup = _ref84.markup; return post([listSection('ul', [listItem([marker('abc'), marker('bo', [markup('b')])]), listItem([marker('ld', [markup('b')])])])]); }); - editor = buildEditorWithMobiledoc(function (_ref77) { - var post = _ref77.post; - var listSection = _ref77.listSection; - var listItem = _ref77.listItem; - var marker = _ref77.marker; - var markup = _ref77.markup; + editor = buildEditorWithMobiledoc(function (_ref85) { + var post = _ref85.post; + var listSection = _ref85.listSection; + var listItem = _ref85.listItem; + var marker = _ref85.marker; + var markup = _ref85.markup; return post([listSection('ul', [listItem([marker('abc'), marker('bold', [markup('b')])])])]); }); @@ -13095,19 +13748,19 @@ define('tests/unit/editor/post-test', ['exports', 'mobiledoc-kit/editor/post', ' }); test('#_splitListItem when position is start creates blank list item', function (assert) { - var expected = _testHelpers['default'].postAbstract.build(function (_ref78) { - var post = _ref78.post; - var listSection = _ref78.listSection; - var listItem = _ref78.listItem; - var marker = _ref78.marker; + var expected = _testHelpers['default'].postAbstract.build(function (_ref86) { + var post = _ref86.post; + var listSection = _ref86.listSection; + var listItem = _ref86.listItem; + var marker = _ref86.marker; return post([listSection('ul', [listItem([marker('')]), listItem([marker('abc')])])]); }); - editor = buildEditorWithMobiledoc(function (_ref79) { - var post = _ref79.post; - var listSection = _ref79.listSection; - var listItem = _ref79.listItem; - var marker = _ref79.marker; + editor = buildEditorWithMobiledoc(function (_ref87) { + var post = _ref87.post; + var listSection = _ref87.listSection; + var listItem = _ref87.listItem; + var marker = _ref87.marker; return post([listSection('ul', [listItem([marker('abc')])])]); }); @@ -13426,6 +14079,12 @@ define('tests/unit/models/card-test', ['exports', '../../test-helpers', 'mobiled card.payload.foo = 'other foo'; assert.equal(card2.payload.foo, 'bar', 'card2 payload not updated'); }); + + test('card cannot have attributes', function (assert) { + var card = builder.createCardSection('card-name'); + + assert.equal(card.attributes, undefined); + }); }); define('tests/unit/models/lifecycle-callbacks-test', ['exports', '../../test-helpers', 'mobiledoc-kit/models/lifecycle-callbacks'], function (exports, _testHelpers, _mobiledocKitModelsLifecycleCallbacks) { 'use strict'; @@ -13524,7 +14183,7 @@ define('tests/unit/models/lifecycle-callbacks-test', ['exports', '../../test-hel assert.equal(calledOnce, 1, 'runs one-time callback only once'); }); }); -define('tests/unit/models/list-section-test', ['exports', 'mobiledoc-kit/models/post-node-builder', '../../test-helpers'], function (exports, _mobiledocKitModelsPostNodeBuilder, _testHelpers) { +define('tests/unit/models/list-section-test', ['exports', 'mobiledoc-kit/models/post-node-builder', '../../test-helpers', '../../helpers/sections'], function (exports, _mobiledocKitModelsPostNodeBuilder, _testHelpers, _helpersSections) { 'use strict'; var _module = _testHelpers['default'].module; @@ -13540,14 +14199,37 @@ define('tests/unit/models/list-section-test', ['exports', 'mobiledoc-kit/models/ } }); - test('cloning a list section creates the same type of list section', function (assert) { - var item = builder.createListItem([builder.createMarker('abc')]); - var list = builder.createListSection('ol', [item]); - var cloned = list.clone(); + _helpersSections.VALID_ATTRIBUTES.forEach(function (attribute) { + // eslint-disable-next-line no-loop-func + test('a section can have attribute "' + attribute.key + '" with value "' + attribute.value, function (assert) { + var attributes = {}; + attributes[attribute.key] = attribute.value; + + var s1 = builder.createListSection('ol', [], attributes); + assert.deepEqual(s1.attributes, attributes, 'Attribute set at instantiation'); + }); + }); + + _helpersSections.INVALID_ATTRIBUTES.forEach(function (attribute) { + // eslint-disable-next-line no-loop-func + test('a section throws when invalid attribute "' + attribute.key + '" is passed to a marker', function (assert) { + var attributes = {}; + attributes[attribute.key] = attribute.value; + + assert.throws(function () { + builder.createListSection('ul', [], attributes); + }); + }); + + test('cloning a list section creates the same type of list section', function (assert) { + var item = builder.createListItem([builder.createMarker('abc')]); + var list = builder.createListSection('ol', [item]); + var cloned = list.clone(); - assert.equal(list.tagName, cloned.tagName); - assert.equal(list.items.length, cloned.items.length); - assert.equal(list.items.head.text, cloned.items.head.text); + assert.equal(list.tagName, cloned.tagName); + assert.equal(list.items.length, cloned.items.length); + assert.equal(list.items.head.text, cloned.items.head.text); + }); }); }); define('tests/unit/models/marker-test', ['exports', '../../test-helpers', 'mobiledoc-kit/models/post-node-builder'], function (exports, _testHelpers, _mobiledocKitModelsPostNodeBuilder) { @@ -13686,9 +14368,11 @@ define('tests/unit/models/marker-test', ['exports', '../../test-helpers', 'mobil assert.equal(marker.value, 'monkey ', 'deletes correctly from high surrogate'); }); }); -define('tests/unit/models/markup-section-test', ['exports', 'mobiledoc-kit/models/post-node-builder', '../../test-helpers', 'mobiledoc-kit/utils/cursor/position'], function (exports, _mobiledocKitModelsPostNodeBuilder, _testHelpers, _mobiledocKitUtilsCursorPosition) { +define('tests/unit/models/markup-section-test', ['exports', 'mobiledoc-kit/models/post-node-builder', '../../test-helpers', 'mobiledoc-kit/utils/cursor/position', '../../helpers/sections'], function (exports, _mobiledocKitModelsPostNodeBuilder, _testHelpers, _mobiledocKitUtilsCursorPosition, _helpersSections) { 'use strict'; + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + var _module = _testHelpers['default'].module; var test = _testHelpers['default'].test; @@ -13710,6 +14394,23 @@ define('tests/unit/models/markup-section-test', ['exports', 'mobiledoc-kit/model assert.equal(s1.markers.length, 1); }); + _helpersSections.VALID_ATTRIBUTES.forEach(function (attribute) { + // eslint-disable-next-line no-loop-func + test('a section can have attribute "' + attribute.key + '" with value "' + attribute.value, function (assert) { + var s1 = builder.createMarkupSection('P', [], false, _defineProperty({}, attribute.key, attribute.value)); + assert.deepEqual(s1.attributes, _defineProperty({}, attribute.key, attribute.value), 'Attribute set at instantiation'); + }); + }); + + _helpersSections.INVALID_ATTRIBUTES.forEach(function (attribute) { + // eslint-disable-next-line no-loop-func + test('a section throws when invalid attribute "' + attribute.key + '" is passed to a marker', function (assert) { + assert.throws(function () { + builder.createMarkupSection('P', [], false, attribute); + }); + }); + }); + test('#isBlank returns true if the text length is zero for two markers', function (assert) { var m1 = builder.createMarker(''); var m2 = builder.createMarker(''); @@ -14652,7 +15353,7 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' var expectations = [['

    some text

    ', ['some text']], ['

    some text

    some other text

    ', ['some text', 'some other text']], ['

    some  text   for    you

    ', ['some text for you']], ['

    a b

    ', ['a' + _mobiledocKitUtilsCharacters.TAB + 'b']], // multiple ps, with and without adjacent text nodes - ['

    first line

    \n

    second line

    ', ['first line', 'second line']], ['

    first line

    middle line

    third line

    ', ['first line', 'middle line', 'third line']], ['

    first line

    second line', ['first line', 'second line']], ['bold text', ['*bold text*']], + ['

    first line

    \n

    second line

    ', ['first line', 'second line']], ['

    first line

    middle line

    third line

    ', ['first line', 'middle line', 'third line']], ['

    first line

    second line', ['first line', 'second line']], ['

    first line

    third line

    ', ['first line', 'third line']], ['bold text', ['*bold text*']], // unrecognized tags ['

    beforespanafter

    ', ['beforespanafter']], ['

    inner

    ', ['inner']], @@ -14667,7 +15368,11 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' ['
    • first element
      • nested element
    ', ['* first element', '* nested element']], // See https://github.com/bustle/mobiledoc-kit/issues/333 - ['abc\ndef', ['abcdef']]]; + ['abc\ndef', ['abc def']]]; + + var structures = [ + // See https://github.com/bustle/mobiledoc-kit/issues/648 + ['

    first

    second

    ', ['first', 'second'], 'one level'], ['

    first

    second

    ', ['first', 'second'], 'two levels'], ['

    first

    second

    ', ['first', 'second'], 'three levels'], ['

    first

    second

    ', ['first', 'second'], 'offset left'], ['

    first

    second

    ', ['first', 'second'], 'offset right']]; expectations.forEach(function (_ref2) { var _ref22 = _slicedToArray(_ref2, 2); @@ -14686,12 +15391,30 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' }); }); + structures.forEach(function (_ref3) { + var _ref32 = _slicedToArray(_ref3, 3); + + var html = _ref32[0]; + var dslText = _ref32[1]; + var name = _ref32[2]; + + test('wrapped#parse ' + html + ' -> ' + dslText + ' (' + name + ')', function (assert) { + var post = parser.parse(buildDOM(html)); + + var _buildFromText2 = buildFromText(dslText); + + var expected = _buildFromText2.post; + + assert.postIsSimilar(post, expected); + }); + }); + test('editor#parse fixes text in atom headTextNode when atom is at start of section', function (assert) { var done = assert.async(); - var _buildFromText2 = buildFromText(['X@("name": "mention", "value": "bob")']); + var _buildFromText3 = buildFromText(['X@("name": "mention", "value": "bob")']); - var expected = _buildFromText2.post; + var expected = _buildFromText3.post; editor = _testHelpers['default'].editor.buildFromText('@("name": "mention", "value": "bob")', editorOpts); @@ -14711,9 +15434,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' test('editor#parse fixes text in atom headTextNode when atom has atom before it', function (assert) { var done = assert.async(); - var _buildFromText3 = buildFromText('@("name": "mention", "value": "first")X@("name": "mention", "value": "last")'); + var _buildFromText4 = buildFromText('@("name": "mention", "value": "first")X@("name": "mention", "value": "last")'); - var expected = _buildFromText3.post; + var expected = _buildFromText4.post; editor = _testHelpers['default'].editor.buildFromText('@("name": "mention", "value": "first")@("name": "mention", "value": "last")', editorOpts); @@ -14731,9 +15454,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' test('editor#parse fixes text in atom headTextNode when atom has marker before it', function (assert) { var done = assert.async(); - var _buildFromText4 = buildFromText('textX@("name":"mention","value":"bob")'); + var _buildFromText5 = buildFromText('textX@("name":"mention","value":"bob")'); - var expected = _buildFromText4.post; + var expected = _buildFromText5.post; editor = _testHelpers['default'].editor.buildFromText('text@("name":"mention","value":"bob")', editorOpts); @@ -14751,9 +15474,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' test('editor#parse fixes text in atom tailTextNode when atom is at end of section', function (assert) { var done = assert.async(); - var _buildFromText5 = buildFromText('@("name":"mention","value":"bob")X'); + var _buildFromText6 = buildFromText('@("name":"mention","value":"bob")X'); - var expected = _buildFromText5.post; + var expected = _buildFromText6.post; editor = _testHelpers['default'].editor.buildFromText('@("name":"mention","value":"bob")', editorOpts); @@ -14771,9 +15494,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' test('editor#parse fixes text in atom tailTextNode when atom has atom after it', function (assert) { var done = assert.async(); - var _buildFromText6 = buildFromText('@("name":"mention","value":"first")X@("name":"mention","value":"last")'); + var _buildFromText7 = buildFromText('@("name":"mention","value":"first")X@("name":"mention","value":"last")'); - var expected = _buildFromText6.post; + var expected = _buildFromText7.post; editor = _testHelpers['default'].editor.buildFromText('@("name":"mention","value":"first")@("name":"mention","value":"last")', editorOpts); @@ -14791,9 +15514,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' test('editor#parse fixes text in atom tailTextNode when atom has marker after it', function (assert) { var done = assert.async(); - var _buildFromText7 = buildFromText('@("name":"mention","value":"bob")Xabc'); + var _buildFromText8 = buildFromText('@("name":"mention","value":"bob")Xabc'); - var expected = _buildFromText7.post; + var expected = _buildFromText8.post; editor = _testHelpers['default'].editor.buildFromText('@("name":"mention","value":"bob")abc', editorOpts); @@ -14820,9 +15543,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' var element = container.firstChild; var post = parser.parse(element); - var _buildFromText8 = buildFromText('plain text'); + var _buildFromText9 = buildFromText('plain text'); - var expected = _buildFromText8.post; + var expected = _buildFromText9.post; assert.postIsSimilar(post, expected); }); @@ -14852,6 +15575,31 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' assert.ok(!m2.hasMarkup('em'), 'm1 is not em'); }); + test('wrapped strong tag + em + text node creates section', function (assert) { + var element = buildDOM('
    stray markup tags
    '); + var post = parser.parse(element); + + assert.equal(post.sections.length, 1, 'parse 1 section'); + assert.equal(post.sections.objectAt(0).text, 'stray markup tags'); + + var markers = post.sections.objectAt(0).markers.toArray(); + assert.equal(markers.length, 2, '2 markers'); + + var _markers2 = _slicedToArray(markers, 2); + + var m1 = _markers2[0]; + var m2 = _markers2[1]; + + assert.equal(m1.value, 'stray'); + assert.equal(m2.value, ' markup tags'); + + assert.ok(m1.hasMarkup('b'), 'm1 is b'); + assert.ok(m1.hasMarkup('em'), 'm1 is em'); + + assert.ok(m2.hasMarkup('b'), 'm2 is b'); + assert.ok(!m2.hasMarkup('em'), 'm1 is not em'); + }); + test('link (A tag) is parsed', function (assert) { var url = 'http://bustle.com', rel = 'nofollow'; @@ -14864,9 +15612,9 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' var markers = post.sections.objectAt(0).markers.toArray(); assert.equal(markers.length, 1, '1 marker'); - var _markers2 = _slicedToArray(markers, 1); + var _markers3 = _slicedToArray(markers, 1); - var marker = _markers2[0]; + var marker = _markers3[0]; assert.equal(marker.value, 'link'); assert.ok(marker.hasMarkup('a'), 'has A markup'); @@ -14956,25 +15704,57 @@ define('tests/unit/parsers/dom-test', ['exports', 'mobiledoc-kit/parsers/dom', ' assert.equal(section.items.objectAt(1).text, 'second element'); }); - /* - * FIXME: Google docs nests uls like this - test('lis in nested uls are flattened (when ul is child of ul)', (assert) => { - let element= buildDOM(` -
      -
    • outer
    • -
      • inner
      -
    - `); - const post = parser.parse(element); - + test('nested html doesn\'t create unneccessary whitespace', function (assert) { + var element = buildDOM('\n
    \n

    \n One\n

    \n

    \n Two\n

    \n
    \n '); + var post = parser.parse(element); + + assert.equal(post.sections.length, 2, '2 sections'); + assert.equal(post.sections.objectAt(0).text, 'One'); + assert.equal(post.sections.objectAt(1).text, 'Two'); + }); + + // Google docs nests uls like this + test('lis in nested uls are flattened (when ul is child of ul)', function (assert) { + var element = buildDOM('\n
      \n
    • outer
    • \n
      • inner
      \n
    \n '); + var post = parser.parse(element); + assert.equal(post.sections.length, 1, '1 section'); - let section = post.sections.objectAt(0); + var section = post.sections.objectAt(0); assert.equal(section.tagName, 'ul'); assert.equal(section.items.length, 2, '2 items'); assert.equal(section.items.objectAt(0).text, 'outer'); assert.equal(section.items.objectAt(1).text, 'inner'); }); - */ + + test('#appendSection does not skip sections containing a single atom with no text value', function (assert) { + var options = { + plugins: [function (node, builder, _ref4) { + var addMarkerable = _ref4.addMarkerable; + var nodeFinished = _ref4.nodeFinished; + + if (node.nodeType !== 1 || node.tagName !== 'BR') { + return; + } + + var softReturn = builder.createAtom('soft-return'); + addMarkerable(softReturn); + + nodeFinished(); + }] + }; + parser = new _mobiledocKitParsersDom['default'](builder, options); + + var element = buildDOM('Testing
    Atoms'); + var post = parser.parse(element); + + assert.equal(post.sections.length, 1, '1 section'); + var section = post.sections.objectAt(0); + assert.equal(section.tagName, 'p'); + assert.equal(section.markers.length, 3, '3 markers'); + assert.equal(section.markers.objectAt(0).value, 'Testing'); + assert.equal(section.markers.objectAt(1).name, 'soft-return'); + assert.equal(section.markers.objectAt(2).value, 'Atoms'); + }); }); define('tests/unit/parsers/html-google-docs-test', ['exports', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/models/post-node-builder', '../../test-helpers', '../../fixtures/google-docs', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/models/types'], function (exports, _mobiledocKitParsersHtml, _mobiledocKitModelsPostNodeBuilder, _testHelpers, _fixturesGoogleDocs, _mobiledocKitUtilsArrayUtils, _mobiledocKitModelsTypes) { 'use strict'; @@ -15191,7 +15971,18 @@ define('tests/unit/parsers/html-test', ['exports', 'mobiledoc-kit/parsers/html', return new _mobiledocKitParsersHtml['default'](builder, options).parse(html); } - _module('Unit: Parser: HTMLParser'); + var didParseVideo = undefined; + function videoParserPlugin(node) { + if (node.tagName === 'VIDEO') { + didParseVideo = true; + } + } + + _module('Unit: Parser: HTMLParser', { + beforeEach: function beforeEach() { + didParseVideo = false; + } + }); test('style tags are ignored', function (assert) { // This is the html you get when copying a message from Slack's desktop app @@ -15210,16 +16001,66 @@ define('tests/unit/parsers/html-test', ['exports', 'mobiledoc-kit/parsers/html', }); // See https://github.com/bustle/mobiledoc-kit/issues/333 - test('newlines ("\\n") are ignored', function (assert) { + test('newlines ("\\n") are replaced with space characters', function (assert) { var html = "abc\ndef"; var post = parseHTML(html); - var _Helpers$postAbstract$buildFromText = _testHelpers['default'].postAbstract.buildFromText(['abcdef']); + var _Helpers$postAbstract$buildFromText = _testHelpers['default'].postAbstract.buildFromText(['abc def']); var expected = _Helpers$postAbstract$buildFromText.post; assert.postIsSimilar(post, expected); }); + + // see https://github.com/bustlelabs/mobiledoc-kit/issues/494 + test('top-level unknown void elements are parsed', function (assert) { + var html = '