diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index 6c48c41..0000000
--- a/.npmignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/node_modules
-.tern-port
-/test
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e17867..36010bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,35 @@
+## 1.8.0 (2022-03-14)
+
+### New features
+
+`MarkdownSerializer` now takes an `escapeExtraCharacters` option that can be used to control backslash-escaping behavior. Fix types for new option
+
+## 1.7.1 (2022-02-16)
+
+### Bug fixes
+
+Avoid escaping underscores surrounded by word characters.
+
+## 1.7.0 (2022-01-06)
+
+### New features
+
+Upgrade markdown-it to version 12.
+
+## 1.6.2 (2022-01-04)
+
+### Bug fixes
+
+Fix a bug where URL text in links and images was overzealously escaped.
+
+## 1.6.1 (2021-12-16)
+
+### Bug fixes
+
+Fix a bug where `MarkdownParser.parse` could return null when the parsed content doesn't fit the schema.
+
+Make sure underscores are escaped when serializing to Markdown.
+
 ## 1.6.0 (2021-09-21)
 
 ### New features
diff --git a/README.md b/README.md
index 9e4bbac..90c4d20 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
 # prosemirror-markdown
 
-[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror-markdown/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) ]
+[ [**WEBSITE**](http://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror-markdown/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) ]
 
-This is a (non-core) module for [ProseMirror](https://prosemirror.net).
+This is a (non-core) module for [ProseMirror](http://prosemirror.net).
 ProseMirror is a well-behaved rich semantic content editor based on
 contentEditable, with support for collaborative editing and custom
 document schemas.
@@ -52,17 +52,18 @@ the tokens to create a ProseMirror document tree.
        `block`, or `mark` must be set.
 
    **`block`**`: ?string`
-     : This token comes in `_open` and `_close` variants (which are
-       appended to the base token name provides a the object
-       property), and wraps a block of content. The block should be
-       wrapped in a node of the type named to by the property's
-       value. If the token does not have `_open` or `_close`, use
-       the `noCloseToken` option.
+     : This token (unless `noCloseToken` is true) comes in `_open`
+       and `_close` variants (which are appended to the base token
+       name provides a the object property), and wraps a block of
+       content. The block should be wrapped in a node of the type
+       named to by the property's value. If the token does not have
+       `_open` or `_close`, use the `noCloseToken` option.
 
    **`mark`**`: ?string`
-     : This token also comes in `_open` and `_close` variants, but
-       should add a mark (named by the value) to its content, rather
-       than wrapping it in a node.
+     : This token (again, unless `noCloseToken` is true) also comes
+       in `_open` and `_close` variants, but should add a mark
+       (named by the value) to its content, rather than wrapping it
+       in a node.
 
    **`attrs`**`: ?Object`
      : Attributes for the node or mark. When `getAttrs` is provided,
@@ -88,6 +89,9 @@ the tokens to create a ProseMirror document tree.
    this parser. Can be useful to copy and modify to base other
    parsers on.
 
+ * **`tokenizer`**`: This`\
+   parser's markdown-it tokenizer.
+
  * **`parse`**`(text: string) → Node`\
    Parse a string as [CommonMark](http://commonmark.org/) markup,
    and create a ProseMirror document as prescribed by this parser's
@@ -104,8 +108,7 @@ the tokens to create a ProseMirror document tree.
 A specification for serializing a ProseMirror document as
 Markdown/CommonMark text.
 
- * `new `**`MarkdownSerializer`**`(nodes: Object< fn(state: MarkdownSerializerState, node: Node, parent: Node, index: number) >, marks: Object)`
-
+ * `new `**`MarkdownSerializer`**`(nodes: Object< fn(state: MarkdownSerializerState, node: Node, parent: Node, index: number) >, marks: Object, options: ?Object)`\
    Construct a serializer with the given configuration. The `nodes`
    object should map node names in a given schema to function that
    take a serializer state and such a node, and serialize the node.
@@ -114,7 +117,14 @@ Markdown/CommonMark text.
    properties, which hold the strings that should appear before and
    after a piece of text marked that way, either directly or as a
    function that takes a serializer state and a mark, and returns a
-   string.
+   string. `open` and `close` can also be functions, which will be
+   called as
+
+       (state: MarkdownSerializerState, mark: Mark,
+        parent: Fragment, index: number) → string
+
+   Where `parent` and `index` allow you to inspect the mark's
+   context to see which nodes it applies to.
 
    Mark information objects can also have a `mixable` property
    which, when `true`, indicates that the order in which the mark's
@@ -132,6 +142,14 @@ Markdown/CommonMark text.
    CommonMark does not permit enclosing whitespace inside emphasis
    marks, see: http://spec.commonmark.org/0.26/#example-330
 
+    * **`options`**`: ?Object`\
+      Optional additional options.
+
+       * **`escapeExtraCharacters`**`: ?RegExp`\
+         Extra characters can be added for escaping. This is passed
+         directly to String.replace(), and the matching characters are
+         preceded by a backslash.
+
  * **`nodes`**`: Object< fn(MarkdownSerializerState, Node) >`\
    The node serializer
    functions for this serializer.
@@ -197,7 +215,7 @@ node and mark serialization methods (see `toMarkdown`).
  * **`esc`**`(str: string, startOfLine: ?bool) → string`\
    Escape the given string so that it can safely appear in Markdown
    content. If `startOfLine` is true, also escape characters that
-   has special meaning only at the start of the line.
+   have special meaning only at the start of the line.
 
  * **`repeat`**`(str: string, n: number) → string`\
    Repeat the given string `n` times.
diff --git a/debian/changelog b/debian/changelog
index a0405aa..d5f9ad2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+node-prosemirror-markdown (1.8.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 20 Mar 2022 14:34:49 -0000
+
 node-prosemirror-markdown (1.6.0-1) unstable; urgency=medium
 
   * Team Upload
diff --git a/dist/index.es.js b/dist/index.es.js
new file mode 100644
index 0000000..89ba7d5
--- /dev/null
+++ b/dist/index.es.js
@@ -0,0 +1,747 @@
+import { Schema, Mark } from 'prosemirror-model';
+import markdownit from 'markdown-it';
+
+// ::Schema Document schema for the data model used by CommonMark.
+var schema = new Schema({
+  nodes: {
+    doc: {
+      content: "block+"
+    },
+
+    paragraph: {
+      content: "inline*",
+      group: "block",
+      parseDOM: [{tag: "p"}],
+      toDOM: function toDOM() { return ["p", 0] }
+    },
+
+    blockquote: {
+      content: "block+",
+      group: "block",
+      parseDOM: [{tag: "blockquote"}],
+      toDOM: function toDOM() { return ["blockquote", 0] }
+    },
+
+    horizontal_rule: {
+      group: "block",
+      parseDOM: [{tag: "hr"}],
+      toDOM: function toDOM() { return ["div", ["hr"]] }
+    },
+
+    heading: {
+      attrs: {level: {default: 1}},
+      content: "(text | image)*",
+      group: "block",
+      defining: true,
+      parseDOM: [{tag: "h1", attrs: {level: 1}},
+                 {tag: "h2", attrs: {level: 2}},
+                 {tag: "h3", attrs: {level: 3}},
+                 {tag: "h4", attrs: {level: 4}},
+                 {tag: "h5", attrs: {level: 5}},
+                 {tag: "h6", attrs: {level: 6}}],
+      toDOM: function toDOM(node) { return ["h" + node.attrs.level, 0] }
+    },
+
+    code_block: {
+      content: "text*",
+      group: "block",
+      code: true,
+      defining: true,
+      marks: "",
+      attrs: {params: {default: ""}},
+      parseDOM: [{tag: "pre", preserveWhitespace: "full", getAttrs: function (node) { return (
+        {params: node.getAttribute("data-params") || ""}
+      ); }}],
+      toDOM: function toDOM(node) { return ["pre", node.attrs.params ? {"data-params": node.attrs.params} : {}, ["code", 0]] }
+    },
+
+    ordered_list: {
+      content: "list_item+",
+      group: "block",
+      attrs: {order: {default: 1}, tight: {default: false}},
+      parseDOM: [{tag: "ol", getAttrs: function getAttrs(dom) {
+        return {order: dom.hasAttribute("start") ? +dom.getAttribute("start") : 1,
+                tight: dom.hasAttribute("data-tight")}
+      }}],
+      toDOM: function toDOM(node) {
+        return ["ol", {start: node.attrs.order == 1 ? null : node.attrs.order,
+                       "data-tight": node.attrs.tight ? "true" : null}, 0]
+      }
+    },
+
+    bullet_list: {
+      content: "list_item+",
+      group: "block",
+      attrs: {tight: {default: false}},
+      parseDOM: [{tag: "ul", getAttrs: function (dom) { return ({tight: dom.hasAttribute("data-tight")}); }}],
+      toDOM: function toDOM(node) { return ["ul", {"data-tight": node.attrs.tight ? "true" : null}, 0] }
+    },
+
+    list_item: {
+      content: "paragraph block*",
+      defining: true,
+      parseDOM: [{tag: "li"}],
+      toDOM: function toDOM() { return ["li", 0] }
+    },
+
+    text: {
+      group: "inline"
+    },
+
+    image: {
+      inline: true,
+      attrs: {
+        src: {},
+        alt: {default: null},
+        title: {default: null}
+      },
+      group: "inline",
+      draggable: true,
+      parseDOM: [{tag: "img[src]", getAttrs: function getAttrs(dom) {
+        return {
+          src: dom.getAttribute("src"),
+          title: dom.getAttribute("title"),
+          alt: dom.getAttribute("alt")
+        }
+      }}],
+      toDOM: function toDOM(node) { return ["img", node.attrs] }
+    },
+
+    hard_break: {
+      inline: true,
+      group: "inline",
+      selectable: false,
+      parseDOM: [{tag: "br"}],
+      toDOM: function toDOM() { return ["br"] }
+    }
+  },
+
+  marks: {
+    em: {
+      parseDOM: [{tag: "i"}, {tag: "em"},
+                 {style: "font-style", getAttrs: function (value) { return value == "italic" && null; }}],
+      toDOM: function toDOM() { return ["em"] }
+    },
+
+    strong: {
+      parseDOM: [{tag: "b"}, {tag: "strong"},
+                 {style: "font-weight", getAttrs: function (value) { return /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null; }}],
+      toDOM: function toDOM() { return ["strong"] }
+    },
+
+    link: {
+      attrs: {
+        href: {},
+        title: {default: null}
+      },
+      inclusive: false,
+      parseDOM: [{tag: "a[href]", getAttrs: function getAttrs(dom) {
+        return {href: dom.getAttribute("href"), title: dom.getAttribute("title")}
+      }}],
+      toDOM: function toDOM(node) { return ["a", node.attrs] }
+    },
+
+    code: {
+      parseDOM: [{tag: "code"}],
+      toDOM: function toDOM() { return ["code"] }
+    }
+  }
+});
+
+function maybeMerge(a, b) {
+  if (a.isText && b.isText && Mark.sameSet(a.marks, b.marks))
+    { return a.withText(a.text + b.text) }
+}
+
+// Object used to track the context of a running parse.
+var MarkdownParseState = function MarkdownParseState(schema, tokenHandlers) {
+  this.schema = schema;
+  this.stack = [{type: schema.topNodeType, content: []}];
+  this.marks = Mark.none;
+  this.tokenHandlers = tokenHandlers;
+};
+
+MarkdownParseState.prototype.top = function top () {
+  return this.stack[this.stack.length - 1]
+};
+
+MarkdownParseState.prototype.push = function push (elt) {
+  if (this.stack.length) { this.top().content.push(elt); }
+};
+
+// : (string)
+// Adds the given text to the current position in the document,
+// using the current marks as styling.
+MarkdownParseState.prototype.addText = function addText (text) {
+  if (!text) { return }
+  var nodes = this.top().content, last = nodes[nodes.length - 1];
+  var node = this.schema.text(text, this.marks), merged;
+  if (last && (merged = maybeMerge(last, node))) { nodes[nodes.length - 1] = merged; }
+  else { nodes.push(node); }
+};
+
+// : (Mark)
+// Adds the given mark to the set of active marks.
+MarkdownParseState.prototype.openMark = function openMark (mark) {
+  this.marks = mark.addToSet(this.marks);
+};
+
+// : (Mark)
+// Removes the given mark from the set of active marks.
+MarkdownParseState.prototype.closeMark = function closeMark (mark) {
+  this.marks = mark.removeFromSet(this.marks);
+};
+
+MarkdownParseState.prototype.parseTokens = function parseTokens (toks) {
+  for (var i = 0; i < toks.length; i++) {
+    var tok = toks[i];
+    var handler = this.tokenHandlers[tok.type];
+    if (!handler)
+      { throw new Error("Token type `" + tok.type + "` not supported by Markdown parser") }
+    handler(this, tok, toks, i);
+  }
+};
+
+// : (NodeType, ?Object, ?[Node]) → ?Node
+// Add a node at the current position.
+MarkdownParseState.prototype.addNode = function addNode (type, attrs, content) {
+  var node = type.createAndFill(attrs, content, this.marks);
+  if (!node) { return null }
+  this.push(node);
+  return node
+};
+
+// : (NodeType, ?Object)
+// Wrap subsequent content in a node of the given type.
+MarkdownParseState.prototype.openNode = function openNode (type, attrs) {
+  this.stack.push({type: type, attrs: attrs, content: []});
+};
+
+// : () → ?Node
+// Close and return the node that is currently on top of the stack.
+MarkdownParseState.prototype.closeNode = function closeNode () {
+  if (this.marks.length) { this.marks = Mark.none; }
+  var info = this.stack.pop();
+  return this.addNode(info.type, info.attrs, info.content)
+};
+
+function attrs(spec, token, tokens, i) {
+  if (spec.getAttrs) { return spec.getAttrs(token, tokens, i) }
+  // For backwards compatibility when `attrs` is a Function
+  else if (spec.attrs instanceof Function) { return spec.attrs(token) }
+  else { return spec.attrs }
+}
+
+// Code content is represented as a single token with a `content`
+// property in Markdown-it.
+function noCloseToken(spec, type) {
+  return spec.noCloseToken || type == "code_inline" || type == "code_block" || type == "fence"
+}
+
+function withoutTrailingNewline(str) {
+  return str[str.length - 1] == "\n" ? str.slice(0, str.length - 1) : str
+}
+
+function noOp() {}
+
+function tokenHandlers(schema, tokens) {
+  var handlers = Object.create(null);
+  var loop = function ( type ) {
+    var spec = tokens[type];
+    if (spec.block) {
+      var nodeType = schema.nodeType(spec.block);
+      if (noCloseToken(spec, type)) {
+        handlers[type] = function (state, tok, tokens, i) {
+          state.openNode(nodeType, attrs(spec, tok, tokens, i));
+          state.addText(withoutTrailingNewline(tok.content));
+          state.closeNode();
+        };
+      } else {
+        handlers[type + "_open"] = function (state, tok, tokens, i) { return state.openNode(nodeType, attrs(spec, tok, tokens, i)); };
+        handlers[type + "_close"] = function (state) { return state.closeNode(); };
+      }
+    } else if (spec.node) {
+      var nodeType$1 = schema.nodeType(spec.node);
+      handlers[type] = function (state, tok, tokens, i) { return state.addNode(nodeType$1, attrs(spec, tok, tokens, i)); };
+    } else if (spec.mark) {
+      var markType = schema.marks[spec.mark];
+      if (noCloseToken(spec, type)) {
+        handlers[type] = function (state, tok, tokens, i) {
+          state.openMark(markType.create(attrs(spec, tok, tokens, i)));
+          state.addText(withoutTrailingNewline(tok.content));
+          state.closeMark(markType);
+        };
+      } else {
+        handlers[type + "_open"] = function (state, tok, tokens, i) { return state.openMark(markType.create(attrs(spec, tok, tokens, i))); };
+        handlers[type + "_close"] = function (state) { return state.closeMark(markType); };
+      }
+    } else if (spec.ignore) {
+      if (noCloseToken(spec, type)) {
+        handlers[type] = noOp;
+      } else {
+        handlers[type + "_open"] = noOp;
+        handlers[type + "_close"] = noOp;
+      }
+    } else {
+      throw new RangeError("Unrecognized parsing spec " + JSON.stringify(spec))
+    }
+  };
+
+  for (var type in tokens) loop( type );
+
+  handlers.text = function (state, tok) { return state.addText(tok.content); };
+  handlers.inline = function (state, tok) { return state.parseTokens(tok.children); };
+  handlers.softbreak = handlers.softbreak || (function (state) { return state.addText("\n"); });
+
+  return handlers
+}
+
+// ::- A configuration of a Markdown parser. Such a parser uses
+// [markdown-it](https://github.com/markdown-it/markdown-it) to
+// tokenize a file, and then runs the custom rules it is given over
+// the tokens to create a ProseMirror document tree.
+var MarkdownParser = function MarkdownParser(schema, tokenizer, tokens) {
+  // :: Object The value of the `tokens` object used to construct
+  // this parser. Can be useful to copy and modify to base other
+  // parsers on.
+  this.tokens = tokens;
+  this.schema = schema;
+  // :: This parser's markdown-it tokenizer.
+  this.tokenizer = tokenizer;
+  this.tokenHandlers = tokenHandlers(schema, tokens);
+};
+
+// :: (string) → Node
+// Parse a string as [CommonMark](http://commonmark.org/) markup,
+// and create a ProseMirror document as prescribed by this parser's
+// rules.
+MarkdownParser.prototype.parse = function parse (text) {
+  var state = new MarkdownParseState(this.schema, this.tokenHandlers), doc;
+  state.parseTokens(this.tokenizer.parse(text, {}));
+  do { doc = state.closeNode(); } while (state.stack.length)
+  return doc || this.schema.topNodeType.createAndFill()
+};
+
+function listIsTight(tokens, i) {
+  while (++i < tokens.length)
+    { if (tokens[i].type != "list_item_open") { return tokens[i].hidden } }
+  return false
+}
+
+// :: MarkdownParser
+// A parser parsing unextended [CommonMark](http://commonmark.org/),
+// without inline HTML, and producing a document in the basic schema.
+var defaultMarkdownParser = new MarkdownParser(schema, markdownit("commonmark", {html: false}), {
+  blockquote: {block: "blockquote"},
+  paragraph: {block: "paragraph"},
+  list_item: {block: "list_item"},
+  bullet_list: {block: "bullet_list", getAttrs: function (_, tokens, i) { return ({tight: listIsTight(tokens, i)}); }},
+  ordered_list: {block: "ordered_list", getAttrs: function (tok, tokens, i) { return ({
+    order: +tok.attrGet("start") || 1,
+    tight: listIsTight(tokens, i)
+  }); }},
+  heading: {block: "heading", getAttrs: function (tok) { return ({level: +tok.tag.slice(1)}); }},
+  code_block: {block: "code_block", noCloseToken: true},
+  fence: {block: "code_block", getAttrs: function (tok) { return ({params: tok.info || ""}); }, noCloseToken: true},
+  hr: {node: "horizontal_rule"},
+  image: {node: "image", getAttrs: function (tok) { return ({
+    src: tok.attrGet("src"),
+    title: tok.attrGet("title") || null,
+    alt: tok.children[0] && tok.children[0].content || null
+  }); }},
+  hardbreak: {node: "hard_break"},
+
+  em: {mark: "em"},
+  strong: {mark: "strong"},
+  link: {mark: "link", getAttrs: function (tok) { return ({
+    href: tok.attrGet("href"),
+    title: tok.attrGet("title") || null
+  }); }},
+  code_inline: {mark: "code", noCloseToken: true}
+});
+
+// ::- A specification for serializing a ProseMirror document as
+// Markdown/CommonMark text.
+var MarkdownSerializer = function MarkdownSerializer(nodes, marks, options) {
+  // :: Object<(MarkdownSerializerState, Node)> The node serializer
+  // functions for this serializer.
+  this.nodes = nodes;
+  // :: Object The mark serializer info.
+  this.marks = marks;
+  this.options = options || {};
+};
+
+// :: (Node, ?Object) → string
+// Serialize the content of the given node to
+// [CommonMark](http://commonmark.org/).
+MarkdownSerializer.prototype.serialize = function serialize (content, options) {
+  options = Object.assign(this.options, options);
+  var state = new MarkdownSerializerState(this.nodes, this.marks, options);
+  state.renderContent(content);
+  return state.out
+};
+
+// :: MarkdownSerializer
+// A serializer for the [basic schema](#schema).
+var defaultMarkdownSerializer = new MarkdownSerializer({
+  blockquote: function blockquote(state, node) {
+    state.wrapBlock("> ", null, node, function () { return state.renderContent(node); });
+  },
+  code_block: function code_block(state, node) {
+    state.write("```" + (node.attrs.params || "") + "\n");
+    state.text(node.textContent, false);
+    state.ensureNewLine();
+    state.write("```");
+    state.closeBlock(node);
+  },
+  heading: function heading(state, node) {
+    state.write(state.repeat("#", node.attrs.level) + " ");
+    state.renderInline(node);
+    state.closeBlock(node);
+  },
+  horizontal_rule: function horizontal_rule(state, node) {
+    state.write(node.attrs.markup || "---");
+    state.closeBlock(node);
+  },
+  bullet_list: function bullet_list(state, node) {
+    state.renderList(node, "  ", function () { return (node.attrs.bullet || "*") + " "; });
+  },
+  ordered_list: function ordered_list(state, node) {
+    var start = node.attrs.order || 1;
+    var maxW = String(start + node.childCount - 1).length;
+    var space = state.repeat(" ", maxW + 2);
+    state.renderList(node, space, function (i) {
+      var nStr = String(start + i);
+      return state.repeat(" ", maxW - nStr.length) + nStr + ". "
+    });
+  },
+  list_item: function list_item(state, node) {
+    state.renderContent(node);
+  },
+  paragraph: function paragraph(state, node) {
+    state.renderInline(node);
+    state.closeBlock(node);
+  },
+
+  image: function image(state, node) {
+    state.write("![" + state.esc(node.attrs.alt || "") + "](" + node.attrs.src +
+                (node.attrs.title ? ' "' + node.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")");
+  },
+  hard_break: function hard_break(state, node, parent, index) {
+    for (var i = index + 1; i < parent.childCount; i++)
+      { if (parent.child(i).type != node.type) {
+        state.write("\\\n");
+        return
+      } }
+  },
+  text: function text(state, node) {
+    state.text(node.text);
+  }
+}, {
+  em: {open: "*", close: "*", mixable: true, expelEnclosingWhitespace: true},
+  strong: {open: "**", close: "**", mixable: true, expelEnclosingWhitespace: true},
+  link: {
+    open: function open(_state, mark, parent, index) {
+      return isPlainURL(mark, parent, index, 1) ? "<" : "["
+    },
+    close: function close(state, mark, parent, index) {
+      return isPlainURL(mark, parent, index, -1) ? ">"
+        : "](" + mark.attrs.href + (mark.attrs.title ? ' "' + mark.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")"
+    }
+  },
+  code: {open: function open(_state, _mark, parent, index) { return backticksFor(parent.child(index), -1) },
+         close: function close(_state, _mark, parent, index) { return backticksFor(parent.child(index - 1), 1) },
+         escape: false}
+});
+
+function backticksFor(node, side) {
+  var ticks = /`+/g, m, len = 0;
+  if (node.isText) { while (m = ticks.exec(node.text)) { len = Math.max(len, m[0].length); } }
+  var result = len > 0 && side > 0 ? " `" : "`";
+  for (var i = 0; i < len; i++) { result += "`"; }
+  if (len > 0 && side < 0) { result += " "; }
+  return result
+}
+
+function isPlainURL(link, parent, index, side) {
+  if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) { return false }
+  var content = parent.child(index + (side < 0 ? -1 : 0));
+  if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link) { return false }
+  if (index == (side < 0 ? 1 : parent.childCount - 1)) { return true }
+  var next = parent.child(index + (side < 0 ? -2 : 1));
+  return !link.isInSet(next.marks)
+}
+
+// ::- This is an object used to track state and expose
+// methods related to markdown serialization. Instances are passed to
+// node and mark serialization methods (see `toMarkdown`).
+var MarkdownSerializerState = function MarkdownSerializerState(nodes, marks, options) {
+  this.nodes = nodes;
+  this.marks = marks;
+  this.delim = this.out = "";
+  this.closed = false;
+  this.inTightList = false;
+  // :: Object
+  // The options passed to the serializer.
+  // tightLists:: ?bool
+  // Whether to render lists in a tight style. This can be overridden
+  // on a node level by specifying a tight attribute on the node.
+  // Defaults to false.
+  this.options = options || {};
+  if (typeof this.options.tightLists == "undefined")
+    { this.options.tightLists = false; }
+};
+
+MarkdownSerializerState.prototype.flushClose = function flushClose (size) {
+  if (this.closed) {
+    if (!this.atBlank()) { this.out += "\n"; }
+    if (size == null) { size = 2; }
+    if (size > 1) {
+      var delimMin = this.delim;
+      var trim = /\s+$/.exec(delimMin);
+      if (trim) { delimMin = delimMin.slice(0, delimMin.length - trim[0].length); }
+      for (var i = 1; i < size; i++)
+        { this.out += delimMin + "\n"; }
+    }
+    this.closed = false;
+  }
+};
+
+// :: (string, ?string, Node, ())
+// Render a block, prefixing each line with `delim`, and the first
+// line in `firstDelim`. `node` should be the node that is closed at
+// the end of the block, and `f` is a function that renders the
+// content of the block.
+MarkdownSerializerState.prototype.wrapBlock = function wrapBlock (delim, firstDelim, node, f) {
+  var old = this.delim;
+  this.write(firstDelim || delim);
+  this.delim += delim;
+  f();
+  this.delim = old;
+  this.closeBlock(node);
+};
+
+MarkdownSerializerState.prototype.atBlank = function atBlank () {
+  return /(^|\n)$/.test(this.out)
+};
+
+// :: ()
+// Ensure the current content ends with a newline.
+MarkdownSerializerState.prototype.ensureNewLine = function ensureNewLine () {
+  if (!this.atBlank()) { this.out += "\n"; }
+};
+
+// :: (?string)
+// Prepare the state for writing output (closing closed paragraphs,
+// adding delimiters, and so on), and then optionally add content
+// (unescaped) to the output.
+MarkdownSerializerState.prototype.write = function write (content) {
+  this.flushClose();
+  if (this.delim && this.atBlank())
+    { this.out += this.delim; }
+  if (content) { this.out += content; }
+};
+
+// :: (Node)
+// Close the block for the given node.
+MarkdownSerializerState.prototype.closeBlock = function closeBlock (node) {
+  this.closed = node;
+};
+
+// :: (string, ?bool)
+// Add the given text to the document. When escape is not `false`,
+// it will be escaped.
+MarkdownSerializerState.prototype.text = function text (text$1, escape) {
+  var lines = text$1.split("\n");
+  for (var i = 0; i < lines.length; i++) {
+    var startOfLine = this.atBlank() || this.closed;
+    this.write();
+    this.out += escape !== false ? this.esc(lines[i], startOfLine) : lines[i];
+    if (i != lines.length - 1) { this.out += "\n"; }
+  }
+};
+
+// :: (Node)
+// Render the given node as a block.
+MarkdownSerializerState.prototype.render = function render (node, parent, index) {
+  if (typeof parent == "number") { throw new Error("!") }
+  if (!this.nodes[node.type.name]) { throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer") }
+  this.nodes[node.type.name](this, node, parent, index);
+};
+
+// :: (Node)
+// Render the contents of `parent` as block nodes.
+MarkdownSerializerState.prototype.renderContent = function renderContent (parent) {
+    var this$1$1 = this;
+
+  parent.forEach(function (node, _, i) { return this$1$1.render(node, parent, i); });
+};
+
+// :: (Node)
+// Render the contents of `parent` as inline content.
+MarkdownSerializerState.prototype.renderInline = function renderInline (parent) {
+    var this$1$1 = this;
+
+  var active = [], trailing = "";
+  var progress = function (node, _, index) {
+    var marks = node ? node.marks : [];
+
+    // Remove marks from `hard_break` that are the last node inside
+    // that mark to prevent parser edge cases with new lines just
+    // before closing marks.
+    // (FIXME it'd be nice if we had a schema-agnostic way to
+    // identify nodes that serialize as hard breaks)
+    if (node && node.type.name === "hard_break")
+      { marks = marks.filter(function (m) {
+        if (index + 1 == parent.childCount) { return false }
+        var next = parent.child(index + 1);
+        return m.isInSet(next.marks) && (!next.isText || /\S/.test(next.text))
+      }); }
+
+    var leading = trailing;
+    trailing = "";
+    // If whitespace has to be expelled from the node, adjust
+    // leading and trailing accordingly.
+    if (node && node.isText && marks.some(function (mark) {
+      var info = this$1$1.marks[mark.type.name];
+      return info && info.expelEnclosingWhitespace
+    })) {
+      var ref = /^(\s*)(.*?)(\s*)$/m.exec(node.text);
+        ref[0];
+        var lead = ref[1];
+        var inner$1 = ref[2];
+        var trail = ref[3];
+      leading += lead;
+      trailing = trail;
+      if (lead || trail) {
+        node = inner$1 ? node.withText(inner$1) : null;
+        if (!node) { marks = active; }
+      }
+    }
+
+    var inner = marks.length && marks[marks.length - 1], noEsc = inner && this$1$1.marks[inner.type.name].escape === false;
+    var len = marks.length - (noEsc ? 1 : 0);
+
+    // Try to reorder 'mixable' marks, such as em and strong, which
+    // in Markdown may be opened and closed in different order, so
+    // that order of the marks for the token matches the order in
+    // active.
+    outer: for (var i = 0; i < len; i++) {
+      var mark = marks[i];
+      if (!this$1$1.marks[mark.type.name].mixable) { break }
+      for (var j = 0; j < active.length; j++) {
+        var other = active[j];
+        if (!this$1$1.marks[other.type.name].mixable) { break }
+        if (mark.eq(other)) {
+          if (i > j)
+            { marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len)); }
+          else if (j > i)
+            { marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len)); }
+          continue outer
+        }
+      }
+    }
+
+    // Find the prefix of the mark set that didn't change
+    var keep = 0;
+    while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) { ++keep; }
+
+    // Close the marks that need to be closed
+    while (keep < active.length)
+      { this$1$1.text(this$1$1.markString(active.pop(), false, parent, index), false); }
+
+    // Output any previously expelled trailing whitespace outside the marks
+    if (leading) { this$1$1.text(leading); }
+
+    // Open the marks that need to be opened
+    if (node) {
+      while (active.length < len) {
+        var add = marks[active.length];
+        active.push(add);
+        this$1$1.text(this$1$1.markString(add, true, parent, index), false);
+      }
+
+      // Render the node. Special case code marks, since their content
+      // may not be escaped.
+      if (noEsc && node.isText)
+        { this$1$1.text(this$1$1.markString(inner, true, parent, index) + node.text +
+                  this$1$1.markString(inner, false, parent, index + 1), false); }
+      else
+        { this$1$1.render(node, parent, index); }
+    }
+  };
+  parent.forEach(progress);
+  progress(null, null, parent.childCount);
+};
+
+// :: (Node, string, (number) → string)
+// Render a node's content as a list. `delim` should be the extra
+// indentation added to all lines except the first in an item,
+// `firstDelim` is a function going from an item index to a
+// delimiter for the first line of the item.
+MarkdownSerializerState.prototype.renderList = function renderList (node, delim, firstDelim) {
+    var this$1$1 = this;
+
+  if (this.closed && this.closed.type == node.type)
+    { this.flushClose(3); }
+  else if (this.inTightList)
+    { this.flushClose(1); }
+
+  var isTight = typeof node.attrs.tight != "undefined" ? node.attrs.tight : this.options.tightLists;
+  var prevTight = this.inTightList;
+  this.inTightList = isTight;
+  node.forEach(function (child, _, i) {
+    if (i && isTight) { this$1$1.flushClose(1); }
+    this$1$1.wrapBlock(delim, firstDelim(i), node, function () { return this$1$1.render(child, node, i); });
+  });
+  this.inTightList = prevTight;
+};
+
+// :: (string, ?bool) → string
+// Escape the given string so that it can safely appear in Markdown
+// content. If `startOfLine` is true, also escape characters that
+// have special meaning only at the start of the line.
+MarkdownSerializerState.prototype.esc = function esc (str, startOfLine) {
+  str = str.replace(
+    /[`*\\~\[\]_]/g, 
+    function (m, i) { return m == "_" && i > 0 && i + 1 < str.length && str[i-1].match(/\w/) && str[i+1].match(/\w/) ?m : "\\" + m; }
+  );
+  if (startOfLine) { str = str.replace(/^[:#\-*+>]/, "\\$&").replace(/^(\s*\d+)\./, "$1\\."); }
+  if (this.options.escapeExtraCharacters) { str = str.replace(this.options.escapeExtraCharacters, "\\$&"); }
+  return str
+};
+
+MarkdownSerializerState.prototype.quote = function quote (str) {
+  var wrap = str.indexOf('"') == -1 ? '""' : str.indexOf("'") == -1 ? "''" : "()";
+  return wrap[0] + str + wrap[1]
+};
+
+// :: (string, number) → string
+// Repeat the given string `n` times.
+MarkdownSerializerState.prototype.repeat = function repeat (str, n) {
+  var out = "";
+  for (var i = 0; i < n; i++) { out += str; }
+  return out
+};
+
+// : (Mark, bool, string?) → string
+// Get the markdown string for a given opening or closing mark.
+MarkdownSerializerState.prototype.markString = function markString (mark, open, parent, index) {
+  var info = this.marks[mark.type.name];
+  var value = open ? info.open : info.close;
+  return typeof value == "string" ? value : value(this, mark, parent, index)
+};
+
+// :: (string) → { leading: ?string, trailing: ?string }
+// Get leading and trailing whitespace from a string. Values of
+// leading or trailing property of the return object will be undefined
+// if there is no match.
+MarkdownSerializerState.prototype.getEnclosingWhitespace = function getEnclosingWhitespace (text) {
+  return {
+    leading: (text.match(/^(\s+)/) || [])[0],
+    trailing: (text.match(/(\s+)$/) || [])[0]
+  }
+};
+
+export { MarkdownParser, MarkdownSerializer, MarkdownSerializerState, defaultMarkdownParser, defaultMarkdownSerializer, schema };
+//# sourceMappingURL=index.es.js.map
diff --git a/dist/index.es.js.map b/dist/index.es.js.map
new file mode 100644
index 0000000..c8a4749
--- /dev/null
+++ b/dist/index.es.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.es.js","sources":["../src/schema.js","../src/from_markdown.js","../src/to_markdown.js"],"sourcesContent":["import {Schema} from \"prosemirror-model\"\n\n// ::Schema Document schema for the data model used by CommonMark.\nexport const schema = new Schema({\n  nodes: {\n    doc: {\n      content: \"block+\"\n    },\n\n    paragraph: {\n      content: \"inline*\",\n      group: \"block\",\n      parseDOM: [{tag: \"p\"}],\n      toDOM() { return [\"p\", 0] }\n    },\n\n    blockquote: {\n      content: \"block+\",\n      group: \"block\",\n      parseDOM: [{tag: \"blockquote\"}],\n      toDOM() { return [\"blockquote\", 0] }\n    },\n\n    horizontal_rule: {\n      group: \"block\",\n      parseDOM: [{tag: \"hr\"}],\n      toDOM() { return [\"div\", [\"hr\"]] }\n    },\n\n    heading: {\n      attrs: {level: {default: 1}},\n      content: \"(text | image)*\",\n      group: \"block\",\n      defining: true,\n      parseDOM: [{tag: \"h1\", attrs: {level: 1}},\n                 {tag: \"h2\", attrs: {level: 2}},\n                 {tag: \"h3\", attrs: {level: 3}},\n                 {tag: \"h4\", attrs: {level: 4}},\n                 {tag: \"h5\", attrs: {level: 5}},\n                 {tag: \"h6\", attrs: {level: 6}}],\n      toDOM(node) { return [\"h\" + node.attrs.level, 0] }\n    },\n\n    code_block: {\n      content: \"text*\",\n      group: \"block\",\n      code: true,\n      defining: true,\n      marks: \"\",\n      attrs: {params: {default: \"\"}},\n      parseDOM: [{tag: \"pre\", preserveWhitespace: \"full\", getAttrs: node => (\n        {params: node.getAttribute(\"data-params\") || \"\"}\n      )}],\n      toDOM(node) { return [\"pre\", node.attrs.params ? {\"data-params\": node.attrs.params} : {}, [\"code\", 0]] }\n    },\n\n    ordered_list: {\n      content: \"list_item+\",\n      group: \"block\",\n      attrs: {order: {default: 1}, tight: {default: false}},\n      parseDOM: [{tag: \"ol\", getAttrs(dom) {\n        return {order: dom.hasAttribute(\"start\") ? +dom.getAttribute(\"start\") : 1,\n                tight: dom.hasAttribute(\"data-tight\")}\n      }}],\n      toDOM(node) {\n        return [\"ol\", {start: node.attrs.order == 1 ? null : node.attrs.order,\n                       \"data-tight\": node.attrs.tight ? \"true\" : null}, 0]\n      }\n    },\n\n    bullet_list: {\n      content: \"list_item+\",\n      group: \"block\",\n      attrs: {tight: {default: false}},\n      parseDOM: [{tag: \"ul\", getAttrs: dom => ({tight: dom.hasAttribute(\"data-tight\")})}],\n      toDOM(node) { return [\"ul\", {\"data-tight\": node.attrs.tight ? \"true\" : null}, 0] }\n    },\n\n    list_item: {\n      content: \"paragraph block*\",\n      defining: true,\n      parseDOM: [{tag: \"li\"}],\n      toDOM() { return [\"li\", 0] }\n    },\n\n    text: {\n      group: \"inline\"\n    },\n\n    image: {\n      inline: true,\n      attrs: {\n        src: {},\n        alt: {default: null},\n        title: {default: null}\n      },\n      group: \"inline\",\n      draggable: true,\n      parseDOM: [{tag: \"img[src]\", getAttrs(dom) {\n        return {\n          src: dom.getAttribute(\"src\"),\n          title: dom.getAttribute(\"title\"),\n          alt: dom.getAttribute(\"alt\")\n        }\n      }}],\n      toDOM(node) { return [\"img\", node.attrs] }\n    },\n\n    hard_break: {\n      inline: true,\n      group: \"inline\",\n      selectable: false,\n      parseDOM: [{tag: \"br\"}],\n      toDOM() { return [\"br\"] }\n    }\n  },\n\n  marks: {\n    em: {\n      parseDOM: [{tag: \"i\"}, {tag: \"em\"},\n                 {style: \"font-style\", getAttrs: value => value == \"italic\" && null}],\n      toDOM() { return [\"em\"] }\n    },\n\n    strong: {\n      parseDOM: [{tag: \"b\"}, {tag: \"strong\"},\n                 {style: \"font-weight\", getAttrs: value => /^(bold(er)?|[5-9]\\d{2,})$/.test(value) && null}],\n      toDOM() { return [\"strong\"] }\n    },\n\n    link: {\n      attrs: {\n        href: {},\n        title: {default: null}\n      },\n      inclusive: false,\n      parseDOM: [{tag: \"a[href]\", getAttrs(dom) {\n        return {href: dom.getAttribute(\"href\"), title: dom.getAttribute(\"title\")}\n      }}],\n      toDOM(node) { return [\"a\", node.attrs] }\n    },\n\n    code: {\n      parseDOM: [{tag: \"code\"}],\n      toDOM() { return [\"code\"] }\n    }\n  }\n})\n","import markdownit from \"markdown-it\"\nimport {schema} from \"./schema\"\nimport {Mark} from \"prosemirror-model\"\n\nfunction maybeMerge(a, b) {\n  if (a.isText && b.isText && Mark.sameSet(a.marks, b.marks))\n    return a.withText(a.text + b.text)\n}\n\n// Object used to track the context of a running parse.\nclass MarkdownParseState {\n  constructor(schema, tokenHandlers) {\n    this.schema = schema\n    this.stack = [{type: schema.topNodeType, content: []}]\n    this.marks = Mark.none\n    this.tokenHandlers = tokenHandlers\n  }\n\n  top() {\n    return this.stack[this.stack.length - 1]\n  }\n\n  push(elt) {\n    if (this.stack.length) this.top().content.push(elt)\n  }\n\n  // : (string)\n  // Adds the given text to the current position in the document,\n  // using the current marks as styling.\n  addText(text) {\n    if (!text) return\n    let nodes = this.top().content, last = nodes[nodes.length - 1]\n    let node = this.schema.text(text, this.marks), merged\n    if (last && (merged = maybeMerge(last, node))) nodes[nodes.length - 1] = merged\n    else nodes.push(node)\n  }\n\n  // : (Mark)\n  // Adds the given mark to the set of active marks.\n  openMark(mark) {\n    this.marks = mark.addToSet(this.marks)\n  }\n\n  // : (Mark)\n  // Removes the given mark from the set of active marks.\n  closeMark(mark) {\n    this.marks = mark.removeFromSet(this.marks)\n  }\n\n  parseTokens(toks) {\n    for (let i = 0; i < toks.length; i++) {\n      let tok = toks[i]\n      let handler = this.tokenHandlers[tok.type]\n      if (!handler)\n        throw new Error(\"Token type `\" + tok.type + \"` not supported by Markdown parser\")\n      handler(this, tok, toks, i)\n    }\n  }\n\n  // : (NodeType, ?Object, ?[Node]) → ?Node\n  // Add a node at the current position.\n  addNode(type, attrs, content) {\n    let node = type.createAndFill(attrs, content, this.marks)\n    if (!node) return null\n    this.push(node)\n    return node\n  }\n\n  // : (NodeType, ?Object)\n  // Wrap subsequent content in a node of the given type.\n  openNode(type, attrs) {\n    this.stack.push({type: type, attrs: attrs, content: []})\n  }\n\n  // : () → ?Node\n  // Close and return the node that is currently on top of the stack.\n  closeNode() {\n    if (this.marks.length) this.marks = Mark.none\n    let info = this.stack.pop()\n    return this.addNode(info.type, info.attrs, info.content)\n  }\n}\n\nfunction attrs(spec, token, tokens, i) {\n  if (spec.getAttrs) return spec.getAttrs(token, tokens, i)\n  // For backwards compatibility when `attrs` is a Function\n  else if (spec.attrs instanceof Function) return spec.attrs(token)\n  else return spec.attrs\n}\n\n// Code content is represented as a single token with a `content`\n// property in Markdown-it.\nfunction noCloseToken(spec, type) {\n  return spec.noCloseToken || type == \"code_inline\" || type == \"code_block\" || type == \"fence\"\n}\n\nfunction withoutTrailingNewline(str) {\n  return str[str.length - 1] == \"\\n\" ? str.slice(0, str.length - 1) : str\n}\n\nfunction noOp() {}\n\nfunction tokenHandlers(schema, tokens) {\n  let handlers = Object.create(null)\n  for (let type in tokens) {\n    let spec = tokens[type]\n    if (spec.block) {\n      let nodeType = schema.nodeType(spec.block)\n      if (noCloseToken(spec, type)) {\n        handlers[type] = (state, tok, tokens, i) => {\n          state.openNode(nodeType, attrs(spec, tok, tokens, i))\n          state.addText(withoutTrailingNewline(tok.content))\n          state.closeNode()\n        }\n      } else {\n        handlers[type + \"_open\"] = (state, tok, tokens, i) => state.openNode(nodeType, attrs(spec, tok, tokens, i))\n        handlers[type + \"_close\"] = state => state.closeNode()\n      }\n    } else if (spec.node) {\n      let nodeType = schema.nodeType(spec.node)\n      handlers[type] = (state, tok, tokens, i) => state.addNode(nodeType, attrs(spec, tok, tokens, i))\n    } else if (spec.mark) {\n      let markType = schema.marks[spec.mark]\n      if (noCloseToken(spec, type)) {\n        handlers[type] = (state, tok, tokens, i) => {\n          state.openMark(markType.create(attrs(spec, tok, tokens, i)))\n          state.addText(withoutTrailingNewline(tok.content))\n          state.closeMark(markType)\n        }\n      } else {\n        handlers[type + \"_open\"] = (state, tok, tokens, i) => state.openMark(markType.create(attrs(spec, tok, tokens, i)))\n        handlers[type + \"_close\"] = state => state.closeMark(markType)\n      }\n    } else if (spec.ignore) {\n      if (noCloseToken(spec, type)) {\n        handlers[type] = noOp\n      } else {\n        handlers[type + \"_open\"] = noOp\n        handlers[type + \"_close\"] = noOp\n      }\n    } else {\n      throw new RangeError(\"Unrecognized parsing spec \" + JSON.stringify(spec))\n    }\n  }\n\n  handlers.text = (state, tok) => state.addText(tok.content)\n  handlers.inline = (state, tok) => state.parseTokens(tok.children)\n  handlers.softbreak = handlers.softbreak || (state => state.addText(\"\\n\"))\n\n  return handlers\n}\n\n// ::- A configuration of a Markdown parser. Such a parser uses\n// [markdown-it](https://github.com/markdown-it/markdown-it) to\n// tokenize a file, and then runs the custom rules it is given over\n// the tokens to create a ProseMirror document tree.\nexport class MarkdownParser {\n  // :: (Schema, MarkdownIt, Object)\n  // Create a parser with the given configuration. You can configure\n  // the markdown-it parser to parse the dialect you want, and provide\n  // a description of the ProseMirror entities those tokens map to in\n  // the `tokens` object, which maps token names to descriptions of\n  // what to do with them. Such a description is an object, and may\n  // have the following properties:\n  //\n  // **`node`**`: ?string`\n  //   : This token maps to a single node, whose type can be looked up\n  //     in the schema under the given name. Exactly one of `node`,\n  //     `block`, or `mark` must be set.\n  //\n  // **`block`**`: ?string`\n  //   : This token (unless `noCloseToken` is true) comes in `_open`\n  //     and `_close` variants (which are appended to the base token\n  //     name provides a the object property), and wraps a block of\n  //     content. The block should be wrapped in a node of the type\n  //     named to by the property's value. If the token does not have\n  //     `_open` or `_close`, use the `noCloseToken` option.\n  //\n  // **`mark`**`: ?string`\n  //   : This token (again, unless `noCloseToken` is true) also comes\n  //     in `_open` and `_close` variants, but should add a mark\n  //     (named by the value) to its content, rather than wrapping it\n  //     in a node.\n  //\n  // **`attrs`**`: ?Object`\n  //   : Attributes for the node or mark. When `getAttrs` is provided,\n  //     it takes precedence.\n  //\n  // **`getAttrs`**`: ?(MarkdownToken) → Object`\n  //   : A function used to compute the attributes for the node or mark\n  //     that takes a [markdown-it\n  //     token](https://markdown-it.github.io/markdown-it/#Token) and\n  //     returns an attribute object.\n  //\n  // **`noCloseToken`**`: ?boolean`\n  //   : Indicates that the [markdown-it\n  //     token](https://markdown-it.github.io/markdown-it/#Token) has\n  //     no `_open` or `_close` for the nodes. This defaults to `true`\n  //     for `code_inline`, `code_block` and `fence`.\n  //\n  // **`ignore`**`: ?bool`\n  //   : When true, ignore content for the matched token.\n  constructor(schema, tokenizer, tokens) {\n    // :: Object The value of the `tokens` object used to construct\n    // this parser. Can be useful to copy and modify to base other\n    // parsers on.\n    this.tokens = tokens\n    this.schema = schema\n    // :: This parser's markdown-it tokenizer.\n    this.tokenizer = tokenizer\n    this.tokenHandlers = tokenHandlers(schema, tokens)\n  }\n\n  // :: (string) → Node\n  // Parse a string as [CommonMark](http://commonmark.org/) markup,\n  // and create a ProseMirror document as prescribed by this parser's\n  // rules.\n  parse(text) {\n    let state = new MarkdownParseState(this.schema, this.tokenHandlers), doc\n    state.parseTokens(this.tokenizer.parse(text, {}))\n    do { doc = state.closeNode() } while (state.stack.length)\n    return doc || this.schema.topNodeType.createAndFill()\n  }\n}\n\nfunction listIsTight(tokens, i) {\n  while (++i < tokens.length)\n    if (tokens[i].type != \"list_item_open\") return tokens[i].hidden\n  return false\n}\n\n// :: MarkdownParser\n// A parser parsing unextended [CommonMark](http://commonmark.org/),\n// without inline HTML, and producing a document in the basic schema.\nexport const defaultMarkdownParser = new MarkdownParser(schema, markdownit(\"commonmark\", {html: false}), {\n  blockquote: {block: \"blockquote\"},\n  paragraph: {block: \"paragraph\"},\n  list_item: {block: \"list_item\"},\n  bullet_list: {block: \"bullet_list\", getAttrs: (_, tokens, i) => ({tight: listIsTight(tokens, i)})},\n  ordered_list: {block: \"ordered_list\", getAttrs: (tok, tokens, i) => ({\n    order: +tok.attrGet(\"start\") || 1,\n    tight: listIsTight(tokens, i)\n  })},\n  heading: {block: \"heading\", getAttrs: tok => ({level: +tok.tag.slice(1)})},\n  code_block: {block: \"code_block\", noCloseToken: true},\n  fence: {block: \"code_block\", getAttrs: tok => ({params: tok.info || \"\"}), noCloseToken: true},\n  hr: {node: \"horizontal_rule\"},\n  image: {node: \"image\", getAttrs: tok => ({\n    src: tok.attrGet(\"src\"),\n    title: tok.attrGet(\"title\") || null,\n    alt: tok.children[0] && tok.children[0].content || null\n  })},\n  hardbreak: {node: \"hard_break\"},\n\n  em: {mark: \"em\"},\n  strong: {mark: \"strong\"},\n  link: {mark: \"link\", getAttrs: tok => ({\n    href: tok.attrGet(\"href\"),\n    title: tok.attrGet(\"title\") || null\n  })},\n  code_inline: {mark: \"code\", noCloseToken: true}\n})\n","// ::- A specification for serializing a ProseMirror document as\n// Markdown/CommonMark text.\nexport class MarkdownSerializer {\n  // :: (Object<(state: MarkdownSerializerState, node: Node, parent: Node, index: number)>, Object, ?Object)\n  // Construct a serializer with the given configuration. The `nodes`\n  // object should map node names in a given schema to function that\n  // take a serializer state and such a node, and serialize the node.\n  //\n  // The `marks` object should hold objects with `open` and `close`\n  // properties, which hold the strings that should appear before and\n  // after a piece of text marked that way, either directly or as a\n  // function that takes a serializer state and a mark, and returns a\n  // string. `open` and `close` can also be functions, which will be\n  // called as\n  //\n  //     (state: MarkdownSerializerState, mark: Mark,\n  //      parent: Fragment, index: number) → string\n  //\n  // Where `parent` and `index` allow you to inspect the mark's\n  // context to see which nodes it applies to.\n  //\n  // Mark information objects can also have a `mixable` property\n  // which, when `true`, indicates that the order in which the mark's\n  // opening and closing syntax appears relative to other mixable\n  // marks can be varied. (For example, you can say `**a *b***` and\n  // `*a **b***`, but not `` `a *b*` ``.)\n  //\n  // To disable character escaping in a mark, you can give it an\n  // `escape` property of `false`. Such a mark has to have the highest\n  // precedence (must always be the innermost mark).\n  //\n  // The `expelEnclosingWhitespace` mark property causes the\n  // serializer to move enclosing whitespace from inside the marks to\n  // outside the marks. This is necessary for emphasis marks as\n  // CommonMark does not permit enclosing whitespace inside emphasis\n  // marks, see: http://spec.commonmark.org/0.26/#example-330\n  //\n  //   options::- Optional additional options.\n  //     escapeExtraCharacters:: ?RegExp\n  //     Extra characters can be added for escaping. This is passed\n  //     directly to String.replace(), and the matching characters are\n  //     preceded by a backslash.\n  constructor(nodes, marks, options) {\n    // :: Object<(MarkdownSerializerState, Node)> The node serializer\n    // functions for this serializer.\n    this.nodes = nodes\n    // :: Object The mark serializer info.\n    this.marks = marks\n    this.options = options || {}\n  }\n\n  // :: (Node, ?Object) → string\n  // Serialize the content of the given node to\n  // [CommonMark](http://commonmark.org/).\n  serialize(content, options) {\n    options = Object.assign(this.options, options)\n    let state = new MarkdownSerializerState(this.nodes, this.marks, options)\n    state.renderContent(content)\n    return state.out\n  }\n}\n\n// :: MarkdownSerializer\n// A serializer for the [basic schema](#schema).\nexport const defaultMarkdownSerializer = new MarkdownSerializer({\n  blockquote(state, node) {\n    state.wrapBlock(\"> \", null, node, () => state.renderContent(node))\n  },\n  code_block(state, node) {\n    state.write(\"```\" + (node.attrs.params || \"\") + \"\\n\")\n    state.text(node.textContent, false)\n    state.ensureNewLine()\n    state.write(\"```\")\n    state.closeBlock(node)\n  },\n  heading(state, node) {\n    state.write(state.repeat(\"#\", node.attrs.level) + \" \")\n    state.renderInline(node)\n    state.closeBlock(node)\n  },\n  horizontal_rule(state, node) {\n    state.write(node.attrs.markup || \"---\")\n    state.closeBlock(node)\n  },\n  bullet_list(state, node) {\n    state.renderList(node, \"  \", () => (node.attrs.bullet || \"*\") + \" \")\n  },\n  ordered_list(state, node) {\n    let start = node.attrs.order || 1\n    let maxW = String(start + node.childCount - 1).length\n    let space = state.repeat(\" \", maxW + 2)\n    state.renderList(node, space, i => {\n      let nStr = String(start + i)\n      return state.repeat(\" \", maxW - nStr.length) + nStr + \". \"\n    })\n  },\n  list_item(state, node) {\n    state.renderContent(node)\n  },\n  paragraph(state, node) {\n    state.renderInline(node)\n    state.closeBlock(node)\n  },\n\n  image(state, node) {\n    state.write(\"![\" + state.esc(node.attrs.alt || \"\") + \"](\" + node.attrs.src +\n                (node.attrs.title ? ' \"' + node.attrs.title.replace(/\"/g, '\\\\\"') + '\"' : \"\") + \")\")\n  },\n  hard_break(state, node, parent, index) {\n    for (let i = index + 1; i < parent.childCount; i++)\n      if (parent.child(i).type != node.type) {\n        state.write(\"\\\\\\n\")\n        return\n      }\n  },\n  text(state, node) {\n    state.text(node.text)\n  }\n}, {\n  em: {open: \"*\", close: \"*\", mixable: true, expelEnclosingWhitespace: true},\n  strong: {open: \"**\", close: \"**\", mixable: true, expelEnclosingWhitespace: true},\n  link: {\n    open(_state, mark, parent, index) {\n      return isPlainURL(mark, parent, index, 1) ? \"<\" : \"[\"\n    },\n    close(state, mark, parent, index) {\n      return isPlainURL(mark, parent, index, -1) ? \">\"\n        : \"](\" + mark.attrs.href + (mark.attrs.title ? ' \"' + mark.attrs.title.replace(/\"/g, '\\\\\"') + '\"' : \"\") + \")\"\n    }\n  },\n  code: {open(_state, _mark, parent, index) { return backticksFor(parent.child(index), -1) },\n         close(_state, _mark, parent, index) { return backticksFor(parent.child(index - 1), 1) },\n         escape: false}\n})\n\nfunction backticksFor(node, side) {\n  let ticks = /`+/g, m, len = 0\n  if (node.isText) while (m = ticks.exec(node.text)) len = Math.max(len, m[0].length)\n  let result = len > 0 && side > 0 ? \" `\" : \"`\"\n  for (let i = 0; i < len; i++) result += \"`\"\n  if (len > 0 && side < 0) result += \" \"\n  return result\n}\n\nfunction isPlainURL(link, parent, index, side) {\n  if (link.attrs.title || !/^\\w+:/.test(link.attrs.href)) return false\n  let content = parent.child(index + (side < 0 ? -1 : 0))\n  if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link) return false\n  if (index == (side < 0 ? 1 : parent.childCount - 1)) return true\n  let next = parent.child(index + (side < 0 ? -2 : 1))\n  return !link.isInSet(next.marks)\n}\n\n// ::- This is an object used to track state and expose\n// methods related to markdown serialization. Instances are passed to\n// node and mark serialization methods (see `toMarkdown`).\nexport class MarkdownSerializerState {\n  constructor(nodes, marks, options) {\n    this.nodes = nodes\n    this.marks = marks\n    this.delim = this.out = \"\"\n    this.closed = false\n    this.inTightList = false\n    // :: Object\n    // The options passed to the serializer.\n    //   tightLists:: ?bool\n    //   Whether to render lists in a tight style. This can be overridden\n    //   on a node level by specifying a tight attribute on the node.\n    //   Defaults to false.\n    this.options = options || {}\n    if (typeof this.options.tightLists == \"undefined\")\n      this.options.tightLists = false\n  }\n\n  flushClose(size) {\n    if (this.closed) {\n      if (!this.atBlank()) this.out += \"\\n\"\n      if (size == null) size = 2\n      if (size > 1) {\n        let delimMin = this.delim\n        let trim = /\\s+$/.exec(delimMin)\n        if (trim) delimMin = delimMin.slice(0, delimMin.length - trim[0].length)\n        for (let i = 1; i < size; i++)\n          this.out += delimMin + \"\\n\"\n      }\n      this.closed = false\n    }\n  }\n\n  // :: (string, ?string, Node, ())\n  // Render a block, prefixing each line with `delim`, and the first\n  // line in `firstDelim`. `node` should be the node that is closed at\n  // the end of the block, and `f` is a function that renders the\n  // content of the block.\n  wrapBlock(delim, firstDelim, node, f) {\n    let old = this.delim\n    this.write(firstDelim || delim)\n    this.delim += delim\n    f()\n    this.delim = old\n    this.closeBlock(node)\n  }\n\n  atBlank() {\n    return /(^|\\n)$/.test(this.out)\n  }\n\n  // :: ()\n  // Ensure the current content ends with a newline.\n  ensureNewLine() {\n    if (!this.atBlank()) this.out += \"\\n\"\n  }\n\n  // :: (?string)\n  // Prepare the state for writing output (closing closed paragraphs,\n  // adding delimiters, and so on), and then optionally add content\n  // (unescaped) to the output.\n  write(content) {\n    this.flushClose()\n    if (this.delim && this.atBlank())\n      this.out += this.delim\n    if (content) this.out += content\n  }\n\n  // :: (Node)\n  // Close the block for the given node.\n  closeBlock(node) {\n    this.closed = node\n  }\n\n  // :: (string, ?bool)\n  // Add the given text to the document. When escape is not `false`,\n  // it will be escaped.\n  text(text, escape) {\n    let lines = text.split(\"\\n\")\n    for (let i = 0; i < lines.length; i++) {\n      var startOfLine = this.atBlank() || this.closed\n      this.write()\n      this.out += escape !== false ? this.esc(lines[i], startOfLine) : lines[i]\n      if (i != lines.length - 1) this.out += \"\\n\"\n    }\n  }\n\n  // :: (Node)\n  // Render the given node as a block.\n  render(node, parent, index) {\n    if (typeof parent == \"number\") throw new Error(\"!\")\n    if (!this.nodes[node.type.name]) throw new Error(\"Token type `\" + node.type.name + \"` not supported by Markdown renderer\")\n    this.nodes[node.type.name](this, node, parent, index)\n  }\n\n  // :: (Node)\n  // Render the contents of `parent` as block nodes.\n  renderContent(parent) {\n    parent.forEach((node, _, i) => this.render(node, parent, i))\n  }\n\n  // :: (Node)\n  // Render the contents of `parent` as inline content.\n  renderInline(parent) {\n    let active = [], trailing = \"\"\n    let progress = (node, _, index) => {\n      let marks = node ? node.marks : []\n\n      // Remove marks from `hard_break` that are the last node inside\n      // that mark to prevent parser edge cases with new lines just\n      // before closing marks.\n      // (FIXME it'd be nice if we had a schema-agnostic way to\n      // identify nodes that serialize as hard breaks)\n      if (node && node.type.name === \"hard_break\")\n        marks = marks.filter(m => {\n          if (index + 1 == parent.childCount) return false\n          let next = parent.child(index + 1)\n          return m.isInSet(next.marks) && (!next.isText || /\\S/.test(next.text))\n        })\n\n      let leading = trailing\n      trailing = \"\"\n      // If whitespace has to be expelled from the node, adjust\n      // leading and trailing accordingly.\n      if (node && node.isText && marks.some(mark => {\n        let info = this.marks[mark.type.name]\n        return info && info.expelEnclosingWhitespace\n      })) {\n        let [_, lead, inner, trail] = /^(\\s*)(.*?)(\\s*)$/m.exec(node.text)\n        leading += lead\n        trailing = trail\n        if (lead || trail) {\n          node = inner ? node.withText(inner) : null\n          if (!node) marks = active\n        }\n      }\n\n      let inner = marks.length && marks[marks.length - 1], noEsc = inner && this.marks[inner.type.name].escape === false\n      let len = marks.length - (noEsc ? 1 : 0)\n\n      // Try to reorder 'mixable' marks, such as em and strong, which\n      // in Markdown may be opened and closed in different order, so\n      // that order of the marks for the token matches the order in\n      // active.\n      outer: for (let i = 0; i < len; i++) {\n        let mark = marks[i]\n        if (!this.marks[mark.type.name].mixable) break\n        for (let j = 0; j < active.length; j++) {\n          let other = active[j]\n          if (!this.marks[other.type.name].mixable) break\n          if (mark.eq(other)) {\n            if (i > j)\n              marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len))\n            else if (j > i)\n              marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len))\n            continue outer\n          }\n        }\n      }\n\n      // Find the prefix of the mark set that didn't change\n      let keep = 0\n      while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) ++keep\n\n      // Close the marks that need to be closed\n      while (keep < active.length)\n        this.text(this.markString(active.pop(), false, parent, index), false)\n\n      // Output any previously expelled trailing whitespace outside the marks\n      if (leading) this.text(leading)\n\n      // Open the marks that need to be opened\n      if (node) {\n        while (active.length < len) {\n          let add = marks[active.length]\n          active.push(add)\n          this.text(this.markString(add, true, parent, index), false)\n        }\n\n        // Render the node. Special case code marks, since their content\n        // may not be escaped.\n        if (noEsc && node.isText)\n          this.text(this.markString(inner, true, parent, index) + node.text +\n                    this.markString(inner, false, parent, index + 1), false)\n        else\n          this.render(node, parent, index)\n      }\n    }\n    parent.forEach(progress)\n    progress(null, null, parent.childCount)\n  }\n\n  // :: (Node, string, (number) → string)\n  // Render a node's content as a list. `delim` should be the extra\n  // indentation added to all lines except the first in an item,\n  // `firstDelim` is a function going from an item index to a\n  // delimiter for the first line of the item.\n  renderList(node, delim, firstDelim) {\n    if (this.closed && this.closed.type == node.type)\n      this.flushClose(3)\n    else if (this.inTightList)\n      this.flushClose(1)\n\n    let isTight = typeof node.attrs.tight != \"undefined\" ? node.attrs.tight : this.options.tightLists\n    let prevTight = this.inTightList\n    this.inTightList = isTight\n    node.forEach((child, _, i) => {\n      if (i && isTight) this.flushClose(1)\n      this.wrapBlock(delim, firstDelim(i), node, () => this.render(child, node, i))\n    })\n    this.inTightList = prevTight\n  }\n\n  // :: (string, ?bool) → string\n  // Escape the given string so that it can safely appear in Markdown\n  // content. If `startOfLine` is true, also escape characters that\n  // have special meaning only at the start of the line.\n  esc(str, startOfLine) {\n    str = str.replace(\n      /[`*\\\\~\\[\\]_]/g, \n      (m, i) => m == \"_\" && i > 0 && i + 1 < str.length && str[i-1].match(/\\w/) && str[i+1].match(/\\w/) ?  m : \"\\\\\" + m\n    )\n    if (startOfLine) str = str.replace(/^[:#\\-*+>]/, \"\\\\$&\").replace(/^(\\s*\\d+)\\./, \"$1\\\\.\")\n    if (this.options.escapeExtraCharacters) str = str.replace(this.options.escapeExtraCharacters, \"\\\\$&\")\n    return str\n  }\n\n  quote(str) {\n    var wrap = str.indexOf('\"') == -1 ? '\"\"' : str.indexOf(\"'\") == -1 ? \"''\" : \"()\"\n    return wrap[0] + str + wrap[1]\n  }\n\n  // :: (string, number) → string\n  // Repeat the given string `n` times.\n  repeat(str, n) {\n    let out = \"\"\n    for (let i = 0; i < n; i++) out += str\n    return out\n  }\n\n  // : (Mark, bool, string?) → string\n  // Get the markdown string for a given opening or closing mark.\n  markString(mark, open, parent, index) {\n    let info = this.marks[mark.type.name]\n    let value = open ? info.open : info.close\n    return typeof value == \"string\" ? value : value(this, mark, parent, index)\n  }\n\n  // :: (string) → { leading: ?string, trailing: ?string }\n  // Get leading and trailing whitespace from a string. Values of\n  // leading or trailing property of the return object will be undefined\n  // if there is no match.\n  getEnclosingWhitespace(text) {\n    return {\n      leading: (text.match(/^(\\s+)/) || [])[0],\n      trailing: (text.match(/(\\s+)$/) || [])[0]\n    }\n  }\n}\n"],"names":["let","nodeType","text","this","inner"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
new file mode 100644
index 0000000..1c75160
--- /dev/null
+++ b/dist/index.js
@@ -0,0 +1,760 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+var prosemirrorModel = require('prosemirror-model');
+var markdownit = require('markdown-it');
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+var markdownit__default = /*#__PURE__*/_interopDefaultLegacy(markdownit);
+
+// ::Schema Document schema for the data model used by CommonMark.
+var schema = new prosemirrorModel.Schema({
+  nodes: {
+    doc: {
+      content: "block+"
+    },
+
+    paragraph: {
+      content: "inline*",
+      group: "block",
+      parseDOM: [{tag: "p"}],
+      toDOM: function toDOM() { return ["p", 0] }
+    },
+
+    blockquote: {
+      content: "block+",
+      group: "block",
+      parseDOM: [{tag: "blockquote"}],
+      toDOM: function toDOM() { return ["blockquote", 0] }
+    },
+
+    horizontal_rule: {
+      group: "block",
+      parseDOM: [{tag: "hr"}],
+      toDOM: function toDOM() { return ["div", ["hr"]] }
+    },
+
+    heading: {
+      attrs: {level: {default: 1}},
+      content: "(text | image)*",
+      group: "block",
+      defining: true,
+      parseDOM: [{tag: "h1", attrs: {level: 1}},
+                 {tag: "h2", attrs: {level: 2}},
+                 {tag: "h3", attrs: {level: 3}},
+                 {tag: "h4", attrs: {level: 4}},
+                 {tag: "h5", attrs: {level: 5}},
+                 {tag: "h6", attrs: {level: 6}}],
+      toDOM: function toDOM(node) { return ["h" + node.attrs.level, 0] }
+    },
+
+    code_block: {
+      content: "text*",
+      group: "block",
+      code: true,
+      defining: true,
+      marks: "",
+      attrs: {params: {default: ""}},
+      parseDOM: [{tag: "pre", preserveWhitespace: "full", getAttrs: function (node) { return (
+        {params: node.getAttribute("data-params") || ""}
+      ); }}],
+      toDOM: function toDOM(node) { return ["pre", node.attrs.params ? {"data-params": node.attrs.params} : {}, ["code", 0]] }
+    },
+
+    ordered_list: {
+      content: "list_item+",
+      group: "block",
+      attrs: {order: {default: 1}, tight: {default: false}},
+      parseDOM: [{tag: "ol", getAttrs: function getAttrs(dom) {
+        return {order: dom.hasAttribute("start") ? +dom.getAttribute("start") : 1,
+                tight: dom.hasAttribute("data-tight")}
+      }}],
+      toDOM: function toDOM(node) {
+        return ["ol", {start: node.attrs.order == 1 ? null : node.attrs.order,
+                       "data-tight": node.attrs.tight ? "true" : null}, 0]
+      }
+    },
+
+    bullet_list: {
+      content: "list_item+",
+      group: "block",
+      attrs: {tight: {default: false}},
+      parseDOM: [{tag: "ul", getAttrs: function (dom) { return ({tight: dom.hasAttribute("data-tight")}); }}],
+      toDOM: function toDOM(node) { return ["ul", {"data-tight": node.attrs.tight ? "true" : null}, 0] }
+    },
+
+    list_item: {
+      content: "paragraph block*",
+      defining: true,
+      parseDOM: [{tag: "li"}],
+      toDOM: function toDOM() { return ["li", 0] }
+    },
+
+    text: {
+      group: "inline"
+    },
+
+    image: {
+      inline: true,
+      attrs: {
+        src: {},
+        alt: {default: null},
+        title: {default: null}
+      },
+      group: "inline",
+      draggable: true,
+      parseDOM: [{tag: "img[src]", getAttrs: function getAttrs(dom) {
+        return {
+          src: dom.getAttribute("src"),
+          title: dom.getAttribute("title"),
+          alt: dom.getAttribute("alt")
+        }
+      }}],
+      toDOM: function toDOM(node) { return ["img", node.attrs] }
+    },
+
+    hard_break: {
+      inline: true,
+      group: "inline",
+      selectable: false,
+      parseDOM: [{tag: "br"}],
+      toDOM: function toDOM() { return ["br"] }
+    }
+  },
+
+  marks: {
+    em: {
+      parseDOM: [{tag: "i"}, {tag: "em"},
+                 {style: "font-style", getAttrs: function (value) { return value == "italic" && null; }}],
+      toDOM: function toDOM() { return ["em"] }
+    },
+
+    strong: {
+      parseDOM: [{tag: "b"}, {tag: "strong"},
+                 {style: "font-weight", getAttrs: function (value) { return /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null; }}],
+      toDOM: function toDOM() { return ["strong"] }
+    },
+
+    link: {
+      attrs: {
+        href: {},
+        title: {default: null}
+      },
+      inclusive: false,
+      parseDOM: [{tag: "a[href]", getAttrs: function getAttrs(dom) {
+        return {href: dom.getAttribute("href"), title: dom.getAttribute("title")}
+      }}],
+      toDOM: function toDOM(node) { return ["a", node.attrs] }
+    },
+
+    code: {
+      parseDOM: [{tag: "code"}],
+      toDOM: function toDOM() { return ["code"] }
+    }
+  }
+});
+
+function maybeMerge(a, b) {
+  if (a.isText && b.isText && prosemirrorModel.Mark.sameSet(a.marks, b.marks))
+    { return a.withText(a.text + b.text) }
+}
+
+// Object used to track the context of a running parse.
+var MarkdownParseState = function MarkdownParseState(schema, tokenHandlers) {
+  this.schema = schema;
+  this.stack = [{type: schema.topNodeType, content: []}];
+  this.marks = prosemirrorModel.Mark.none;
+  this.tokenHandlers = tokenHandlers;
+};
+
+MarkdownParseState.prototype.top = function top () {
+  return this.stack[this.stack.length - 1]
+};
+
+MarkdownParseState.prototype.push = function push (elt) {
+  if (this.stack.length) { this.top().content.push(elt); }
+};
+
+// : (string)
+// Adds the given text to the current position in the document,
+// using the current marks as styling.
+MarkdownParseState.prototype.addText = function addText (text) {
+  if (!text) { return }
+  var nodes = this.top().content, last = nodes[nodes.length - 1];
+  var node = this.schema.text(text, this.marks), merged;
+  if (last && (merged = maybeMerge(last, node))) { nodes[nodes.length - 1] = merged; }
+  else { nodes.push(node); }
+};
+
+// : (Mark)
+// Adds the given mark to the set of active marks.
+MarkdownParseState.prototype.openMark = function openMark (mark) {
+  this.marks = mark.addToSet(this.marks);
+};
+
+// : (Mark)
+// Removes the given mark from the set of active marks.
+MarkdownParseState.prototype.closeMark = function closeMark (mark) {
+  this.marks = mark.removeFromSet(this.marks);
+};
+
+MarkdownParseState.prototype.parseTokens = function parseTokens (toks) {
+  for (var i = 0; i < toks.length; i++) {
+    var tok = toks[i];
+    var handler = this.tokenHandlers[tok.type];
+    if (!handler)
+      { throw new Error("Token type `" + tok.type + "` not supported by Markdown parser") }
+    handler(this, tok, toks, i);
+  }
+};
+
+// : (NodeType, ?Object, ?[Node]) → ?Node
+// Add a node at the current position.
+MarkdownParseState.prototype.addNode = function addNode (type, attrs, content) {
+  var node = type.createAndFill(attrs, content, this.marks);
+  if (!node) { return null }
+  this.push(node);
+  return node
+};
+
+// : (NodeType, ?Object)
+// Wrap subsequent content in a node of the given type.
+MarkdownParseState.prototype.openNode = function openNode (type, attrs) {
+  this.stack.push({type: type, attrs: attrs, content: []});
+};
+
+// : () → ?Node
+// Close and return the node that is currently on top of the stack.
+MarkdownParseState.prototype.closeNode = function closeNode () {
+  if (this.marks.length) { this.marks = prosemirrorModel.Mark.none; }
+  var info = this.stack.pop();
+  return this.addNode(info.type, info.attrs, info.content)
+};
+
+function attrs(spec, token, tokens, i) {
+  if (spec.getAttrs) { return spec.getAttrs(token, tokens, i) }
+  // For backwards compatibility when `attrs` is a Function
+  else if (spec.attrs instanceof Function) { return spec.attrs(token) }
+  else { return spec.attrs }
+}
+
+// Code content is represented as a single token with a `content`
+// property in Markdown-it.
+function noCloseToken(spec, type) {
+  return spec.noCloseToken || type == "code_inline" || type == "code_block" || type == "fence"
+}
+
+function withoutTrailingNewline(str) {
+  return str[str.length - 1] == "\n" ? str.slice(0, str.length - 1) : str
+}
+
+function noOp() {}
+
+function tokenHandlers(schema, tokens) {
+  var handlers = Object.create(null);
+  var loop = function ( type ) {
+    var spec = tokens[type];
+    if (spec.block) {
+      var nodeType = schema.nodeType(spec.block);
+      if (noCloseToken(spec, type)) {
+        handlers[type] = function (state, tok, tokens, i) {
+          state.openNode(nodeType, attrs(spec, tok, tokens, i));
+          state.addText(withoutTrailingNewline(tok.content));
+          state.closeNode();
+        };
+      } else {
+        handlers[type + "_open"] = function (state, tok, tokens, i) { return state.openNode(nodeType, attrs(spec, tok, tokens, i)); };
+        handlers[type + "_close"] = function (state) { return state.closeNode(); };
+      }
+    } else if (spec.node) {
+      var nodeType$1 = schema.nodeType(spec.node);
+      handlers[type] = function (state, tok, tokens, i) { return state.addNode(nodeType$1, attrs(spec, tok, tokens, i)); };
+    } else if (spec.mark) {
+      var markType = schema.marks[spec.mark];
+      if (noCloseToken(spec, type)) {
+        handlers[type] = function (state, tok, tokens, i) {
+          state.openMark(markType.create(attrs(spec, tok, tokens, i)));
+          state.addText(withoutTrailingNewline(tok.content));
+          state.closeMark(markType);
+        };
+      } else {
+        handlers[type + "_open"] = function (state, tok, tokens, i) { return state.openMark(markType.create(attrs(spec, tok, tokens, i))); };
+        handlers[type + "_close"] = function (state) { return state.closeMark(markType); };
+      }
+    } else if (spec.ignore) {
+      if (noCloseToken(spec, type)) {
+        handlers[type] = noOp;
+      } else {
+        handlers[type + "_open"] = noOp;
+        handlers[type + "_close"] = noOp;
+      }
+    } else {
+      throw new RangeError("Unrecognized parsing spec " + JSON.stringify(spec))
+    }
+  };
+
+  for (var type in tokens) loop( type );
+
+  handlers.text = function (state, tok) { return state.addText(tok.content); };
+  handlers.inline = function (state, tok) { return state.parseTokens(tok.children); };
+  handlers.softbreak = handlers.softbreak || (function (state) { return state.addText("\n"); });
+
+  return handlers
+}
+
+// ::- A configuration of a Markdown parser. Such a parser uses
+// [markdown-it](https://github.com/markdown-it/markdown-it) to
+// tokenize a file, and then runs the custom rules it is given over
+// the tokens to create a ProseMirror document tree.
+var MarkdownParser = function MarkdownParser(schema, tokenizer, tokens) {
+  // :: Object The value of the `tokens` object used to construct
+  // this parser. Can be useful to copy and modify to base other
+  // parsers on.
+  this.tokens = tokens;
+  this.schema = schema;
+  // :: This parser's markdown-it tokenizer.
+  this.tokenizer = tokenizer;
+  this.tokenHandlers = tokenHandlers(schema, tokens);
+};
+
+// :: (string) → Node
+// Parse a string as [CommonMark](http://commonmark.org/) markup,
+// and create a ProseMirror document as prescribed by this parser's
+// rules.
+MarkdownParser.prototype.parse = function parse (text) {
+  var state = new MarkdownParseState(this.schema, this.tokenHandlers), doc;
+  state.parseTokens(this.tokenizer.parse(text, {}));
+  do { doc = state.closeNode(); } while (state.stack.length)
+  return doc || this.schema.topNodeType.createAndFill()
+};
+
+function listIsTight(tokens, i) {
+  while (++i < tokens.length)
+    { if (tokens[i].type != "list_item_open") { return tokens[i].hidden } }
+  return false
+}
+
+// :: MarkdownParser
+// A parser parsing unextended [CommonMark](http://commonmark.org/),
+// without inline HTML, and producing a document in the basic schema.
+var defaultMarkdownParser = new MarkdownParser(schema, markdownit__default["default"]("commonmark", {html: false}), {
+  blockquote: {block: "blockquote"},
+  paragraph: {block: "paragraph"},
+  list_item: {block: "list_item"},
+  bullet_list: {block: "bullet_list", getAttrs: function (_, tokens, i) { return ({tight: listIsTight(tokens, i)}); }},
+  ordered_list: {block: "ordered_list", getAttrs: function (tok, tokens, i) { return ({
+    order: +tok.attrGet("start") || 1,
+    tight: listIsTight(tokens, i)
+  }); }},
+  heading: {block: "heading", getAttrs: function (tok) { return ({level: +tok.tag.slice(1)}); }},
+  code_block: {block: "code_block", noCloseToken: true},
+  fence: {block: "code_block", getAttrs: function (tok) { return ({params: tok.info || ""}); }, noCloseToken: true},
+  hr: {node: "horizontal_rule"},
+  image: {node: "image", getAttrs: function (tok) { return ({
+    src: tok.attrGet("src"),
+    title: tok.attrGet("title") || null,
+    alt: tok.children[0] && tok.children[0].content || null
+  }); }},
+  hardbreak: {node: "hard_break"},
+
+  em: {mark: "em"},
+  strong: {mark: "strong"},
+  link: {mark: "link", getAttrs: function (tok) { return ({
+    href: tok.attrGet("href"),
+    title: tok.attrGet("title") || null
+  }); }},
+  code_inline: {mark: "code", noCloseToken: true}
+});
+
+// ::- A specification for serializing a ProseMirror document as
+// Markdown/CommonMark text.
+var MarkdownSerializer = function MarkdownSerializer(nodes, marks, options) {
+  // :: Object<(MarkdownSerializerState, Node)> The node serializer
+  // functions for this serializer.
+  this.nodes = nodes;
+  // :: Object The mark serializer info.
+  this.marks = marks;
+  this.options = options || {};
+};
+
+// :: (Node, ?Object) → string
+// Serialize the content of the given node to
+// [CommonMark](http://commonmark.org/).
+MarkdownSerializer.prototype.serialize = function serialize (content, options) {
+  options = Object.assign(this.options, options);
+  var state = new MarkdownSerializerState(this.nodes, this.marks, options);
+  state.renderContent(content);
+  return state.out
+};
+
+// :: MarkdownSerializer
+// A serializer for the [basic schema](#schema).
+var defaultMarkdownSerializer = new MarkdownSerializer({
+  blockquote: function blockquote(state, node) {
+    state.wrapBlock("> ", null, node, function () { return state.renderContent(node); });
+  },
+  code_block: function code_block(state, node) {
+    state.write("```" + (node.attrs.params || "") + "\n");
+    state.text(node.textContent, false);
+    state.ensureNewLine();
+    state.write("```");
+    state.closeBlock(node);
+  },
+  heading: function heading(state, node) {
+    state.write(state.repeat("#", node.attrs.level) + " ");
+    state.renderInline(node);
+    state.closeBlock(node);
+  },
+  horizontal_rule: function horizontal_rule(state, node) {
+    state.write(node.attrs.markup || "---");
+    state.closeBlock(node);
+  },
+  bullet_list: function bullet_list(state, node) {
+    state.renderList(node, "  ", function () { return (node.attrs.bullet || "*") + " "; });
+  },
+  ordered_list: function ordered_list(state, node) {
+    var start = node.attrs.order || 1;
+    var maxW = String(start + node.childCount - 1).length;
+    var space = state.repeat(" ", maxW + 2);
+    state.renderList(node, space, function (i) {
+      var nStr = String(start + i);
+      return state.repeat(" ", maxW - nStr.length) + nStr + ". "
+    });
+  },
+  list_item: function list_item(state, node) {
+    state.renderContent(node);
+  },
+  paragraph: function paragraph(state, node) {
+    state.renderInline(node);
+    state.closeBlock(node);
+  },
+
+  image: function image(state, node) {
+    state.write("![" + state.esc(node.attrs.alt || "") + "](" + node.attrs.src +
+                (node.attrs.title ? ' "' + node.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")");
+  },
+  hard_break: function hard_break(state, node, parent, index) {
+    for (var i = index + 1; i < parent.childCount; i++)
+      { if (parent.child(i).type != node.type) {
+        state.write("\\\n");
+        return
+      } }
+  },
+  text: function text(state, node) {
+    state.text(node.text);
+  }
+}, {
+  em: {open: "*", close: "*", mixable: true, expelEnclosingWhitespace: true},
+  strong: {open: "**", close: "**", mixable: true, expelEnclosingWhitespace: true},
+  link: {
+    open: function open(_state, mark, parent, index) {
+      return isPlainURL(mark, parent, index, 1) ? "<" : "["
+    },
+    close: function close(state, mark, parent, index) {
+      return isPlainURL(mark, parent, index, -1) ? ">"
+        : "](" + mark.attrs.href + (mark.attrs.title ? ' "' + mark.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")"
+    }
+  },
+  code: {open: function open(_state, _mark, parent, index) { return backticksFor(parent.child(index), -1) },
+         close: function close(_state, _mark, parent, index) { return backticksFor(parent.child(index - 1), 1) },
+         escape: false}
+});
+
+function backticksFor(node, side) {
+  var ticks = /`+/g, m, len = 0;
+  if (node.isText) { while (m = ticks.exec(node.text)) { len = Math.max(len, m[0].length); } }
+  var result = len > 0 && side > 0 ? " `" : "`";
+  for (var i = 0; i < len; i++) { result += "`"; }
+  if (len > 0 && side < 0) { result += " "; }
+  return result
+}
+
+function isPlainURL(link, parent, index, side) {
+  if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) { return false }
+  var content = parent.child(index + (side < 0 ? -1 : 0));
+  if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link) { return false }
+  if (index == (side < 0 ? 1 : parent.childCount - 1)) { return true }
+  var next = parent.child(index + (side < 0 ? -2 : 1));
+  return !link.isInSet(next.marks)
+}
+
+// ::- This is an object used to track state and expose
+// methods related to markdown serialization. Instances are passed to
+// node and mark serialization methods (see `toMarkdown`).
+var MarkdownSerializerState = function MarkdownSerializerState(nodes, marks, options) {
+  this.nodes = nodes;
+  this.marks = marks;
+  this.delim = this.out = "";
+  this.closed = false;
+  this.inTightList = false;
+  // :: Object
+  // The options passed to the serializer.
+  // tightLists:: ?bool
+  // Whether to render lists in a tight style. This can be overridden
+  // on a node level by specifying a tight attribute on the node.
+  // Defaults to false.
+  this.options = options || {};
+  if (typeof this.options.tightLists == "undefined")
+    { this.options.tightLists = false; }
+};
+
+MarkdownSerializerState.prototype.flushClose = function flushClose (size) {
+  if (this.closed) {
+    if (!this.atBlank()) { this.out += "\n"; }
+    if (size == null) { size = 2; }
+    if (size > 1) {
+      var delimMin = this.delim;
+      var trim = /\s+$/.exec(delimMin);
+      if (trim) { delimMin = delimMin.slice(0, delimMin.length - trim[0].length); }
+      for (var i = 1; i < size; i++)
+        { this.out += delimMin + "\n"; }
+    }
+    this.closed = false;
+  }
+};
+
+// :: (string, ?string, Node, ())
+// Render a block, prefixing each line with `delim`, and the first
+// line in `firstDelim`. `node` should be the node that is closed at
+// the end of the block, and `f` is a function that renders the
+// content of the block.
+MarkdownSerializerState.prototype.wrapBlock = function wrapBlock (delim, firstDelim, node, f) {
+  var old = this.delim;
+  this.write(firstDelim || delim);
+  this.delim += delim;
+  f();
+  this.delim = old;
+  this.closeBlock(node);
+};
+
+MarkdownSerializerState.prototype.atBlank = function atBlank () {
+  return /(^|\n)$/.test(this.out)
+};
+
+// :: ()
+// Ensure the current content ends with a newline.
+MarkdownSerializerState.prototype.ensureNewLine = function ensureNewLine () {
+  if (!this.atBlank()) { this.out += "\n"; }
+};
+
+// :: (?string)
+// Prepare the state for writing output (closing closed paragraphs,
+// adding delimiters, and so on), and then optionally add content
+// (unescaped) to the output.
+MarkdownSerializerState.prototype.write = function write (content) {
+  this.flushClose();
+  if (this.delim && this.atBlank())
+    { this.out += this.delim; }
+  if (content) { this.out += content; }
+};
+
+// :: (Node)
+// Close the block for the given node.
+MarkdownSerializerState.prototype.closeBlock = function closeBlock (node) {
+  this.closed = node;
+};
+
+// :: (string, ?bool)
+// Add the given text to the document. When escape is not `false`,
+// it will be escaped.
+MarkdownSerializerState.prototype.text = function text (text$1, escape) {
+  var lines = text$1.split("\n");
+  for (var i = 0; i < lines.length; i++) {
+    var startOfLine = this.atBlank() || this.closed;
+    this.write();
+    this.out += escape !== false ? this.esc(lines[i], startOfLine) : lines[i];
+    if (i != lines.length - 1) { this.out += "\n"; }
+  }
+};
+
+// :: (Node)
+// Render the given node as a block.
+MarkdownSerializerState.prototype.render = function render (node, parent, index) {
+  if (typeof parent == "number") { throw new Error("!") }
+  if (!this.nodes[node.type.name]) { throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer") }
+  this.nodes[node.type.name](this, node, parent, index);
+};
+
+// :: (Node)
+// Render the contents of `parent` as block nodes.
+MarkdownSerializerState.prototype.renderContent = function renderContent (parent) {
+    var this$1$1 = this;
+
+  parent.forEach(function (node, _, i) { return this$1$1.render(node, parent, i); });
+};
+
+// :: (Node)
+// Render the contents of `parent` as inline content.
+MarkdownSerializerState.prototype.renderInline = function renderInline (parent) {
+    var this$1$1 = this;
+
+  var active = [], trailing = "";
+  var progress = function (node, _, index) {
+    var marks = node ? node.marks : [];
+
+    // Remove marks from `hard_break` that are the last node inside
+    // that mark to prevent parser edge cases with new lines just
+    // before closing marks.
+    // (FIXME it'd be nice if we had a schema-agnostic way to
+    // identify nodes that serialize as hard breaks)
+    if (node && node.type.name === "hard_break")
+      { marks = marks.filter(function (m) {
+        if (index + 1 == parent.childCount) { return false }
+        var next = parent.child(index + 1);
+        return m.isInSet(next.marks) && (!next.isText || /\S/.test(next.text))
+      }); }
+
+    var leading = trailing;
+    trailing = "";
+    // If whitespace has to be expelled from the node, adjust
+    // leading and trailing accordingly.
+    if (node && node.isText && marks.some(function (mark) {
+      var info = this$1$1.marks[mark.type.name];
+      return info && info.expelEnclosingWhitespace
+    })) {
+      var ref = /^(\s*)(.*?)(\s*)$/m.exec(node.text);
+        ref[0];
+        var lead = ref[1];
+        var inner$1 = ref[2];
+        var trail = ref[3];
+      leading += lead;
+      trailing = trail;
+      if (lead || trail) {
+        node = inner$1 ? node.withText(inner$1) : null;
+        if (!node) { marks = active; }
+      }
+    }
+
+    var inner = marks.length && marks[marks.length - 1], noEsc = inner && this$1$1.marks[inner.type.name].escape === false;
+    var len = marks.length - (noEsc ? 1 : 0);
+
+    // Try to reorder 'mixable' marks, such as em and strong, which
+    // in Markdown may be opened and closed in different order, so
+    // that order of the marks for the token matches the order in
+    // active.
+    outer: for (var i = 0; i < len; i++) {
+      var mark = marks[i];
+      if (!this$1$1.marks[mark.type.name].mixable) { break }
+      for (var j = 0; j < active.length; j++) {
+        var other = active[j];
+        if (!this$1$1.marks[other.type.name].mixable) { break }
+        if (mark.eq(other)) {
+          if (i > j)
+            { marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len)); }
+          else if (j > i)
+            { marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len)); }
+          continue outer
+        }
+      }
+    }
+
+    // Find the prefix of the mark set that didn't change
+    var keep = 0;
+    while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) { ++keep; }
+
+    // Close the marks that need to be closed
+    while (keep < active.length)
+      { this$1$1.text(this$1$1.markString(active.pop(), false, parent, index), false); }
+
+    // Output any previously expelled trailing whitespace outside the marks
+    if (leading) { this$1$1.text(leading); }
+
+    // Open the marks that need to be opened
+    if (node) {
+      while (active.length < len) {
+        var add = marks[active.length];
+        active.push(add);
+        this$1$1.text(this$1$1.markString(add, true, parent, index), false);
+      }
+
+      // Render the node. Special case code marks, since their content
+      // may not be escaped.
+      if (noEsc && node.isText)
+        { this$1$1.text(this$1$1.markString(inner, true, parent, index) + node.text +
+                  this$1$1.markString(inner, false, parent, index + 1), false); }
+      else
+        { this$1$1.render(node, parent, index); }
+    }
+  };
+  parent.forEach(progress);
+  progress(null, null, parent.childCount);
+};
+
+// :: (Node, string, (number) → string)
+// Render a node's content as a list. `delim` should be the extra
+// indentation added to all lines except the first in an item,
+// `firstDelim` is a function going from an item index to a
+// delimiter for the first line of the item.
+MarkdownSerializerState.prototype.renderList = function renderList (node, delim, firstDelim) {
+    var this$1$1 = this;
+
+  if (this.closed && this.closed.type == node.type)
+    { this.flushClose(3); }
+  else if (this.inTightList)
+    { this.flushClose(1); }
+
+  var isTight = typeof node.attrs.tight != "undefined" ? node.attrs.tight : this.options.tightLists;
+  var prevTight = this.inTightList;
+  this.inTightList = isTight;
+  node.forEach(function (child, _, i) {
+    if (i && isTight) { this$1$1.flushClose(1); }
+    this$1$1.wrapBlock(delim, firstDelim(i), node, function () { return this$1$1.render(child, node, i); });
+  });
+  this.inTightList = prevTight;
+};
+
+// :: (string, ?bool) → string
+// Escape the given string so that it can safely appear in Markdown
+// content. If `startOfLine` is true, also escape characters that
+// have special meaning only at the start of the line.
+MarkdownSerializerState.prototype.esc = function esc (str, startOfLine) {
+  str = str.replace(
+    /[`*\\~\[\]_]/g, 
+    function (m, i) { return m == "_" && i > 0 && i + 1 < str.length && str[i-1].match(/\w/) && str[i+1].match(/\w/) ?m : "\\" + m; }
+  );
+  if (startOfLine) { str = str.replace(/^[:#\-*+>]/, "\\$&").replace(/^(\s*\d+)\./, "$1\\."); }
+  if (this.options.escapeExtraCharacters) { str = str.replace(this.options.escapeExtraCharacters, "\\$&"); }
+  return str
+};
+
+MarkdownSerializerState.prototype.quote = function quote (str) {
+  var wrap = str.indexOf('"') == -1 ? '""' : str.indexOf("'") == -1 ? "''" : "()";
+  return wrap[0] + str + wrap[1]
+};
+
+// :: (string, number) → string
+// Repeat the given string `n` times.
+MarkdownSerializerState.prototype.repeat = function repeat (str, n) {
+  var out = "";
+  for (var i = 0; i < n; i++) { out += str; }
+  return out
+};
+
+// : (Mark, bool, string?) → string
+// Get the markdown string for a given opening or closing mark.
+MarkdownSerializerState.prototype.markString = function markString (mark, open, parent, index) {
+  var info = this.marks[mark.type.name];
+  var value = open ? info.open : info.close;
+  return typeof value == "string" ? value : value(this, mark, parent, index)
+};
+
+// :: (string) → { leading: ?string, trailing: ?string }
+// Get leading and trailing whitespace from a string. Values of
+// leading or trailing property of the return object will be undefined
+// if there is no match.
+MarkdownSerializerState.prototype.getEnclosingWhitespace = function getEnclosingWhitespace (text) {
+  return {
+    leading: (text.match(/^(\s+)/) || [])[0],
+    trailing: (text.match(/(\s+)$/) || [])[0]
+  }
+};
+
+exports.MarkdownParser = MarkdownParser;
+exports.MarkdownSerializer = MarkdownSerializer;
+exports.MarkdownSerializerState = MarkdownSerializerState;
+exports.defaultMarkdownParser = defaultMarkdownParser;
+exports.defaultMarkdownSerializer = defaultMarkdownSerializer;
+exports.schema = schema;
+//# sourceMappingURL=index.js.map
diff --git a/dist/index.js.map b/dist/index.js.map
new file mode 100644
index 0000000..651a0e9
--- /dev/null
+++ b/dist/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sources":["../src/schema.js","../src/from_markdown.js","../src/to_markdown.js"],"sourcesContent":["import {Schema} from \"prosemirror-model\"\n\n// ::Schema Document schema for the data model used by CommonMark.\nexport const schema = new Schema({\n  nodes: {\n    doc: {\n      content: \"block+\"\n    },\n\n    paragraph: {\n      content: \"inline*\",\n      group: \"block\",\n      parseDOM: [{tag: \"p\"}],\n      toDOM() { return [\"p\", 0] }\n    },\n\n    blockquote: {\n      content: \"block+\",\n      group: \"block\",\n      parseDOM: [{tag: \"blockquote\"}],\n      toDOM() { return [\"blockquote\", 0] }\n    },\n\n    horizontal_rule: {\n      group: \"block\",\n      parseDOM: [{tag: \"hr\"}],\n      toDOM() { return [\"div\", [\"hr\"]] }\n    },\n\n    heading: {\n      attrs: {level: {default: 1}},\n      content: \"(text | image)*\",\n      group: \"block\",\n      defining: true,\n      parseDOM: [{tag: \"h1\", attrs: {level: 1}},\n                 {tag: \"h2\", attrs: {level: 2}},\n                 {tag: \"h3\", attrs: {level: 3}},\n                 {tag: \"h4\", attrs: {level: 4}},\n                 {tag: \"h5\", attrs: {level: 5}},\n                 {tag: \"h6\", attrs: {level: 6}}],\n      toDOM(node) { return [\"h\" + node.attrs.level, 0] }\n    },\n\n    code_block: {\n      content: \"text*\",\n      group: \"block\",\n      code: true,\n      defining: true,\n      marks: \"\",\n      attrs: {params: {default: \"\"}},\n      parseDOM: [{tag: \"pre\", preserveWhitespace: \"full\", getAttrs: node => (\n        {params: node.getAttribute(\"data-params\") || \"\"}\n      )}],\n      toDOM(node) { return [\"pre\", node.attrs.params ? {\"data-params\": node.attrs.params} : {}, [\"code\", 0]] }\n    },\n\n    ordered_list: {\n      content: \"list_item+\",\n      group: \"block\",\n      attrs: {order: {default: 1}, tight: {default: false}},\n      parseDOM: [{tag: \"ol\", getAttrs(dom) {\n        return {order: dom.hasAttribute(\"start\") ? +dom.getAttribute(\"start\") : 1,\n                tight: dom.hasAttribute(\"data-tight\")}\n      }}],\n      toDOM(node) {\n        return [\"ol\", {start: node.attrs.order == 1 ? null : node.attrs.order,\n                       \"data-tight\": node.attrs.tight ? \"true\" : null}, 0]\n      }\n    },\n\n    bullet_list: {\n      content: \"list_item+\",\n      group: \"block\",\n      attrs: {tight: {default: false}},\n      parseDOM: [{tag: \"ul\", getAttrs: dom => ({tight: dom.hasAttribute(\"data-tight\")})}],\n      toDOM(node) { return [\"ul\", {\"data-tight\": node.attrs.tight ? \"true\" : null}, 0] }\n    },\n\n    list_item: {\n      content: \"paragraph block*\",\n      defining: true,\n      parseDOM: [{tag: \"li\"}],\n      toDOM() { return [\"li\", 0] }\n    },\n\n    text: {\n      group: \"inline\"\n    },\n\n    image: {\n      inline: true,\n      attrs: {\n        src: {},\n        alt: {default: null},\n        title: {default: null}\n      },\n      group: \"inline\",\n      draggable: true,\n      parseDOM: [{tag: \"img[src]\", getAttrs(dom) {\n        return {\n          src: dom.getAttribute(\"src\"),\n          title: dom.getAttribute(\"title\"),\n          alt: dom.getAttribute(\"alt\")\n        }\n      }}],\n      toDOM(node) { return [\"img\", node.attrs] }\n    },\n\n    hard_break: {\n      inline: true,\n      group: \"inline\",\n      selectable: false,\n      parseDOM: [{tag: \"br\"}],\n      toDOM() { return [\"br\"] }\n    }\n  },\n\n  marks: {\n    em: {\n      parseDOM: [{tag: \"i\"}, {tag: \"em\"},\n                 {style: \"font-style\", getAttrs: value => value == \"italic\" && null}],\n      toDOM() { return [\"em\"] }\n    },\n\n    strong: {\n      parseDOM: [{tag: \"b\"}, {tag: \"strong\"},\n                 {style: \"font-weight\", getAttrs: value => /^(bold(er)?|[5-9]\\d{2,})$/.test(value) && null}],\n      toDOM() { return [\"strong\"] }\n    },\n\n    link: {\n      attrs: {\n        href: {},\n        title: {default: null}\n      },\n      inclusive: false,\n      parseDOM: [{tag: \"a[href]\", getAttrs(dom) {\n        return {href: dom.getAttribute(\"href\"), title: dom.getAttribute(\"title\")}\n      }}],\n      toDOM(node) { return [\"a\", node.attrs] }\n    },\n\n    code: {\n      parseDOM: [{tag: \"code\"}],\n      toDOM() { return [\"code\"] }\n    }\n  }\n})\n","import markdownit from \"markdown-it\"\nimport {schema} from \"./schema\"\nimport {Mark} from \"prosemirror-model\"\n\nfunction maybeMerge(a, b) {\n  if (a.isText && b.isText && Mark.sameSet(a.marks, b.marks))\n    return a.withText(a.text + b.text)\n}\n\n// Object used to track the context of a running parse.\nclass MarkdownParseState {\n  constructor(schema, tokenHandlers) {\n    this.schema = schema\n    this.stack = [{type: schema.topNodeType, content: []}]\n    this.marks = Mark.none\n    this.tokenHandlers = tokenHandlers\n  }\n\n  top() {\n    return this.stack[this.stack.length - 1]\n  }\n\n  push(elt) {\n    if (this.stack.length) this.top().content.push(elt)\n  }\n\n  // : (string)\n  // Adds the given text to the current position in the document,\n  // using the current marks as styling.\n  addText(text) {\n    if (!text) return\n    let nodes = this.top().content, last = nodes[nodes.length - 1]\n    let node = this.schema.text(text, this.marks), merged\n    if (last && (merged = maybeMerge(last, node))) nodes[nodes.length - 1] = merged\n    else nodes.push(node)\n  }\n\n  // : (Mark)\n  // Adds the given mark to the set of active marks.\n  openMark(mark) {\n    this.marks = mark.addToSet(this.marks)\n  }\n\n  // : (Mark)\n  // Removes the given mark from the set of active marks.\n  closeMark(mark) {\n    this.marks = mark.removeFromSet(this.marks)\n  }\n\n  parseTokens(toks) {\n    for (let i = 0; i < toks.length; i++) {\n      let tok = toks[i]\n      let handler = this.tokenHandlers[tok.type]\n      if (!handler)\n        throw new Error(\"Token type `\" + tok.type + \"` not supported by Markdown parser\")\n      handler(this, tok, toks, i)\n    }\n  }\n\n  // : (NodeType, ?Object, ?[Node]) → ?Node\n  // Add a node at the current position.\n  addNode(type, attrs, content) {\n    let node = type.createAndFill(attrs, content, this.marks)\n    if (!node) return null\n    this.push(node)\n    return node\n  }\n\n  // : (NodeType, ?Object)\n  // Wrap subsequent content in a node of the given type.\n  openNode(type, attrs) {\n    this.stack.push({type: type, attrs: attrs, content: []})\n  }\n\n  // : () → ?Node\n  // Close and return the node that is currently on top of the stack.\n  closeNode() {\n    if (this.marks.length) this.marks = Mark.none\n    let info = this.stack.pop()\n    return this.addNode(info.type, info.attrs, info.content)\n  }\n}\n\nfunction attrs(spec, token, tokens, i) {\n  if (spec.getAttrs) return spec.getAttrs(token, tokens, i)\n  // For backwards compatibility when `attrs` is a Function\n  else if (spec.attrs instanceof Function) return spec.attrs(token)\n  else return spec.attrs\n}\n\n// Code content is represented as a single token with a `content`\n// property in Markdown-it.\nfunction noCloseToken(spec, type) {\n  return spec.noCloseToken || type == \"code_inline\" || type == \"code_block\" || type == \"fence\"\n}\n\nfunction withoutTrailingNewline(str) {\n  return str[str.length - 1] == \"\\n\" ? str.slice(0, str.length - 1) : str\n}\n\nfunction noOp() {}\n\nfunction tokenHandlers(schema, tokens) {\n  let handlers = Object.create(null)\n  for (let type in tokens) {\n    let spec = tokens[type]\n    if (spec.block) {\n      let nodeType = schema.nodeType(spec.block)\n      if (noCloseToken(spec, type)) {\n        handlers[type] = (state, tok, tokens, i) => {\n          state.openNode(nodeType, attrs(spec, tok, tokens, i))\n          state.addText(withoutTrailingNewline(tok.content))\n          state.closeNode()\n        }\n      } else {\n        handlers[type + \"_open\"] = (state, tok, tokens, i) => state.openNode(nodeType, attrs(spec, tok, tokens, i))\n        handlers[type + \"_close\"] = state => state.closeNode()\n      }\n    } else if (spec.node) {\n      let nodeType = schema.nodeType(spec.node)\n      handlers[type] = (state, tok, tokens, i) => state.addNode(nodeType, attrs(spec, tok, tokens, i))\n    } else if (spec.mark) {\n      let markType = schema.marks[spec.mark]\n      if (noCloseToken(spec, type)) {\n        handlers[type] = (state, tok, tokens, i) => {\n          state.openMark(markType.create(attrs(spec, tok, tokens, i)))\n          state.addText(withoutTrailingNewline(tok.content))\n          state.closeMark(markType)\n        }\n      } else {\n        handlers[type + \"_open\"] = (state, tok, tokens, i) => state.openMark(markType.create(attrs(spec, tok, tokens, i)))\n        handlers[type + \"_close\"] = state => state.closeMark(markType)\n      }\n    } else if (spec.ignore) {\n      if (noCloseToken(spec, type)) {\n        handlers[type] = noOp\n      } else {\n        handlers[type + \"_open\"] = noOp\n        handlers[type + \"_close\"] = noOp\n      }\n    } else {\n      throw new RangeError(\"Unrecognized parsing spec \" + JSON.stringify(spec))\n    }\n  }\n\n  handlers.text = (state, tok) => state.addText(tok.content)\n  handlers.inline = (state, tok) => state.parseTokens(tok.children)\n  handlers.softbreak = handlers.softbreak || (state => state.addText(\"\\n\"))\n\n  return handlers\n}\n\n// ::- A configuration of a Markdown parser. Such a parser uses\n// [markdown-it](https://github.com/markdown-it/markdown-it) to\n// tokenize a file, and then runs the custom rules it is given over\n// the tokens to create a ProseMirror document tree.\nexport class MarkdownParser {\n  // :: (Schema, MarkdownIt, Object)\n  // Create a parser with the given configuration. You can configure\n  // the markdown-it parser to parse the dialect you want, and provide\n  // a description of the ProseMirror entities those tokens map to in\n  // the `tokens` object, which maps token names to descriptions of\n  // what to do with them. Such a description is an object, and may\n  // have the following properties:\n  //\n  // **`node`**`: ?string`\n  //   : This token maps to a single node, whose type can be looked up\n  //     in the schema under the given name. Exactly one of `node`,\n  //     `block`, or `mark` must be set.\n  //\n  // **`block`**`: ?string`\n  //   : This token (unless `noCloseToken` is true) comes in `_open`\n  //     and `_close` variants (which are appended to the base token\n  //     name provides a the object property), and wraps a block of\n  //     content. The block should be wrapped in a node of the type\n  //     named to by the property's value. If the token does not have\n  //     `_open` or `_close`, use the `noCloseToken` option.\n  //\n  // **`mark`**`: ?string`\n  //   : This token (again, unless `noCloseToken` is true) also comes\n  //     in `_open` and `_close` variants, but should add a mark\n  //     (named by the value) to its content, rather than wrapping it\n  //     in a node.\n  //\n  // **`attrs`**`: ?Object`\n  //   : Attributes for the node or mark. When `getAttrs` is provided,\n  //     it takes precedence.\n  //\n  // **`getAttrs`**`: ?(MarkdownToken) → Object`\n  //   : A function used to compute the attributes for the node or mark\n  //     that takes a [markdown-it\n  //     token](https://markdown-it.github.io/markdown-it/#Token) and\n  //     returns an attribute object.\n  //\n  // **`noCloseToken`**`: ?boolean`\n  //   : Indicates that the [markdown-it\n  //     token](https://markdown-it.github.io/markdown-it/#Token) has\n  //     no `_open` or `_close` for the nodes. This defaults to `true`\n  //     for `code_inline`, `code_block` and `fence`.\n  //\n  // **`ignore`**`: ?bool`\n  //   : When true, ignore content for the matched token.\n  constructor(schema, tokenizer, tokens) {\n    // :: Object The value of the `tokens` object used to construct\n    // this parser. Can be useful to copy and modify to base other\n    // parsers on.\n    this.tokens = tokens\n    this.schema = schema\n    // :: This parser's markdown-it tokenizer.\n    this.tokenizer = tokenizer\n    this.tokenHandlers = tokenHandlers(schema, tokens)\n  }\n\n  // :: (string) → Node\n  // Parse a string as [CommonMark](http://commonmark.org/) markup,\n  // and create a ProseMirror document as prescribed by this parser's\n  // rules.\n  parse(text) {\n    let state = new MarkdownParseState(this.schema, this.tokenHandlers), doc\n    state.parseTokens(this.tokenizer.parse(text, {}))\n    do { doc = state.closeNode() } while (state.stack.length)\n    return doc || this.schema.topNodeType.createAndFill()\n  }\n}\n\nfunction listIsTight(tokens, i) {\n  while (++i < tokens.length)\n    if (tokens[i].type != \"list_item_open\") return tokens[i].hidden\n  return false\n}\n\n// :: MarkdownParser\n// A parser parsing unextended [CommonMark](http://commonmark.org/),\n// without inline HTML, and producing a document in the basic schema.\nexport const defaultMarkdownParser = new MarkdownParser(schema, markdownit(\"commonmark\", {html: false}), {\n  blockquote: {block: \"blockquote\"},\n  paragraph: {block: \"paragraph\"},\n  list_item: {block: \"list_item\"},\n  bullet_list: {block: \"bullet_list\", getAttrs: (_, tokens, i) => ({tight: listIsTight(tokens, i)})},\n  ordered_list: {block: \"ordered_list\", getAttrs: (tok, tokens, i) => ({\n    order: +tok.attrGet(\"start\") || 1,\n    tight: listIsTight(tokens, i)\n  })},\n  heading: {block: \"heading\", getAttrs: tok => ({level: +tok.tag.slice(1)})},\n  code_block: {block: \"code_block\", noCloseToken: true},\n  fence: {block: \"code_block\", getAttrs: tok => ({params: tok.info || \"\"}), noCloseToken: true},\n  hr: {node: \"horizontal_rule\"},\n  image: {node: \"image\", getAttrs: tok => ({\n    src: tok.attrGet(\"src\"),\n    title: tok.attrGet(\"title\") || null,\n    alt: tok.children[0] && tok.children[0].content || null\n  })},\n  hardbreak: {node: \"hard_break\"},\n\n  em: {mark: \"em\"},\n  strong: {mark: \"strong\"},\n  link: {mark: \"link\", getAttrs: tok => ({\n    href: tok.attrGet(\"href\"),\n    title: tok.attrGet(\"title\") || null\n  })},\n  code_inline: {mark: \"code\", noCloseToken: true}\n})\n","// ::- A specification for serializing a ProseMirror document as\n// Markdown/CommonMark text.\nexport class MarkdownSerializer {\n  // :: (Object<(state: MarkdownSerializerState, node: Node, parent: Node, index: number)>, Object, ?Object)\n  // Construct a serializer with the given configuration. The `nodes`\n  // object should map node names in a given schema to function that\n  // take a serializer state and such a node, and serialize the node.\n  //\n  // The `marks` object should hold objects with `open` and `close`\n  // properties, which hold the strings that should appear before and\n  // after a piece of text marked that way, either directly or as a\n  // function that takes a serializer state and a mark, and returns a\n  // string. `open` and `close` can also be functions, which will be\n  // called as\n  //\n  //     (state: MarkdownSerializerState, mark: Mark,\n  //      parent: Fragment, index: number) → string\n  //\n  // Where `parent` and `index` allow you to inspect the mark's\n  // context to see which nodes it applies to.\n  //\n  // Mark information objects can also have a `mixable` property\n  // which, when `true`, indicates that the order in which the mark's\n  // opening and closing syntax appears relative to other mixable\n  // marks can be varied. (For example, you can say `**a *b***` and\n  // `*a **b***`, but not `` `a *b*` ``.)\n  //\n  // To disable character escaping in a mark, you can give it an\n  // `escape` property of `false`. Such a mark has to have the highest\n  // precedence (must always be the innermost mark).\n  //\n  // The `expelEnclosingWhitespace` mark property causes the\n  // serializer to move enclosing whitespace from inside the marks to\n  // outside the marks. This is necessary for emphasis marks as\n  // CommonMark does not permit enclosing whitespace inside emphasis\n  // marks, see: http://spec.commonmark.org/0.26/#example-330\n  //\n  //   options::- Optional additional options.\n  //     escapeExtraCharacters:: ?RegExp\n  //     Extra characters can be added for escaping. This is passed\n  //     directly to String.replace(), and the matching characters are\n  //     preceded by a backslash.\n  constructor(nodes, marks, options) {\n    // :: Object<(MarkdownSerializerState, Node)> The node serializer\n    // functions for this serializer.\n    this.nodes = nodes\n    // :: Object The mark serializer info.\n    this.marks = marks\n    this.options = options || {}\n  }\n\n  // :: (Node, ?Object) → string\n  // Serialize the content of the given node to\n  // [CommonMark](http://commonmark.org/).\n  serialize(content, options) {\n    options = Object.assign(this.options, options)\n    let state = new MarkdownSerializerState(this.nodes, this.marks, options)\n    state.renderContent(content)\n    return state.out\n  }\n}\n\n// :: MarkdownSerializer\n// A serializer for the [basic schema](#schema).\nexport const defaultMarkdownSerializer = new MarkdownSerializer({\n  blockquote(state, node) {\n    state.wrapBlock(\"> \", null, node, () => state.renderContent(node))\n  },\n  code_block(state, node) {\n    state.write(\"```\" + (node.attrs.params || \"\") + \"\\n\")\n    state.text(node.textContent, false)\n    state.ensureNewLine()\n    state.write(\"```\")\n    state.closeBlock(node)\n  },\n  heading(state, node) {\n    state.write(state.repeat(\"#\", node.attrs.level) + \" \")\n    state.renderInline(node)\n    state.closeBlock(node)\n  },\n  horizontal_rule(state, node) {\n    state.write(node.attrs.markup || \"---\")\n    state.closeBlock(node)\n  },\n  bullet_list(state, node) {\n    state.renderList(node, \"  \", () => (node.attrs.bullet || \"*\") + \" \")\n  },\n  ordered_list(state, node) {\n    let start = node.attrs.order || 1\n    let maxW = String(start + node.childCount - 1).length\n    let space = state.repeat(\" \", maxW + 2)\n    state.renderList(node, space, i => {\n      let nStr = String(start + i)\n      return state.repeat(\" \", maxW - nStr.length) + nStr + \". \"\n    })\n  },\n  list_item(state, node) {\n    state.renderContent(node)\n  },\n  paragraph(state, node) {\n    state.renderInline(node)\n    state.closeBlock(node)\n  },\n\n  image(state, node) {\n    state.write(\"![\" + state.esc(node.attrs.alt || \"\") + \"](\" + node.attrs.src +\n                (node.attrs.title ? ' \"' + node.attrs.title.replace(/\"/g, '\\\\\"') + '\"' : \"\") + \")\")\n  },\n  hard_break(state, node, parent, index) {\n    for (let i = index + 1; i < parent.childCount; i++)\n      if (parent.child(i).type != node.type) {\n        state.write(\"\\\\\\n\")\n        return\n      }\n  },\n  text(state, node) {\n    state.text(node.text)\n  }\n}, {\n  em: {open: \"*\", close: \"*\", mixable: true, expelEnclosingWhitespace: true},\n  strong: {open: \"**\", close: \"**\", mixable: true, expelEnclosingWhitespace: true},\n  link: {\n    open(_state, mark, parent, index) {\n      return isPlainURL(mark, parent, index, 1) ? \"<\" : \"[\"\n    },\n    close(state, mark, parent, index) {\n      return isPlainURL(mark, parent, index, -1) ? \">\"\n        : \"](\" + mark.attrs.href + (mark.attrs.title ? ' \"' + mark.attrs.title.replace(/\"/g, '\\\\\"') + '\"' : \"\") + \")\"\n    }\n  },\n  code: {open(_state, _mark, parent, index) { return backticksFor(parent.child(index), -1) },\n         close(_state, _mark, parent, index) { return backticksFor(parent.child(index - 1), 1) },\n         escape: false}\n})\n\nfunction backticksFor(node, side) {\n  let ticks = /`+/g, m, len = 0\n  if (node.isText) while (m = ticks.exec(node.text)) len = Math.max(len, m[0].length)\n  let result = len > 0 && side > 0 ? \" `\" : \"`\"\n  for (let i = 0; i < len; i++) result += \"`\"\n  if (len > 0 && side < 0) result += \" \"\n  return result\n}\n\nfunction isPlainURL(link, parent, index, side) {\n  if (link.attrs.title || !/^\\w+:/.test(link.attrs.href)) return false\n  let content = parent.child(index + (side < 0 ? -1 : 0))\n  if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link) return false\n  if (index == (side < 0 ? 1 : parent.childCount - 1)) return true\n  let next = parent.child(index + (side < 0 ? -2 : 1))\n  return !link.isInSet(next.marks)\n}\n\n// ::- This is an object used to track state and expose\n// methods related to markdown serialization. Instances are passed to\n// node and mark serialization methods (see `toMarkdown`).\nexport class MarkdownSerializerState {\n  constructor(nodes, marks, options) {\n    this.nodes = nodes\n    this.marks = marks\n    this.delim = this.out = \"\"\n    this.closed = false\n    this.inTightList = false\n    // :: Object\n    // The options passed to the serializer.\n    //   tightLists:: ?bool\n    //   Whether to render lists in a tight style. This can be overridden\n    //   on a node level by specifying a tight attribute on the node.\n    //   Defaults to false.\n    this.options = options || {}\n    if (typeof this.options.tightLists == \"undefined\")\n      this.options.tightLists = false\n  }\n\n  flushClose(size) {\n    if (this.closed) {\n      if (!this.atBlank()) this.out += \"\\n\"\n      if (size == null) size = 2\n      if (size > 1) {\n        let delimMin = this.delim\n        let trim = /\\s+$/.exec(delimMin)\n        if (trim) delimMin = delimMin.slice(0, delimMin.length - trim[0].length)\n        for (let i = 1; i < size; i++)\n          this.out += delimMin + \"\\n\"\n      }\n      this.closed = false\n    }\n  }\n\n  // :: (string, ?string, Node, ())\n  // Render a block, prefixing each line with `delim`, and the first\n  // line in `firstDelim`. `node` should be the node that is closed at\n  // the end of the block, and `f` is a function that renders the\n  // content of the block.\n  wrapBlock(delim, firstDelim, node, f) {\n    let old = this.delim\n    this.write(firstDelim || delim)\n    this.delim += delim\n    f()\n    this.delim = old\n    this.closeBlock(node)\n  }\n\n  atBlank() {\n    return /(^|\\n)$/.test(this.out)\n  }\n\n  // :: ()\n  // Ensure the current content ends with a newline.\n  ensureNewLine() {\n    if (!this.atBlank()) this.out += \"\\n\"\n  }\n\n  // :: (?string)\n  // Prepare the state for writing output (closing closed paragraphs,\n  // adding delimiters, and so on), and then optionally add content\n  // (unescaped) to the output.\n  write(content) {\n    this.flushClose()\n    if (this.delim && this.atBlank())\n      this.out += this.delim\n    if (content) this.out += content\n  }\n\n  // :: (Node)\n  // Close the block for the given node.\n  closeBlock(node) {\n    this.closed = node\n  }\n\n  // :: (string, ?bool)\n  // Add the given text to the document. When escape is not `false`,\n  // it will be escaped.\n  text(text, escape) {\n    let lines = text.split(\"\\n\")\n    for (let i = 0; i < lines.length; i++) {\n      var startOfLine = this.atBlank() || this.closed\n      this.write()\n      this.out += escape !== false ? this.esc(lines[i], startOfLine) : lines[i]\n      if (i != lines.length - 1) this.out += \"\\n\"\n    }\n  }\n\n  // :: (Node)\n  // Render the given node as a block.\n  render(node, parent, index) {\n    if (typeof parent == \"number\") throw new Error(\"!\")\n    if (!this.nodes[node.type.name]) throw new Error(\"Token type `\" + node.type.name + \"` not supported by Markdown renderer\")\n    this.nodes[node.type.name](this, node, parent, index)\n  }\n\n  // :: (Node)\n  // Render the contents of `parent` as block nodes.\n  renderContent(parent) {\n    parent.forEach((node, _, i) => this.render(node, parent, i))\n  }\n\n  // :: (Node)\n  // Render the contents of `parent` as inline content.\n  renderInline(parent) {\n    let active = [], trailing = \"\"\n    let progress = (node, _, index) => {\n      let marks = node ? node.marks : []\n\n      // Remove marks from `hard_break` that are the last node inside\n      // that mark to prevent parser edge cases with new lines just\n      // before closing marks.\n      // (FIXME it'd be nice if we had a schema-agnostic way to\n      // identify nodes that serialize as hard breaks)\n      if (node && node.type.name === \"hard_break\")\n        marks = marks.filter(m => {\n          if (index + 1 == parent.childCount) return false\n          let next = parent.child(index + 1)\n          return m.isInSet(next.marks) && (!next.isText || /\\S/.test(next.text))\n        })\n\n      let leading = trailing\n      trailing = \"\"\n      // If whitespace has to be expelled from the node, adjust\n      // leading and trailing accordingly.\n      if (node && node.isText && marks.some(mark => {\n        let info = this.marks[mark.type.name]\n        return info && info.expelEnclosingWhitespace\n      })) {\n        let [_, lead, inner, trail] = /^(\\s*)(.*?)(\\s*)$/m.exec(node.text)\n        leading += lead\n        trailing = trail\n        if (lead || trail) {\n          node = inner ? node.withText(inner) : null\n          if (!node) marks = active\n        }\n      }\n\n      let inner = marks.length && marks[marks.length - 1], noEsc = inner && this.marks[inner.type.name].escape === false\n      let len = marks.length - (noEsc ? 1 : 0)\n\n      // Try to reorder 'mixable' marks, such as em and strong, which\n      // in Markdown may be opened and closed in different order, so\n      // that order of the marks for the token matches the order in\n      // active.\n      outer: for (let i = 0; i < len; i++) {\n        let mark = marks[i]\n        if (!this.marks[mark.type.name].mixable) break\n        for (let j = 0; j < active.length; j++) {\n          let other = active[j]\n          if (!this.marks[other.type.name].mixable) break\n          if (mark.eq(other)) {\n            if (i > j)\n              marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len))\n            else if (j > i)\n              marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len))\n            continue outer\n          }\n        }\n      }\n\n      // Find the prefix of the mark set that didn't change\n      let keep = 0\n      while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) ++keep\n\n      // Close the marks that need to be closed\n      while (keep < active.length)\n        this.text(this.markString(active.pop(), false, parent, index), false)\n\n      // Output any previously expelled trailing whitespace outside the marks\n      if (leading) this.text(leading)\n\n      // Open the marks that need to be opened\n      if (node) {\n        while (active.length < len) {\n          let add = marks[active.length]\n          active.push(add)\n          this.text(this.markString(add, true, parent, index), false)\n        }\n\n        // Render the node. Special case code marks, since their content\n        // may not be escaped.\n        if (noEsc && node.isText)\n          this.text(this.markString(inner, true, parent, index) + node.text +\n                    this.markString(inner, false, parent, index + 1), false)\n        else\n          this.render(node, parent, index)\n      }\n    }\n    parent.forEach(progress)\n    progress(null, null, parent.childCount)\n  }\n\n  // :: (Node, string, (number) → string)\n  // Render a node's content as a list. `delim` should be the extra\n  // indentation added to all lines except the first in an item,\n  // `firstDelim` is a function going from an item index to a\n  // delimiter for the first line of the item.\n  renderList(node, delim, firstDelim) {\n    if (this.closed && this.closed.type == node.type)\n      this.flushClose(3)\n    else if (this.inTightList)\n      this.flushClose(1)\n\n    let isTight = typeof node.attrs.tight != \"undefined\" ? node.attrs.tight : this.options.tightLists\n    let prevTight = this.inTightList\n    this.inTightList = isTight\n    node.forEach((child, _, i) => {\n      if (i && isTight) this.flushClose(1)\n      this.wrapBlock(delim, firstDelim(i), node, () => this.render(child, node, i))\n    })\n    this.inTightList = prevTight\n  }\n\n  // :: (string, ?bool) → string\n  // Escape the given string so that it can safely appear in Markdown\n  // content. If `startOfLine` is true, also escape characters that\n  // have special meaning only at the start of the line.\n  esc(str, startOfLine) {\n    str = str.replace(\n      /[`*\\\\~\\[\\]_]/g, \n      (m, i) => m == \"_\" && i > 0 && i + 1 < str.length && str[i-1].match(/\\w/) && str[i+1].match(/\\w/) ?  m : \"\\\\\" + m\n    )\n    if (startOfLine) str = str.replace(/^[:#\\-*+>]/, \"\\\\$&\").replace(/^(\\s*\\d+)\\./, \"$1\\\\.\")\n    if (this.options.escapeExtraCharacters) str = str.replace(this.options.escapeExtraCharacters, \"\\\\$&\")\n    return str\n  }\n\n  quote(str) {\n    var wrap = str.indexOf('\"') == -1 ? '\"\"' : str.indexOf(\"'\") == -1 ? \"''\" : \"()\"\n    return wrap[0] + str + wrap[1]\n  }\n\n  // :: (string, number) → string\n  // Repeat the given string `n` times.\n  repeat(str, n) {\n    let out = \"\"\n    for (let i = 0; i < n; i++) out += str\n    return out\n  }\n\n  // : (Mark, bool, string?) → string\n  // Get the markdown string for a given opening or closing mark.\n  markString(mark, open, parent, index) {\n    let info = this.marks[mark.type.name]\n    let value = open ? info.open : info.close\n    return typeof value == \"string\" ? value : value(this, mark, parent, index)\n  }\n\n  // :: (string) → { leading: ?string, trailing: ?string }\n  // Get leading and trailing whitespace from a string. Values of\n  // leading or trailing property of the return object will be undefined\n  // if there is no match.\n  getEnclosingWhitespace(text) {\n    return {\n      leading: (text.match(/^(\\s+)/) || [])[0],\n      trailing: (text.match(/(\\s+)$/) || [])[0]\n    }\n  }\n}\n"],"names":["Schema","Mark","let","nodeType","markdownit","text","this","inner"],"mappings":";;;;;;;;;;;AAEA;AACY,IAAC,MAAM,GAAG,IAAIA,uBAAM,CAAC;AACjC,EAAE,KAAK,EAAE;AACT,IAAI,GAAG,EAAE;AACT,MAAM,OAAO,EAAE,QAAQ;AACvB,KAAK;AACL;AACA,IAAI,SAAS,EAAE;AACf,MAAM,OAAO,EAAE,SAAS;AACxB,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5B,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE;AACjC,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,OAAO,EAAE,QAAQ;AACvB,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACrC,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE;AAC1C,KAAK;AACL;AACA,IAAI,eAAe,EAAE;AACrB,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7B,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE;AACxC,KAAK;AACL;AACA,IAAI,OAAO,EAAE;AACb,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAClC,MAAM,OAAO,EAAE,iBAAiB;AAChC,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,QAAQ,EAAE,IAAI;AACpB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/C,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/C,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/C,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/C,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/C,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AAChD,MAAM,qBAAK,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE;AACxD,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,OAAO,EAAE,OAAO;AACtB,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,IAAI,EAAE,IAAI;AAChB,MAAM,QAAQ,EAAE,IAAI;AACpB,MAAM,KAAK,EAAE,EAAE;AACf,MAAM,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpC,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,QAAQ,YAAE;AACpE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AACxD,UAAO,CAAC,CAAC;AACT,MAAM,qBAAK,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;AAC9G,KAAK;AACL;AACA,IAAI,YAAY,EAAE;AAClB,MAAM,OAAO,EAAE,YAAY;AAC3B,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC3D,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,2BAAQ,CAAC,GAAG,EAAE;AAC3C,QAAQ,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC;AACjF,gBAAgB,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;AACtD,OAAO,CAAC,CAAC;AACT,MAAM,qBAAK,CAAC,IAAI,EAAE;AAClB,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK;AAC7E,uBAAuB,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1E,OAAO;AACP,KAAK;AACL;AACA,IAAI,WAAW,EAAE;AACjB,MAAM,OAAO,EAAE,YAAY;AAC3B,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACtC,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,YAAE,eAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,IAAC,CAAC,CAAC;AACzF,MAAM,qBAAK,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE;AACxF,KAAK;AACL;AACA,IAAI,SAAS,EAAE;AACf,MAAM,OAAO,EAAE,kBAAkB;AACjC,MAAM,QAAQ,EAAE,IAAI;AACpB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7B,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE;AAClC,KAAK;AACL;AACA,IAAI,IAAI,EAAE;AACV,MAAM,KAAK,EAAE,QAAQ;AACrB,KAAK;AACL;AACA,IAAI,KAAK,EAAE;AACX,MAAM,MAAM,EAAE,IAAI;AAClB,MAAM,KAAK,EAAE;AACb,QAAQ,GAAG,EAAE,EAAE;AACf,QAAQ,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;AAC5B,QAAQ,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;AAC9B,OAAO;AACP,MAAM,KAAK,EAAE,QAAQ;AACrB,MAAM,SAAS,EAAE,IAAI;AACrB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,2BAAQ,CAAC,GAAG,EAAE;AACjD,QAAQ,OAAO;AACf,UAAU,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC;AACtC,UAAU,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;AAC1C,UAAU,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC;AACtC,SAAS;AACT,OAAO,CAAC,CAAC;AACT,MAAM,qBAAK,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;AAChD,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,MAAM,EAAE,IAAI;AAClB,MAAM,KAAK,EAAE,QAAQ;AACrB,MAAM,UAAU,EAAE,KAAK;AACvB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7B,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/B,KAAK;AACL,GAAG;AACH;AACA,EAAE,KAAK,EAAE;AACT,IAAI,EAAE,EAAE;AACR,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC;AACxC,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,YAAE,gBAAS,KAAK,IAAI,QAAQ,IAAI,OAAI,CAAC,CAAC;AACrF,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/B,KAAK;AACL;AACA,IAAI,MAAM,EAAE;AACZ,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC;AAC5C,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,YAAE,gBAAS,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAI,CAAC,CAAC;AAC5G,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE;AACnC,KAAK;AACL;AACA,IAAI,IAAI,EAAE;AACV,MAAM,KAAK,EAAE;AACb,QAAQ,IAAI,EAAE,EAAE;AAChB,QAAQ,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;AAC9B,OAAO;AACP,MAAM,SAAS,EAAE,KAAK;AACtB,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,2BAAQ,CAAC,GAAG,EAAE;AAChD,QAAQ,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AACjF,OAAO,CAAC,CAAC;AACT,MAAM,qBAAK,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;AAC9C,KAAK;AACL;AACA,IAAI,IAAI,EAAE;AACV,MAAM,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/B,MAAM,qBAAK,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;AACjC,KAAK;AACL,GAAG;AACH,CAAC;;AC/ID,SAAS,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE;AAC1B,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAIC,qBAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;AAC5D,MAAI,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,GAAC;AACtC,CAAC;AACD;AACA;AACA,IAAM,kBAAkB,GACtB,2BAAW,CAAC,MAAM,EAAE,aAAa,EAAE;AACrC,EAAI,IAAI,CAAC,MAAM,GAAG,OAAM;AACxB,EAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,EAAC;AAC1D,EAAI,IAAI,CAAC,KAAK,GAAGA,qBAAI,CAAC,KAAI;AAC1B,EAAI,IAAI,CAAC,aAAa,GAAG,cAAa;AACpC,EAAC;AACH;6BACE,sBAAM;AACR,EAAI,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1C,EAAC;AACH;6BACE,sBAAK,GAAG,EAAE;AACZ,EAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAE,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAC;AACrD,EAAC;AACH;AACE;AACA;AACA;6BACA,4BAAQ,IAAI,EAAE;AAChB,EAAI,IAAI,CAAC,IAAI,IAAE,QAAM;AACrB,EAAIC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAC;AAClE,EAAIA,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,OAAM;AACzD,EAAI,IAAI,IAAI,KAAK,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,SAAM;AACnF,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,IAAC;AACvB,EAAC;AACH;AACE;AACA;6BACA,8BAAS,IAAI,EAAE;AACjB,EAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAC;AACxC,EAAC;AACH;AACE;AACA;6BACA,gCAAU,IAAI,EAAE;AAClB,EAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAC;AAC7C,EAAC;AACH;6BACE,oCAAY,IAAI,EAAE;AACpB,EAAI,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC1C,IAAMA,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,EAAC;AACvB,IAAMA,IAAI,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAC;AAChD,IAAM,IAAI,CAAC,OAAO;AAClB,QAAQ,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,GAAG,CAAC,IAAI,GAAG,oCAAoC,GAAC;AACzF,IAAM,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAC;AACjC,GAAK;AACH,EAAC;AACH;AACE;AACA;6BACA,4BAAQ,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;AAChC,EAAIA,IAAI,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAC;AAC7D,EAAI,IAAI,CAAC,IAAI,IAAE,OAAO,MAAI;AAC1B,EAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;AACnB,EAAI,OAAO,IAAI;AACb,EAAC;AACH;AACE;AACA;6BACA,8BAAS,IAAI,EAAE,KAAK,EAAE;AACxB,EAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,EAAC;AAC1D,EAAC;AACH;AACE;AACA;6BACA,kCAAY;AACd,EAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAE,IAAI,CAAC,KAAK,GAAGD,qBAAI,CAAC,OAAI;AACjD,EAAIC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAE;AAC/B,EAAI,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC;AAC1D,EACD;AACD;AACA,SAAS,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE;AACvC,EAAE,IAAI,IAAI,CAAC,QAAQ,IAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,GAAC;AAC3D;AACA,OAAO,IAAI,IAAI,CAAC,KAAK,YAAY,QAAQ,IAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAC;AACnE,SAAO,OAAO,IAAI,CAAC,OAAK;AACxB,CAAC;AACD;AACA;AACA;AACA,SAAS,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE;AAClC,EAAE,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,IAAI,YAAY,IAAI,IAAI,IAAI,OAAO;AAC9F,CAAC;AACD;AACA,SAAS,sBAAsB,CAAC,GAAG,EAAE;AACrC,EAAE,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG;AACzE,CAAC;AACD;AACA,SAAS,IAAI,GAAG,EAAE;AAClB;AACA,SAAS,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE;AACvC,EAAEA,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAC;AACpC,+BAA2B;AAC3B,IAAIA,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,EAAC;AAC3B,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;AACpB,MAAMA,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAC;AAChD,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACpC,QAAQ,QAAQ,CAAC,IAAI,CAAC,aAAI,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAK;AACpD,UAAU,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,EAAC;AAC/D,UAAU,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAC;AAC5D,UAAU,KAAK,CAAC,SAAS,GAAE;AAC3B,UAAS;AACT,OAAO,MAAM;AACb,QAAQ,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,aAAI,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,WAAK,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAC;AACnH,QAAQ,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,aAAG,gBAAS,KAAK,CAAC,SAAS,MAAE;AAC9D,OAAO;AACP,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AAC1B,MAAMA,IAAIC,UAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAC;AAC/C,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAI,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,WAAK,KAAK,CAAC,OAAO,CAACA,UAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAC;AACtG,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AAC1B,MAAMD,IAAI,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAC;AAC5C,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACpC,QAAQ,QAAQ,CAAC,IAAI,CAAC,aAAI,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAK;AACpD,UAAU,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAC;AACtE,UAAU,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAC;AAC5D,UAAU,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAC;AACnC,UAAS;AACT,OAAO,MAAM;AACb,QAAQ,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,aAAI,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,WAAK,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,KAAC;AAC1H,QAAQ,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,aAAG,gBAAS,KAAK,CAAC,SAAS,CAAC,QAAQ,KAAC;AACtE,OAAO;AACP,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE;AAC5B,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACpC,QAAQ,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAI;AAC7B,OAAO,MAAM;AACb,QAAQ,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,KAAI;AACvC,QAAQ,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,KAAI;AACxC,OAAO;AACP,KAAK,MAAM;AACX,MAAM,MAAM,IAAI,UAAU,CAAC,4BAA4B,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC/E,KAAK;AACL;;EAvCE,KAAKA,IAAI,IAAI,IAAI,MAAM,eAuCtB;AACH;AACA,EAAE,QAAQ,CAAC,IAAI,aAAI,KAAK,EAAE,GAAG,WAAK,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAC;AAC5D,EAAE,QAAQ,CAAC,MAAM,aAAI,KAAK,EAAE,GAAG,WAAK,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,KAAC;AACnE,EAAE,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,eAAK,gBAAS,KAAK,CAAC,OAAO,CAAC,IAAI,IAAC,EAAC;AAC3E;AACA,EAAE,OAAO,QAAQ;AACjB,CAAC;AACD;AACA;AACA;AACA;AACA;IACa,cAAc,GA8CzB,uBAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;AACzC;AACA;AACA;AACA,EAAI,IAAI,CAAC,MAAM,GAAG,OAAM;AACxB,EAAI,IAAI,CAAC,MAAM,GAAG,OAAM;AACxB;AACA,EAAI,IAAI,CAAC,SAAS,GAAG,UAAS;AAC9B,EAAI,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAC;AACpD,EAAC;AACH;AACE;AACA;AACA;AACA;yBACA,wBAAM,IAAI,EAAE;AACd,EAAIA,IAAI,KAAK,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,IAAG;AAC5E,EAAI,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,EAAC;AACrD,EAAI,GAAG,EAAE,GAAG,GAAG,KAAK,CAAC,SAAS,GAAE,EAAE,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7D,EAAI,OAAO,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE;AACvD,EACD;AACD;AACA,SAAS,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE;AAChC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM;AAC5B,MAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,gBAAgB,IAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,UAAM;AACnE,EAAE,OAAO,KAAK;AACd,CAAC;AACD;AACA;AACA;AACA;AACY,IAAC,qBAAqB,GAAG,IAAI,cAAc,CAAC,MAAM,EAAEE,8BAAU,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE;AACzG,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC;AACnC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;AACjC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;AACjC,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,YAAG,CAAC,EAAE,MAAM,EAAE,CAAC,YAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAC,CAAC;AACpG,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,YAAG,GAAG,EAAE,MAAM,EAAE,CAAC,YAAM;AACvE,IAAI,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;AACrC,IAAI,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;AACjC,GAAG,IAAC,CAAC;AACL,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,YAAE,eAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAC,CAAC;AAC5E,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,CAAC;AACvD,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,YAAE,eAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,IAAC,EAAE,YAAY,EAAE,IAAI,CAAC;AAC/F,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC;AAC/B,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,YAAE,eAAQ;AAC3C,IAAI,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;AAC3B,IAAI,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI;AACvC,IAAI,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI;AAC3D,GAAG,IAAC,CAAC;AACL,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;AACjC;AACA,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;AAClB,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC1B,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,YAAE,eAAQ;AACzC,IAAI,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;AAC7B,IAAI,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI;AACvC,GAAG,IAAC,CAAC;AACL,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC;AACjD,CAAC;;ACrQD;AACA;IACa,kBAAkB,GAwC7B,2BAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;AACrC;AACA;AACA,EAAI,IAAI,CAAC,KAAK,GAAG,MAAK;AACtB;AACA,EAAI,IAAI,CAAC,KAAK,GAAG,MAAK;AACtB,EAAI,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,GAAE;AAC9B,EAAC;AACH;AACE;AACA;AACA;6BACA,gCAAU,OAAO,EAAE,OAAO,EAAE;AAC9B,EAAI,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAC;AAClD,EAAIF,IAAI,KAAK,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAC;AAC5E,EAAI,KAAK,CAAC,aAAa,CAAC,OAAO,EAAC;AAChC,EAAI,OAAO,KAAK,CAAC,GAAG;AAClB,EACD;AACD;AACA;AACA;AACY,IAAC,yBAAyB,GAAG,IAAI,kBAAkB,CAAC;AAChE,EAAE,+BAAU,CAAC,KAAK,EAAE,IAAI,EAAE;AAC1B,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,uBAAQ,KAAK,CAAC,aAAa,CAAC,IAAI,IAAC,EAAC;AACtE,GAAG;AACH,EAAE,+BAAU,CAAC,KAAK,EAAE,IAAI,EAAE;AAC1B,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,IAAI,EAAC;AACzD,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAC;AACvC,IAAI,KAAK,CAAC,aAAa,GAAE;AACzB,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAC;AACtB,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAC;AAC1B,GAAG;AACH,EAAE,yBAAO,CAAC,KAAK,EAAE,IAAI,EAAE;AACvB,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,EAAC;AAC1D,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,EAAC;AAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAC;AAC1B,GAAG;AACH,EAAE,yCAAe,CAAC,KAAK,EAAE,IAAI,EAAE;AAC/B,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,EAAC;AAC3C,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAC;AAC1B,GAAG;AACH,EAAE,iCAAW,CAAC,KAAK,EAAE,IAAI,EAAE;AAC3B,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,uBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,IAAI,MAAG,EAAC;AACxE,GAAG;AACH,EAAE,mCAAY,CAAC,KAAK,EAAE,IAAI,EAAE;AAC5B,IAAIA,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAC;AACrC,IAAIA,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,OAAM;AACzD,IAAIA,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,EAAC;AAC3C,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,YAAE,GAAK;AACvC,MAAMA,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,EAAC;AAClC,MAAM,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI;AAChE,KAAK,EAAC;AACN,GAAG;AACH,EAAE,6BAAS,CAAC,KAAK,EAAE,IAAI,EAAE;AACzB,IAAI,KAAK,CAAC,aAAa,CAAC,IAAI,EAAC;AAC7B,GAAG;AACH,EAAE,6BAAS,CAAC,KAAK,EAAE,IAAI,EAAE;AACzB,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,EAAC;AAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAC;AAC1B,GAAG;AACH;AACA,EAAE,qBAAK,CAAC,KAAK,EAAE,IAAI,EAAE;AACrB,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG;AAC9E,iBAAiB,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAC;AACnG,GAAG;AACH,EAAE,+BAAU,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AACzC,IAAI,KAAKA,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE;AACtD,QAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;AAC7C,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,EAAC;AAC3B,QAAQ,MAAM;AACd,SAAO;AACP,GAAG;AACH,EAAE,mBAAI,CAAC,KAAK,EAAE,IAAI,EAAE;AACpB,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;AACzB,GAAG;AACH,CAAC,EAAE;AACH,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,CAAC;AAC5E,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,CAAC;AAClF,EAAE,IAAI,EAAE;AACR,IAAI,mBAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AACtC,MAAM,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG;AAC3D,KAAK;AACL,IAAI,qBAAK,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AACtC,MAAM,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;AACtD,UAAU,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;AACrH,KAAK;AACL,GAAG;AACH,EAAE,IAAI,EAAE,CAAC,mBAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAC5F,SAAS,qBAAK,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AAChG,SAAS,MAAM,EAAE,KAAK,CAAC;AACvB,CAAC,EAAC;AACF;AACA,SAAS,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE;AAClC,EAAEA,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC,EAAE,GAAG,GAAG,EAAC;AAC/B,EAAE,IAAI,IAAI,CAAC,MAAM,IAAE,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,MAAC;AACrF,EAAEA,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAG;AAC/C,EAAE,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,IAAE,MAAM,IAAI,MAAG;AAC7C,EAAE,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAE,MAAM,IAAI,MAAG;AACxC,EAAE,OAAO,MAAM;AACf,CAAC;AACD;AACA,SAAS,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE;AAC/C,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAE,OAAO,OAAK;AACtE,EAAEA,IAAI,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC;AACzD,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,IAAE,OAAO,OAAK;AACzH,EAAE,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,IAAE,OAAO,MAAI;AAClE,EAAEA,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAC;AACtD,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AAClC,CAAC;AACD;AACA;AACA;AACA;IACa,uBAAuB,GAClC,gCAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;AACrC,EAAI,IAAI,CAAC,KAAK,GAAG,MAAK;AACtB,EAAI,IAAI,CAAC,KAAK,GAAG,MAAK;AACtB,EAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,GAAG,GAAE;AAC9B,EAAI,IAAI,CAAC,MAAM,GAAG,MAAK;AACvB,EAAI,IAAI,CAAC,WAAW,GAAG,MAAK;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,EAAI,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,GAAE;AAChC,EAAI,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,WAAW;AACrD,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,QAAK;AACnC,EAAC;AACH;kCACE,kCAAW,IAAI,EAAE;AACnB,EAAI,IAAI,IAAI,CAAC,MAAM,EAAE;AACrB,IAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAE,IAAI,CAAC,GAAG,IAAI,OAAI;AAC3C,IAAM,IAAI,IAAI,IAAI,IAAI,IAAE,IAAI,GAAG,IAAC;AAChC,IAAM,IAAI,IAAI,GAAG,CAAC,EAAE;AACpB,MAAQA,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAK;AACjC,MAAQA,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAC;AACxC,MAAQ,IAAI,IAAI,IAAE,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAC;AAChF,MAAQ,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;AACrC,UAAU,IAAI,CAAC,GAAG,IAAI,QAAQ,GAAG,OAAI;AACrC,KAAO;AACP,IAAM,IAAI,CAAC,MAAM,GAAG,MAAK;AACzB,GAAK;AACH,EAAC;AACH;AACE;AACA;AACA;AACA;AACA;kCACA,gCAAU,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE;AACxC,EAAIA,IAAI,GAAG,GAAG,IAAI,CAAC,MAAK;AACxB,EAAI,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,EAAC;AACnC,EAAI,IAAI,CAAC,KAAK,IAAI,MAAK;AACvB,EAAI,CAAC,GAAE;AACP,EAAI,IAAI,CAAC,KAAK,GAAG,IAAG;AACpB,EAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAC;AACvB,EAAC;AACH;kCACE,8BAAU;AACZ,EAAI,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACjC,EAAC;AACH;AACE;AACA;kCACA,0CAAgB;AAClB,EAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAE,IAAI,CAAC,GAAG,IAAI,OAAI;AACvC,EAAC;AACH;AACE;AACA;AACA;AACA;kCACA,wBAAM,OAAO,EAAE;AACjB,EAAI,IAAI,CAAC,UAAU,GAAE;AACrB,EAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE;AACpC,MAAM,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,QAAK;AAC5B,EAAI,IAAI,OAAO,IAAE,IAAI,CAAC,GAAG,IAAI,UAAO;AAClC,EAAC;AACH;AACE;AACA;kCACA,kCAAW,IAAI,EAAE;AACnB,EAAI,IAAI,CAAC,MAAM,GAAG,KAAI;AACpB,EAAC;AACH;AACE;AACA;AACA;kCACA,sBAAKG,MAAI,EAAE,MAAM,EAAE;AACrB,EAAIH,IAAI,KAAK,GAAGG,MAAI,CAAC,KAAK,CAAC,IAAI,EAAC;AAChC,EAAI,KAAKH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC3C,IAAM,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,OAAM;AACrD,IAAM,IAAI,CAAC,KAAK,GAAE;AAClB,IAAM,IAAI,CAAC,GAAG,IAAI,MAAM,KAAK,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,EAAC;AAC/E,IAAM,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAE,IAAI,CAAC,GAAG,IAAI,OAAI;AACjD,GAAK;AACH,EAAC;AACH;AACE;AACA;kCACA,0BAAO,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AAC9B,EAAI,IAAI,OAAO,MAAM,IAAI,QAAQ,IAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAC;AACvD,EAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,sCAAsC,GAAC;AAC9H,EAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAC;AACvD,EAAC;AACH;AACE;AACA;kCACA,wCAAc,MAAM,EAAE;;AAAC;AACzB,EAAI,MAAM,CAAC,OAAO,WAAE,IAAI,EAAE,CAAC,EAAE,CAAC,WAAKI,QAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAC,EAAC;AAC9D,EAAC;AACH;AACE;AACA;kCACA,sCAAa,MAAM,EAAE;;AAAC;AACxB,EAAIJ,IAAI,MAAM,GAAG,EAAE,EAAE,QAAQ,GAAG,GAAE;AAClC,EAAIA,IAAI,QAAQ,aAAI,IAAI,EAAE,CAAC,EAAE,KAAK,EAAK;AACvC,IAAMA,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,GAAE;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,IAAM,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY;AACjD,QAAQ,KAAK,GAAG,KAAK,CAAC,MAAM,WAAC,GAAK;AAClC,QAAU,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,IAAE,OAAO,OAAK;AAC1D,QAAUA,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAC;AAC5C,QAAU,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChF,OAAS,IAAC;AACV;AACA,IAAMA,IAAI,OAAO,GAAG,SAAQ;AAC5B,IAAM,QAAQ,GAAG,GAAE;AACnB;AACA;AACA,IAAM,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,WAAC,MAAQ;AACpD,MAAQA,IAAI,IAAI,GAAGI,QAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;AAC7C,MAAQ,OAAO,IAAI,IAAI,IAAI,CAAC,wBAAwB;AACpD,KAAO,CAAC,EAAE;AACV,aAAmC,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;;QAAzD;QAAM;QAAO,mBAA6C;AAC1E,MAAQ,OAAO,IAAI,KAAI;AACvB,MAAQ,QAAQ,GAAG,MAAK;AACxB,MAAQ,IAAI,IAAI,IAAI,KAAK,EAAE;AAC3B,QAAU,IAAI,GAAGC,OAAK,GAAG,IAAI,CAAC,QAAQ,CAACA,OAAK,CAAC,GAAG,KAAI;AACpD,QAAU,IAAI,CAAC,IAAI,IAAE,KAAK,GAAG,SAAM;AACnC,OAAS;AACT,KAAO;AACP;AACA,IAAML,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,IAAII,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAK;AACxH,IAAMJ,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,EAAC;AAC9C;AACA;AACA;AACA;AACA;AACA,IAAM,KAAK,EAAE,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;AAC3C,MAAQA,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,EAAC;AAC3B,MAAQ,IAAI,CAACI,QAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,IAAE,OAAK;AACtD,MAAQ,KAAKJ,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAChD,QAAUA,IAAI,KAAK,GAAG,MAAM,CAAC,CAAC,EAAC;AAC/B,QAAU,IAAI,CAACI,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,IAAE,OAAK;AACzD,QAAU,IAAI,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAC9B,UAAY,IAAI,CAAC,GAAG,CAAC;AACrB,cAAc,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,IAAC;AAC9G,eAAiB,IAAI,CAAC,GAAG,CAAC;AAC1B,cAAc,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAC;AAC9G,UAAY,SAAS,KAAK;AAC1B,SAAW;AACX,OAAS;AACT,KAAO;AACP;AACA;AACA,IAAMJ,IAAI,IAAI,GAAG,EAAC;AAClB,IAAM,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAE,EAAE,OAAI;AACxF;AACA;AACA,IAAM,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM;AACjC,QAAQI,QAAI,CAAC,IAAI,CAACA,QAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,IAAC;AAC7E;AACA;AACA,IAAM,IAAI,OAAO,IAAEA,QAAI,CAAC,IAAI,CAAC,OAAO,IAAC;AACrC;AACA;AACA,IAAM,IAAI,IAAI,EAAE;AAChB,MAAQ,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;AACpC,QAAUJ,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAC;AACxC,QAAU,MAAM,CAAC,IAAI,CAAC,GAAG,EAAC;AAC1B,QAAUI,QAAI,CAAC,IAAI,CAACA,QAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAC;AACrE,OAAS;AACT;AACA;AACA;AACA,MAAQ,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM;AAChC,UAAUA,QAAI,CAAC,IAAI,CAACA,QAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI;AAC3E,kBAAoBA,QAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,IAAC;AAC5E;AACA,UAAUA,QAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAC;AAC1C,KAAO;AACP,IAAK;AACL,EAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAC;AAC5B,EAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,EAAC;AACzC,EAAC;AACH;AACE;AACA;AACA;AACA;AACA;kCACA,kCAAW,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE;;AAAC;AACvC,EAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;AACpD,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,IAAC;AACxB,OAAS,IAAI,IAAI,CAAC,WAAW;AAC7B,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,IAAC;AACxB;AACA,EAAIJ,IAAI,OAAO,GAAG,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,WAAU;AACrG,EAAIA,IAAI,SAAS,GAAG,IAAI,CAAC,YAAW;AACpC,EAAI,IAAI,CAAC,WAAW,GAAG,QAAO;AAC9B,EAAI,IAAI,CAAC,OAAO,WAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAK;AAClC,IAAM,IAAI,CAAC,IAAI,OAAO,IAAEI,QAAI,CAAC,UAAU,CAAC,CAAC,IAAC;AAC1C,IAAMA,QAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,uBAAQA,QAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,IAAC,EAAC;AACnF,GAAK,EAAC;AACN,EAAI,IAAI,CAAC,WAAW,GAAG,UAAS;AAC9B,EAAC;AACH;AACE;AACA;AACA;AACA;kCACA,oBAAI,GAAG,EAAE,WAAW,EAAE;AACxB,EAAI,GAAG,GAAG,GAAG,CAAC,OAAO;AACrB,IAAM,eAAe;AACrB,cAAO,CAAC,EAAE,CAAC,WAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAI,CAAC,GAAG,IAAI,GAAG,IAAC;AACvH,IAAK;AACL,EAAI,IAAI,WAAW,IAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,IAAC;AAC5F,EAAI,IAAI,IAAI,CAAC,OAAO,CAAC,qBAAqB,IAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,IAAC;AACzG,EAAI,OAAO,GAAG;AACZ,EAAC;AACH;kCACE,wBAAM,GAAG,EAAE;AACb,EAAI,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,KAAI;AACnF,EAAI,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;AAChC,EAAC;AACH;AACE;AACA;kCACA,0BAAO,GAAG,EAAE,CAAC,EAAE;AACjB,EAAIJ,IAAI,GAAG,GAAG,GAAE;AAChB,EAAI,KAAKA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAE,GAAG,IAAI,MAAG;AAC1C,EAAI,OAAO,GAAG;AACZ,EAAC;AACH;AACE;AACA;kCACA,kCAAW,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;AACxC,EAAIA,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;AACzC,EAAIA,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAK;AAC7C,EAAI,OAAO,OAAO,KAAK,IAAI,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC;AAC5E,EAAC;AACH;AACE;AACA;AACA;AACA;kCACA,0DAAuB,IAAI,EAAE;AAC/B,EAAI,OAAO;AACX,IAAM,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC9C,IAAM,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC/C,GAAK;AACH;;;;;;;;;"}
\ No newline at end of file
diff --git a/package.json b/package.json
index f121b88..b215956 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "prosemirror-markdown",
-  "version": "1.6.0",
+  "version": "1.8.0",
   "description": "ProseMirror Markdown integration",
   "main": "dist/index.js",
   "module": "dist/index.es.js",
@@ -17,12 +17,12 @@
     "url": "git://github.com/prosemirror/prosemirror-markdown.git"
   },
   "dependencies": {
-    "prosemirror-model": "^1.0.0",
-    "markdown-it": "^10.0.0"
+    "markdown-it": "^12.0.0",
+    "prosemirror-model": "^1.0.0"
   },
   "devDependencies": {
     "ist": "1.0.0",
-    "mocha": "^3.0.2",
+    "mocha": "^9.1.2",
     "prosemirror-test-builder": "^1.0.0",
     "punycode": "^1.4.0",
     "rollup": "^2.26.3",
diff --git a/src/from_markdown.js b/src/from_markdown.js
index 5037dfd..38f067b 100644
--- a/src/from_markdown.js
+++ b/src/from_markdown.js
@@ -135,8 +135,8 @@ function tokenHandlers(schema, tokens) {
       if (noCloseToken(spec, type)) {
         handlers[type] = noOp
       } else {
-        handlers[type + '_open'] = noOp
-        handlers[type + '_close'] = noOp
+        handlers[type + "_open"] = noOp
+        handlers[type + "_close"] = noOp
       }
     } else {
       throw new RangeError("Unrecognized parsing spec " + JSON.stringify(spec))
@@ -219,7 +219,7 @@ export class MarkdownParser {
     let state = new MarkdownParseState(this.schema, this.tokenHandlers), doc
     state.parseTokens(this.tokenizer.parse(text, {}))
     do { doc = state.closeNode() } while (state.stack.length)
-    return doc
+    return doc || this.schema.topNodeType.createAndFill()
   }
 }
 
diff --git a/src/to_markdown.js b/src/to_markdown.js
index a5a3edd..6863344 100644
--- a/src/to_markdown.js
+++ b/src/to_markdown.js
@@ -1,7 +1,7 @@
 // ::- A specification for serializing a ProseMirror document as
 // Markdown/CommonMark text.
 export class MarkdownSerializer {
-  // :: (Object<(state: MarkdownSerializerState, node: Node, parent: Node, index: number)>, Object)
+  // :: (Object<(state: MarkdownSerializerState, node: Node, parent: Node, index: number)>, Object, ?Object)
   // Construct a serializer with the given configuration. The `nodes`
   // object should map node names in a given schema to function that
   // take a serializer state and such a node, and serialize the node.
@@ -34,18 +34,26 @@ export class MarkdownSerializer {
   // outside the marks. This is necessary for emphasis marks as
   // CommonMark does not permit enclosing whitespace inside emphasis
   // marks, see: http://spec.commonmark.org/0.26/#example-330
-  constructor(nodes, marks) {
+  //
+  //   options::- Optional additional options.
+  //     escapeExtraCharacters:: ?RegExp
+  //     Extra characters can be added for escaping. This is passed
+  //     directly to String.replace(), and the matching characters are
+  //     preceded by a backslash.
+  constructor(nodes, marks, options) {
     // :: Object<(MarkdownSerializerState, Node)> The node serializer
     // functions for this serializer.
     this.nodes = nodes
     // :: Object The mark serializer info.
     this.marks = marks
+    this.options = options || {}
   }
 
   // :: (Node, ?Object) → string
   // Serialize the content of the given node to
   // [CommonMark](http://commonmark.org/).
   serialize(content, options) {
+    options = Object.assign(this.options, options)
     let state = new MarkdownSerializerState(this.nodes, this.marks, options)
     state.renderContent(content)
     return state.out
@@ -95,8 +103,8 @@ export const defaultMarkdownSerializer = new MarkdownSerializer({
   },
 
   image(state, node) {
-    state.write("![" + state.esc(node.attrs.alt || "") + "](" + state.esc(node.attrs.src) +
-                (node.attrs.title ? " " + state.quote(node.attrs.title) : "") + ")")
+    state.write("![" + state.esc(node.attrs.alt || "") + "](" + node.attrs.src +
+                (node.attrs.title ? ' "' + node.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")")
   },
   hard_break(state, node, parent, index) {
     for (let i = index + 1; i < parent.childCount; i++)
@@ -117,7 +125,7 @@ export const defaultMarkdownSerializer = new MarkdownSerializer({
     },
     close(state, mark, parent, index) {
       return isPlainURL(mark, parent, index, -1) ? ">"
-        : "](" + state.esc(mark.attrs.href) + (mark.attrs.title ? " " + state.quote(mark.attrs.title) : "") + ")"
+        : "](" + mark.attrs.href + (mark.attrs.title ? ' "' + mark.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")"
     }
   },
   code: {open(_state, _mark, parent, index) { return backticksFor(parent.child(index), -1) },
@@ -364,8 +372,12 @@ export class MarkdownSerializerState {
   // content. If `startOfLine` is true, also escape characters that
   // have special meaning only at the start of the line.
   esc(str, startOfLine) {
-    str = str.replace(/[`*\\~\[\]]/g, "\\$&")
+    str = str.replace(
+      /[`*\\~\[\]_]/g, 
+      (m, i) => m == "_" && i > 0 && i + 1 < str.length && str[i-1].match(/\w/) && str[i+1].match(/\w/) ?  m : "\\" + m
+    )
     if (startOfLine) str = str.replace(/^[:#\-*+>]/, "\\$&").replace(/^(\s*\d+)\./, "$1\\.")
+    if (this.options.escapeExtraCharacters) str = str.replace(this.options.escapeExtraCharacters, "\\$&")
     return str
   }
 
diff --git a/test/build.js b/test/build.js
deleted file mode 100644
index 25a108b..0000000
--- a/test/build.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const {builders} = require("prosemirror-test-builder")
-const {schema} = require("..")
-
-module.exports = builders(schema, {
-  p: {nodeType: "paragraph"},
-  h1: {nodeType: "heading", level: 1},
-  h2: {nodeType: "heading", level: 2},
-  hr: {nodeType: "horizontal_rule"},
-  li: {nodeType: "list_item"},
-  ol: {nodeType: "ordered_list"},
-  ol3: {nodeType: "ordered_list", order: 3},
-  ul: {nodeType: "bullet_list"},
-  pre: {nodeType: "code_block"},
-  a: {markType: "link", href: "foo"},
-  br: {nodeType: "hard_break"},
-  img: {nodeType: "image", src: "img.png", alt: "x"}
-})
diff --git a/test/test-custom-parser.js b/test/test-custom-parser.js
deleted file mode 100644
index 6d7d9d0..0000000
--- a/test/test-custom-parser.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const {eq} = require("prosemirror-test-builder")
-const ist = require("ist")
-
-const markdownit = require("markdown-it")
-const {schema, MarkdownParser} = require("..")
-
-const {doc, p, hard_break} = require("./build")
-
-const md = markdownit("commonmark", {html: false})
-const ignoreBlockquoteParser = new MarkdownParser(schema, md, {
-  blockquote: {ignore: true},
-  paragraph: {block: "paragraph"},
-  softbreak: {node: 'hard_break'}
-})
-
-function parseWith(parser) {
-  return (text, doc) => {
-    ist(parser.parse(text), doc, eq)
-  }
-}
-
-describe("custom markdown parser", () => {
-  it("ignores a blockquote", () =>
-     parseWith(ignoreBlockquoteParser)("> hello!",
-          doc(p("hello!"))))
-
-  it("converts softbreaks to hard_break nodes", () =>
-    parseWith(ignoreBlockquoteParser)("hello\nworld!",
-         doc(p("hello", hard_break(), 'world!'))))
-})
diff --git a/test/test-parse.js b/test/test-parse.js
deleted file mode 100644
index c762d3c..0000000
--- a/test/test-parse.js
+++ /dev/null
@@ -1,147 +0,0 @@
-const {eq} = require("prosemirror-test-builder")
-const ist = require("ist")
-
-const {schema, defaultMarkdownParser, defaultMarkdownSerializer} = require("..")
-
-const {doc, blockquote, h1, h2, p, hr, li, ol, ol3, ul, pre, em, strong, code, a, link, br, img} = require("./build")
-
-function parse(text, doc) {
-  ist(defaultMarkdownParser.parse(text), doc, eq)
-}
-
-function serialize(doc, text) {
-  ist(defaultMarkdownSerializer.serialize(doc), text)
-}
-
-function same(text, doc) {
-  parse(text, doc)
-  serialize(doc, text)
-}
-
-describe("markdown", () => {
-  it("parses a paragraph", () =>
-     same("hello!",
-          doc(p("hello!"))))
-
-  it("parses headings", () =>
-     same("# one\n\n## two\n\nthree",
-          doc(h1("one"), h2("two"), p("three"))))
-
-  it("parses a blockquote", () =>
-     same("> once\n\n> > twice",
-          doc(blockquote(p("once")), blockquote(blockquote(p("twice"))))))
-
-  // FIXME bring back testing for preserving bullets and tight attrs
-  // when supported again
-
-  it("parses a bullet list", () =>
-     same("* foo\n\n  * bar\n\n  * baz\n\n* quux",
-          doc(ul(li(p("foo"), ul(li(p("bar")), li(p("baz")))), li(p("quux"))))))
-
-  it("parses an ordered list", () =>
-     same("1. Hello\n\n2. Goodbye\n\n3. Nest\n\n   1. Hey\n\n   2. Aye",
-          doc(ol(li(p("Hello")), li(p("Goodbye")), li(p("Nest"), ol(li(p("Hey")), li(p("Aye"))))))))
-
-  it("preserves ordered list start number", () =>
-     same("3. Foo\n\n4. Bar",
-          doc(ol3(li(p("Foo")), li(p("Bar"))))))
-
-  it("parses a code block", () =>
-     same("Some code:\n\n```\nHere it is\n```\n\nPara",
-          doc(p("Some code:"), schema.node("code_block", {params: ""}, [schema.text("Here it is")]), p("Para"))))
-
-  it("parses an intended code block", () =>
-     parse("Some code:\n\n    Here it is\n\nPara",
-          doc(p("Some code:"), pre("Here it is"), p("Para"))))
-
-  it("parses a fenced code block with info string", () =>
-     same("foo\n\n```javascript\n1\n```",
-          doc(p("foo"), schema.node("code_block", {params: "javascript"}, [schema.text("1")]))))
-
-  it("parses inline marks", () =>
-     same("Hello. Some *em* text, some **strong** text, and some `code`",
-          doc(p("Hello. Some ", em("em"), " text, some ", strong("strong"), " text, and some ", code("code")))))
-
-  it("parses overlapping inline marks", () =>
-     same("This is **strong *emphasized text with `code` in* it**",
-          doc(p("This is ", strong("strong ", em("emphasized text with ", code("code"), " in"), " it")))))
-
-  it("parses links inside strong text", () =>
-     same("**[link](foo) is bold**",
-          doc(p(strong(a("link"), " is bold")))))
-
-  it("parses code mark inside strong text", () =>
-     same("**`code` is bold**",
-          doc(p(strong(code("code"), " is bold")))))
-
-  it("parses code mark containing backticks", () =>
-     same("``` one backtick: ` two backticks: `` ```",
-          doc(p(code("one backtick: ` two backticks: ``")))))
-
-  it("parses code mark containing only whitespace", () =>
-     serialize(doc(p("Three spaces: ", code("   "))),
-               "Three spaces: `   `"))
-
-  it("parses links", () =>
-     same("My [link](foo) goes to foo",
-          doc(p("My ", a("link"), " goes to foo"))))
-
-  it("parses urls", () =>
-     same("Link to <https://prosemirror.net>",
-          doc(p("Link to ", link({href: "https://prosemirror.net"}, "https://prosemirror.net")))))
-
-  it("correctly serializes relative urls", () => {
-    same("[foo.html](foo.html)",
-         doc(p(link({href: "foo.html"}, "foo.html"))))
-  })
-
-  it("parses emphasized urls", () =>
-     same("Link to *<https://prosemirror.net>*",
-          doc(p("Link to ", em(link({href: "https://prosemirror.net"}, "https://prosemirror.net"))))))
-
-  it("parses an image", () =>
-     same("Here's an image: ![x](img.png)",
-          doc(p("Here's an image: ", img))))
-
-  it("parses a line break", () =>
-     same("line one\\\nline two",
-          doc(p("line one", br, "line two"))))
-
-  it("parses a horizontal rule", () =>
-     same("one two\n\n---\n\nthree",
-          doc(p("one two"), hr, p("three"))))
-
-  it("ignores HTML tags", () =>
-     same("Foo < img> bar",
-          doc(p("Foo < img> bar"))))
-
-  it("doesn't accidentally generate list markup", () =>
-     same("1\\. foo",
-          doc(p("1. foo"))))
-
-  it("doesn't fail with line break inside inline mark", () =>
-     same("**text1\ntext2**", doc(p(strong("text1\ntext2")))))
-
-  it("drops trailing hard breaks", () =>
-     serialize(doc(p("a", br, br)), "a"))
-
-  it("expels enclosing whitespace from inside emphasis", () =>
-     serialize(doc(p("Some emphasized text with", strong(em("  whitespace   ")), "surrounding the emphasis.")),
-               "Some emphasized text with  ***whitespace***   surrounding the emphasis."))
-
-  it("drops nodes when all whitespace is expelled from them", () =>
-     serialize(doc(p("Text with", em(" "), "an emphasized space")),
-               "Text with an emphasized space"))
-
-  it("preserves list tightness", () => {
-    same("* foo\n* bar", doc(ul({tight: true}, li(p("foo")), li(p("bar")))))
-    same("1. foo\n2. bar", doc(ol({tight: true}, li(p("foo")), li(p("bar")))))
-  })
-
-  it("doesn't put a code block after a list item inside the list item", () =>
-     same("* list item\n\n```\ncode\n```",
-          doc(ul({tight: true}, li(p("list item"))), pre("code"))))
-
-  it("doesn't escape characters in code", () =>
-     same("foo`*`", doc(p("foo", code("*")))))
-})