From 5f7a117102de39a655ff1bd8b7c7ff535a359b16 Mon Sep 17 00:00:00 2001 From: leandrom-humanforce Date: Mon, 22 Apr 2024 10:33:05 +1000 Subject: [PATCH] changes --- .obsidian/app.json | 4 +- .obsidian/community-plugins.json | 4 + .obsidian/graph.json | 22 + .../obsidian-enhancing-mindmap/main.js | 37769 ++++++++++++++++ .../obsidian-enhancing-mindmap/manifest.json | 10 + .../obsidian-enhancing-mindmap/styles.css | 175 + .obsidian/plugins/obsidian-plugin-toc/main.js | 20 + .../plugins/obsidian-plugin-toc/manifest.json | 10 + .../plugins/table-editor-obsidian/data.json | 6 + .../plugins/table-editor-obsidian/main.js | 28989 ++++++++++++ .../table-editor-obsidian/manifest.json | 17 + .../plugins/table-editor-obsidian/styles.css | 78 + .obsidian/workspace.json | 139 +- 2024-04-12.md | 0 2024-04-16.md | 0 ...-d23e-4dc9-8fa6-5391fa175bea_3000x2250.png | Bin 0 -> 110139 bytes ...d23e-4dc9-8fa6-5391fa175bea_3000x2250.webp | Bin 0 -> 31480 bytes Untitled.canvas | 1 + ...-c3f4-43d1-8842-d8ccc3cd2f75_3000x2250.png | Bin 0 -> 186816 bytes assets/image_1672704213276_0.png.md | 0 ...the Unhappiness of Software Developers.pdf | Bin 0 -> 610952 bytes .../What Makes a Great Software Engineer.pdf | Bin 0 -> 672429 bytes src/DotNet/Libraries/Playwright.md | 12 - .../Microsoft.FeatureManagement.md | 0 src/Management/Code Reviews.md | 1 + src/Management/Community Of Practice.md | 2 +- src/Management/Developer Experience.md | 10 + src/Management/Engineering Management.md | 34 + src/Management/Metrics.md | 12 +- src/Testing/MsTest.md | 1 + src/Testing/Playwright using .NET.md | 24 + src/Testing/Playwright using TypeScript.md | 208 + .../Libraries => Testing}/WireMockNet.md | 0 src/Tools/Kubernetes.md | 40 + src/Tools/Sql Server.md | 79 +- src/Tools/Tye.md | 170 - 36 files changed, 67541 insertions(+), 296 deletions(-) create mode 100644 .obsidian/community-plugins.json create mode 100644 .obsidian/graph.json create mode 100644 .obsidian/plugins/obsidian-enhancing-mindmap/main.js create mode 100644 .obsidian/plugins/obsidian-enhancing-mindmap/manifest.json create mode 100644 .obsidian/plugins/obsidian-enhancing-mindmap/styles.css create mode 100644 .obsidian/plugins/obsidian-plugin-toc/main.js create mode 100644 .obsidian/plugins/obsidian-plugin-toc/manifest.json create mode 100644 .obsidian/plugins/table-editor-obsidian/data.json create mode 100644 .obsidian/plugins/table-editor-obsidian/main.js create mode 100644 .obsidian/plugins/table-editor-obsidian/manifest.json create mode 100644 .obsidian/plugins/table-editor-obsidian/styles.css create mode 100644 2024-04-12.md create mode 100644 2024-04-16.md create mode 100644 44aedbbb-d23e-4dc9-8fa6-5391fa175bea_3000x2250.png create mode 100644 44aedbbb-d23e-4dc9-8fa6-5391fa175bea_3000x2250.webp create mode 100644 Untitled.canvas create mode 100644 a0a584bd-c3f4-43d1-8842-d8ccc3cd2f75_3000x2250.png create mode 100644 assets/image_1672704213276_0.png.md create mode 100644 papers/On the Unhappiness of Software Developers.pdf create mode 100644 papers/What Makes a Great Software Engineer.pdf delete mode 100644 src/DotNet/Libraries/Playwright.md rename src/{DotNet/Libraries => FeatureManagement}/Microsoft.FeatureManagement.md (100%) create mode 100644 src/Management/Code Reviews.md create mode 100644 src/Management/Developer Experience.md create mode 100644 src/Management/Engineering Management.md create mode 100644 src/Testing/MsTest.md create mode 100644 src/Testing/Playwright using .NET.md create mode 100644 src/Testing/Playwright using TypeScript.md rename src/{DotNet/Libraries => Testing}/WireMockNet.md (100%) delete mode 100644 src/Tools/Tye.md diff --git a/.obsidian/app.json b/.obsidian/app.json index 9e26dfeeb..6abe4c134 100644 --- a/.obsidian/app.json +++ b/.obsidian/app.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "alwaysUpdateLinks": true +} \ No newline at end of file diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json new file mode 100644 index 000000000..1ca655481 --- /dev/null +++ b/.obsidian/community-plugins.json @@ -0,0 +1,4 @@ +[ + "obsidian-plugin-toc", + "table-editor-obsidian" +] \ No newline at end of file diff --git a/.obsidian/graph.json b/.obsidian/graph.json new file mode 100644 index 000000000..e21a18dc2 --- /dev/null +++ b/.obsidian/graph.json @@ -0,0 +1,22 @@ +{ + "collapse-filter": true, + "search": "", + "showTags": false, + "showAttachments": false, + "hideUnresolved": false, + "showOrphans": true, + "collapse-color-groups": true, + "colorGroups": [], + "collapse-display": true, + "showArrow": false, + "textFadeMultiplier": 0, + "nodeSizeMultiplier": 1, + "lineSizeMultiplier": 1, + "collapse-forces": true, + "centerStrength": 0.518713248970312, + "repelStrength": 10, + "linkStrength": 1, + "linkDistance": 250, + "scale": 1, + "close": false +} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-enhancing-mindmap/main.js b/.obsidian/plugins/obsidian-enhancing-mindmap/main.js new file mode 100644 index 000000000..f07ca9063 --- /dev/null +++ b/.obsidian/plugins/obsidian-enhancing-mindmap/main.js @@ -0,0 +1,37769 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ROLLUP +if you want to view the source visit the plugins github repository +*/ + +'use strict'; + +var obsidian = require('obsidian'); + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +function around(obj, factories) { + const removers = Object.keys(factories).map(key => around1(obj, key, factories[key])); + return removers.length === 1 ? removers[0] : function () { removers.forEach(r => r()); }; +} +function around1(obj, method, createWrapper) { + const original = obj[method], hadOwn = obj.hasOwnProperty(method); + let current = createWrapper(original); + // Let our wrapper inherit static props from the wrapping method, + // and the wrapping method, props from the original method + if (original) + Object.setPrototypeOf(current, original); + Object.setPrototypeOf(wrapper, current); + obj[method] = wrapper; + // Return a callback to allow safe removal + return remove; + function wrapper(...args) { + // If we have been deactivated and are no longer wrapped, remove ourselves + if (current === original && obj[method] === wrapper) + remove(); + return current.apply(this, args); + } + function remove() { + // If no other patches, just do a direct removal + if (obj[method] === wrapper) { + if (hadOwn) + obj[method] = original; + else + delete obj[method]; + } + if (current === original) + return; + // Else pass future calls through, and remove wrapper from the prototype chain + current = original; + Object.setPrototypeOf(wrapper, original || Function); + } +} + +// العربية +var ar = {}; + +// čeština +var cz = {}; + +// Dansk +var da = {}; + +// Deutsch +var de = { + // main.ts + "Open as mindmap board": "Öffne als Mindmap", + "Create new mindmap": "Erstelle neue Mindmap", + "New mindmap board": "Neue Mindmap", + "Untitled mindmap": "Unbenannte Mindmap", + "Open as markdown": "Öffne als Markdown", + //Execute.ts + "Sub title": "Untertitel", + "Export to opml": "Exportiere als opml", + "Export to image": "Exportiere als Bild", + //setting + "Canvas size": "Leinwandgröße", + "Canvas size desc": "Breite und Höhe der Leinwand", + "Canvas background": "Leinwand Hintergrund", + "Canvas background desc": "Hintergrundfarbe der Leinwand", + "Max level of node to markdown head": "Maximale Knotenebene welche eine Überschrift erstellt", + "Max level of node to markdown head desc": "Angeben, welche Knotenebene eine separate Überschrift anstelle eines Listenelements erstellt.", + "Font size": "Schriftgröße", + "Font size desc": "Gebe die Schriftgröße ans", + "Mind map layout direct": "Mindmap Layout", + "Mind map layout direct desc": "Geben Sie die Richtung an, in der die Knoten in Ihrer Mindmap platziert werden.", + "Right": "Rechts", + "Left": "Links", + "Centered": "Zentriert" +}; + +// English +var en = { + // main.ts + "Open as mindmap board": "Open as mindmap board", + "Create new mindmap": "Create new mindmap", + "New mindmap board": "New mindmap board", + "Untitled mindmap": "Untitled mindmap", + "Open as markdown": "Open as markdown", + //Execute.ts + "Sub title": "Sub title", + "Export to opml": "Export to opml", + "Export to image": "Export to image", + //setting + "Canvas size": "Canvas size", + "Canvas size desc": "Width and height of the canvas", + "Canvas background": "Canvas background", + "Canvas background desc": "Background color of canvas", + "Max level of node to markdown head": "Max level of node to create a Heading", + "Max level of node to markdown head desc": "Specify which Node Level creates a seperate Heading instead of a List-Item", + "Font size": "Font Size", + "Font size desc": "Specify the Font Size", + "Mind map layout direct": "Mindmap Layout", + "Mind map layout direct desc": "Specify the direction the nodes are placed in your Mindmap", + "Right": "Right", + "Left": "Left", + "Centered": "Centered", + "Clockwise": "Clockwise", + "Stroke Array": "Stroke array", + "Stroke Array Desc": "Node link color base on this value or random color", + "Save fail": "Save data err", + "Save success": "Save data success", + "Toggle markdown/mindmap": "Toggle to markdown/mindmap mode", + "Copy node": "Copy", + "Paste node": "Paste", + "Export to html": "Export to html" +}; + +// British English +var enGB = {}; + +// Español +var es = {}; + +// français +var fr = {}; + +// हिन्दी +var hi = {}; + +// Bahasa Indonesia +var id = {}; + +// Italiano +var it = {}; + +// 日本語 +var ja = {}; + +// 한국어 +var ko = {}; + +// Nederlands +var nl = {}; + +// Norsk +var no = {}; + +// język polski +var pl = {}; + +// Português +var pt = {}; + +// Português do Brasil +// Brazilian Portuguese +var ptBR = {}; + +// Română +var ro = {}; + +// русский +var ru = {}; + +// Türkçe +var tr = {}; + +// 简体中文 +var zhCN = { + // main.ts + "Open as mindmap board": "打开为思维导图", + "Create new mindmap": "创建新思维导图", + "New mindmap board": "新建思维导图", + "Untitled mindmap": "未命名思维导图", + "Open as markdown": "打开为 Markdown 文件", + //Execute.ts + "Sub title": "新节点", + "Export to opml": "导出至OPML", + "Export to image": "导出至图片", + //setting + "Canvas size": "画布尺寸", + "Canvas size desc": "绘制思维导图画布的宽度和高度", + "Canvas background": "背景颜色", + "Canvas background desc": "画布的背景颜色", + "Max level of node to markdown head": "节点文字转为markdown标题的最大层级", + "Max level of node to markdown head desc": "将小于该层级的节点文字转为markdown标题,最大层级为6,因为HTML标题支持最大为6级", + "Font size": "文字大小", + "Font size desc": "思维导图文字默认大小,单位px", + "Mind map layout direct": "思维导图布局方向", + "Mind map layout direct desc": "思维导图的布局方向,分为向两侧发散、仅右侧、仅左侧三个方向", + // wait to use + "Expand node": "展开节点", + "Collapse node": "收缩节点", + "Only show this node": "仅显示该节点", + "Expand all node": "展开所有节点", + "Collapse all node": "收缩所有节点", + "Add relate link": "添加联系线", + "Remove relate link": "删除联系线", + "Add summary node": "添加归纳", + "Remove summary node": "删除归纳", + "Remove node": "删除节点", + "Only remove this node": "仅删除该节点", + "Add child node": "添加子节点", + "Add brother node": "添加兄弟节点", + "Stroke Array": "颜色组", + "Stroke Array Desc": "节点连线颜色将按照颜色组生成,否则生成随机颜色", + "Save fail": "保存失败", + "Save success": "保存成功", + "Toggle markdown/mindmap": "切换为 markdown 或 mindmap 模式", + "Copy node": "复制", + "Paste node": "粘贴", + "Export to html": "导出为 html" +}; + +// 繁體中文 +var zhTW = {}; + +const localeMap = { + ar, + cs: cz, + da, + de, + en, + "en-gb": enGB, + es, + fr, + hi, + id, + it, + ja, + ko, + nl, + nn: no, + pl, + pt, + "pt-br": ptBR, + ro, + ru, + tr, + "zh-cn": zhCN, + "zh-tw": zhTW, +}; +const locale = localeMap[obsidian.moment.locale()]; +function t(str) { + if (!locale) { + console.error("Error: kanban locale not found", obsidian.moment.locale()); + } + return (locale && locale[str]) || en[str]; +} + +const FRONT_MATTER_REGEX = /^(---)$.+?^(---)$.+?/ims; +const frontMatterKey = 'mindmap-plugin'; +const basicFrontmatter = [ + "---", + "", + `${frontMatterKey}: basic`, + "", + "---", + "", + "", +].join("\n"); + +function keepLastIndex(dom) { + if (window.getSelection) { //ie11 10 9 ff safari + dom.focus(); //ff + var range = window.getSelection(); + range.selectAllChildren(dom); + range.collapseToEnd(); + } + // else if ( document.selection ) { //ie10 9 8 7 6 5 + // var range = document.selection.createRange(); + // range.moveToElementText(dom); + // range.collapse(false); + // range.select(); + // } +} +class Node { + constructor(data, mindMap) { + this.box = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + this.isExpand = true; + this.isSelect = false; + this.children = []; + this.isHide = false; + this.isEdit = false; + this._barDom = null; + this.data = data; + this.mindmap = mindMap; + this.initDom(); + } + getId() { + return this.data.id; + } + initDom() { + this.containEl = document.createElement('div'); + this.containEl.classList.add('mm-node'); + this.containEl.setAttribute('contentEditable', 'false'); + this.containEl.setAttribute('tabIndex', '-1'); + this.containEl.setAttribute('data-id', this.data.id); + this.containEl.setAttribute('draggable', 'false'); + this.contentEl = document.createElement('div'); + this.contentEl.classList.add('mm-node-content'); + this.containEl.appendChild(this.contentEl); + //this.containEl.textContent = this.data.text; + this.initNodeBar(); + if (this.data.isRoot) { + this.containEl.classList.add('mm-root'); + this.isRoot = true; + } + this.parseText(); + } + initNodeBar() { + this._barDom = document.createElement('div'); + this._barDom.classList.add('mm-node-bar'); + this.containEl.appendChild(this._barDom); + } + parseText() { + if (this.data.text.length === 0) { + this.data.text = "Sub title"; + } + obsidian.MarkdownRenderer.renderMarkdown(this.data.text, this.contentEl, this.mindmap.path || "", null).then(() => { + this.data.mdText = this.contentEl.innerHTML; + this.refreshBox(); + this.mindmap && this.mindmap.emit('initNode', {}); + this._delay(); + }); + } + _delay() { + //parse md + this.contentEl.findAll(".internal-embed").forEach((el) => __awaiter(this, void 0, void 0, function* () { + const src = el.getAttribute("src"); + if (typeof src === 'string') { + var pathObj = obsidian.parseLinktext(src); + var fileData = ''; + if (this.mindmap && this.mindmap.view) { + var f = this.mindmap.view.app.metadataCache.getFirstLinkpathDest(pathObj.path, this.mindmap.path); + if (f instanceof obsidian.TFile && f.extension === 'md') { + fileData = yield this.mindmap.view.app.vault.adapter.read(f.path); + var markdownEmbed = document.createElement('div'); + markdownEmbed.classList.add('markdown-embed'); + // var markdownHead = document.createElement('div'); + // markdownHead.classList.add('markdown-embed-title'); + // markdownHead.innerText=f.basename; + markdownEmbed.setAttribute('data-name', f.path); + var markdownContent = document.createElement('div'); + markdownContent.classList.add('markdown-embed-content'); + var markdownPreview = document.createElement('div'); + markdownPreview.classList.add('markdown-preview-view'); + markdownContent.appendChild(markdownPreview); + var markdownLink = document.createElement('div'); + markdownLink.classList.add('markdown-embed-link'); + markdownLink.setAttribute('aria-label', 'Open link'); + markdownLink.innerHTML = ``; + el.appendChild(markdownEmbed); + // markdownEmbed.appendChild(markdownHead); + markdownEmbed.appendChild(markdownContent); + markdownEmbed.appendChild(markdownLink); + if (pathObj.subpath) { + var metacache = this.mindmap.view.app.metadataCache.getFileCache(f); + var t = obsidian.resolveSubpath(metacache, pathObj.subpath); + // console.log(t); + if (t && t.start && t.end) { + var md = fileData.substring(t.start.offset, t.end.offset); + // console.log(md) + } + else if (t && t.start && !t.end) { + var md = fileData.substr(t.start.offset); + } + else { + var md = fileData || ''; + } + } + else { + var md = fileData || ''; + } + if (md) { + obsidian.MarkdownRenderer.renderMarkdown(md, markdownPreview, this.mindmap.path || "", null).then(() => { + // this.data.mdText = this.editDom.innerHTML; + this.refreshBox(); + //this._delay(); + this.mindmap && this.mindmap.emit('renderEditNode', { node: this }); + }); + } + } + } + } + })); + //parse image + setTimeout(() => { + this.contentEl.findAll(".internal-embed").forEach((el) => { + var _a; + const src = el.getAttribute("src"); + const target = typeof src === "string" && + this.mindmap && ((_a = this.mindmap.view) === null || _a === void 0 ? void 0 : _a.app.metadataCache.getFirstLinkpathDest(src, this.mindmap.path)); + if (target instanceof obsidian.TFile && target.extension !== "md" && this.mindmap) { + el.innerText = ""; + el.createEl("img", { attr: { src: this.mindmap.view.app.vault.getResourcePath(target) } }, (img) => { + if (el.hasAttribute("width")) + img.setAttribute("width", el.getAttribute("width")); + if (el.hasAttribute("alt")) + img.setAttribute("alt", el.getAttribute("alt")); + }); + el.addClasses(["image-embed", "is-loaded"]); + } + }); + //Possible causes of delay,code mathjax + var dom = this.contentEl.querySelector('code') || this.contentEl.querySelector('.MathJax'); + if (dom) { + setTimeout(() => { + this.clearCacheData(); + this.refreshBox(); + this.mindmap && this.mindmap.emit('renderEditNode', {}); + }, 100); + } + //image + this.contentEl.querySelectorAll('img').forEach(element => { + element.onload = () => { + this.clearCacheData(); + this.refreshBox(); + this.mindmap && this.mindmap.emit('renderEditNode', {}); + }; + element.onerror = () => { + this.clearCacheData(); + this.refreshBox(); + this.mindmap && this.mindmap.emit('renderEditNode', {}); + }; + element.setAttribute('draggble', 'false'); + }); + }, 100); + } + select() { + this.isSelect = true; + this.containEl.setAttribute('draggable', 'true'); + Object.assign(window, { + myNode: this + }); + if (!this.containEl.classList.contains('mm-node-select')) { + this.containEl.classList.add('mm-node-select'); + } + this.mindmap.selectNode = this; + } + unSelect() { + this.isSelect = false; + this.containEl.setAttribute('draggable', 'false'); + if (this.containEl.classList.contains('mm-node-select')) { + this.containEl.classList.remove('mm-node-select'); + } + } + edit() { + this.contentEl.innerText = ''; + this._oldText = this.data.text; + //var _t = this.data.text.replace(/\r\n/g,"
") + // _t = _t.replace(/\n/g,"
"); + // console.log(_t); + this.contentEl.innerText = this.data.text; + this.contentEl.setAttribute('contentEditable', 'true'); + this.contentEl.focus(); + this.mindmap.editNode = this; + this.isEdit = true; + keepLastIndex(this.contentEl); + if (this.contentEl.innerText == t('Sub title')) { + this.selectText(); + } + if (!this.containEl.classList.contains('mm-edit-node')) { + this.containEl.classList.add('mm-edit-node'); + } + } + selectText() { + var text = this.contentEl; + // if (document.body.createTextRange) { + // var range = document.body.createTextRange(); + // range.moveToElementText(text); + // range.select(); + // } + if (window.getSelection) { + var selection = window.getSelection(); + var range = document.createRange(); + range.selectNodeContents(text); + selection.removeAllRanges(); + selection.addRange(range); + } + } + cancelEdit() { + var text = this.contentEl.innerText.trim() || ''; + if (text.length == 0) { + text = this._oldText; + } + this.data.text = text; + this.contentEl.innerText = ''; + obsidian.MarkdownRenderer.renderMarkdown(text, this.contentEl, this.mindmap.path || "", null).then(() => { + this.data.mdText = this.contentEl.innerHTML; + this.refreshBox(); + this._delay(); + }); + if (text != this._oldText) { + this.mindmap.execute('changeNodeText', { + node: this, + text, + oldText: this._oldText + }); + } + this.contentEl.setAttribute('contentEditable', 'false'); + this.isEdit = false; + if (this.containEl.classList.contains('mm-edit-node')) { + this.containEl.classList.remove('mm-edit-node'); + } + } + getLevel() { + var level = 0, parent = this.parent; + if (this == this.mindmap.root) { + return level; + } + level++; + while (parent && parent != this.mindmap.root) { + level++; + parent = parent.parent; + } + return level; + } + getChildren() { + return this.children; + } + setPosition(x, y) { + this.box.x = x; + this.box.y = y; + this.containEl.style.left = x + 'px'; + this.containEl.style.top = y + 'px'; + } + getPosition() { + return { + x: this.box.x, + y: this.box.y + }; + } + move(dx, dy) { + var p = this.getPosition(); + this.setPosition(p.x + dx, p.y + dy); + } + getData() { + return JSON.parse(JSON.stringify(this.data)); + } + refreshBox() { + this.box = this.getDomBox(); + } + getBox() { + return Object.assign({}, this.box); + } + getCBox() { + return Object.assign({}, this.box); + } + getDomBox() { + var t = parseInt(this.containEl.style.top); + var l = parseInt(this.containEl.style.left); + var w = Math.ceil(this.contentEl.offsetWidth); + var h = Math.ceil(this.contentEl.offsetHeight); + return { + x: l, + y: t, + width: w, + height: h, + th: 0, + bh: 0 + }; + } + getShowNodeList() { + var list = []; + (function getList(node) { + if (node.isShow()) { + list.push(node); + } + node.children.forEach((n) => { + getList(n); + }); + })(this); + return list; + } + getSiblings() { + if (this.parent) { + return this.parent.children.filter(item => item != this); + } + else { + return []; + } + } + isLeaf() { + return !this.children.length; + } + isShow() { + return !this.isHide; + } + show() { + this.containEl.style.display = "block"; + this.isHide = false; + } + hide() { + this.containEl.style.display = "none"; + this.isHide = true; + } + clearCacheData() { + var anchor = this; + while (anchor) { + anchor.boundingRect = null; + anchor = anchor.parent; + } + } + addChild(node, i) { + if (this.children.indexOf(node) == -1) { + if (i > -1) { + if (i > this.children.length) + i = this.children.length; + this.children.splice(i, 0, node); + } + else { + this.children.push(node); + } + node.parent = this; + } + } + removeChild(child) { + var index = this.children.indexOf(child); + if (index > -1) { + this.children.splice(index, 1); + } + return index; + } + setText(text) { + this.data.text = text; + this.contentEl.innerHTML = ''; + this.parseText(); + } + expand() { + this.isExpand = true; + function show(node) { + node.show(); + node.refreshBox(); + node.boundingRect = null; + if (node.isExpand) { + node.children.forEach(c => { + show(c); + }); + } + } + show(this); + if (this.containEl.classList.contains('mm-node-collapse')) { + this.containEl.classList.remove('mm-node-collapse'); + } + } + collapse() { + this.isExpand = false; + function hide(node) { + node.hide(); + if (node.isExpand) { + node.children.forEach(c => { + hide(c); + }); + } + } + this.children.forEach((c) => { + hide(c); + }); + if (!this.containEl.classList.contains('mm-node-collapse')) { + this.containEl.classList.add('mm-node-collapse'); + } + } +} + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function createCommonjsModule(fn) { + var module = { exports: {} }; + return fn(module, module.exports), module.exports; +} + +function commonjsRequire (path) { + throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); +} + +var randomColor = createCommonjsModule(function (module, exports) { +(function(root, factory) { + + // Support CommonJS + { + var randomColor = factory(); + + // Support NodeJS & Component, which allow module.exports to be a function + if (module && module.exports) { + exports = module.exports = randomColor; + } + + // Support CommonJS 1.1.1 spec + exports.randomColor = randomColor; + + // Support AMD + } + +}(commonjsGlobal, function() { + + // Seed to get repeatable colors + var seed = null; + + // Shared color dictionary + var colorDictionary = {}; + + // Populate the color dictionary + loadColorBounds(); + + // check if a range is taken + var colorRanges = []; + + var randomColor = function (options) { + + options = options || {}; + + // Check if there is a seed and ensure it's an + // integer. Otherwise, reset the seed value. + if (options.seed !== undefined && options.seed !== null && options.seed === parseInt(options.seed, 10)) { + seed = options.seed; + + // A string was passed as a seed + } else if (typeof options.seed === 'string') { + seed = stringToInteger(options.seed); + + // Something was passed as a seed but it wasn't an integer or string + } else if (options.seed !== undefined && options.seed !== null) { + throw new TypeError('The seed value must be an integer or string'); + + // No seed, reset the value outside. + } else { + seed = null; + } + + var H,S,B; + + // Check if we need to generate multiple colors + if (options.count !== null && options.count !== undefined) { + + var totalColors = options.count, + colors = []; + // Value false at index i means the range i is not taken yet. + for (var i = 0; i < options.count; i++) { + colorRanges.push(false); + } + options.count = null; + + while (totalColors > colors.length) { + + var color = randomColor(options); + + if (seed !== null) { + options.seed = seed; + } + + colors.push(color); + } + + options.count = totalColors; + + return colors; + } + + // First we pick a hue (H) + H = pickHue(options); + + // Then use H to determine saturation (S) + S = pickSaturation(H, options); + + // Then use S and H to determine brightness (B). + B = pickBrightness(H, S, options); + + // Then we return the HSB color in the desired format + return setFormat([H,S,B], options); + }; + + function pickHue(options) { + if (colorRanges.length > 0) { + var hueRange = getRealHueRange(options.hue); + + var hue = randomWithin(hueRange); + + //Each of colorRanges.length ranges has a length equal approximatelly one step + var step = (hueRange[1] - hueRange[0]) / colorRanges.length; + + var j = parseInt((hue - hueRange[0]) / step); + + //Check if the range j is taken + if (colorRanges[j] === true) { + j = (j + 2) % colorRanges.length; + } + else { + colorRanges[j] = true; + } + + var min = (hueRange[0] + j * step) % 359, + max = (hueRange[0] + (j + 1) * step) % 359; + + hueRange = [min, max]; + + hue = randomWithin(hueRange); + + if (hue < 0) {hue = 360 + hue;} + return hue + } + else { + var hueRange = getHueRange(options.hue); + + hue = randomWithin(hueRange); + // Instead of storing red as two seperate ranges, + // we group them, using negative numbers + if (hue < 0) { + hue = 360 + hue; + } + + return hue; + } + } + + function pickSaturation (hue, options) { + + if (options.hue === 'monochrome') { + return 0; + } + + if (options.luminosity === 'random') { + return randomWithin([0,100]); + } + + var saturationRange = getSaturationRange(hue); + + var sMin = saturationRange[0], + sMax = saturationRange[1]; + + switch (options.luminosity) { + + case 'bright': + sMin = 55; + break; + + case 'dark': + sMin = sMax - 10; + break; + + case 'light': + sMax = 55; + break; + } + + return randomWithin([sMin, sMax]); + + } + + function pickBrightness (H, S, options) { + + var bMin = getMinimumBrightness(H, S), + bMax = 100; + + switch (options.luminosity) { + + case 'dark': + bMax = bMin + 20; + break; + + case 'light': + bMin = (bMax + bMin)/2; + break; + + case 'random': + bMin = 0; + bMax = 100; + break; + } + + return randomWithin([bMin, bMax]); + } + + function setFormat (hsv, options) { + + switch (options.format) { + + case 'hsvArray': + return hsv; + + case 'hslArray': + return HSVtoHSL(hsv); + + case 'hsl': + var hsl = HSVtoHSL(hsv); + return 'hsl('+hsl[0]+', '+hsl[1]+'%, '+hsl[2]+'%)'; + + case 'hsla': + var hslColor = HSVtoHSL(hsv); + var alpha = options.alpha || Math.random(); + return 'hsla('+hslColor[0]+', '+hslColor[1]+'%, '+hslColor[2]+'%, ' + alpha + ')'; + + case 'rgbArray': + return HSVtoRGB(hsv); + + case 'rgb': + var rgb = HSVtoRGB(hsv); + return 'rgb(' + rgb.join(', ') + ')'; + + case 'rgba': + var rgbColor = HSVtoRGB(hsv); + var alpha = options.alpha || Math.random(); + return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')'; + + default: + return HSVtoHex(hsv); + } + + } + + function getMinimumBrightness(H, S) { + + var lowerBounds = getColorInfo(H).lowerBounds; + + for (var i = 0; i < lowerBounds.length - 1; i++) { + + var s1 = lowerBounds[i][0], + v1 = lowerBounds[i][1]; + + var s2 = lowerBounds[i+1][0], + v2 = lowerBounds[i+1][1]; + + if (S >= s1 && S <= s2) { + + var m = (v2 - v1)/(s2 - s1), + b = v1 - m*s1; + + return m*S + b; + } + + } + + return 0; + } + + function getHueRange (colorInput) { + + if (typeof parseInt(colorInput) === 'number') { + + var number = parseInt(colorInput); + + if (number < 360 && number > 0) { + return [number, number]; + } + + } + + if (typeof colorInput === 'string') { + + if (colorDictionary[colorInput]) { + var color = colorDictionary[colorInput]; + if (color.hueRange) {return color.hueRange;} + } else if (colorInput.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) { + var hue = HexToHSB(colorInput)[0]; + return [ hue, hue ]; + } + } + + return [0,360]; + + } + + function getSaturationRange (hue) { + return getColorInfo(hue).saturationRange; + } + + function getColorInfo (hue) { + + // Maps red colors to make picking hue easier + if (hue >= 334 && hue <= 360) { + hue-= 360; + } + + for (var colorName in colorDictionary) { + var color = colorDictionary[colorName]; + if (color.hueRange && + hue >= color.hueRange[0] && + hue <= color.hueRange[1]) { + return colorDictionary[colorName]; + } + } return 'Color not found'; + } + + function randomWithin (range) { + if (seed === null) { + //generate random evenly destinct number from : https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ + var golden_ratio = 0.618033988749895; + var r=Math.random(); + r += golden_ratio; + r %= 1; + return Math.floor(range[0] + r*(range[1] + 1 - range[0])); + } else { + //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/ + var max = range[1] || 1; + var min = range[0] || 0; + seed = (seed * 9301 + 49297) % 233280; + var rnd = seed / 233280.0; + return Math.floor(min + rnd * (max - min)); +} + } + + function HSVtoHex (hsv){ + + var rgb = HSVtoRGB(hsv); + + function componentToHex(c) { + var hex = c.toString(16); + return hex.length == 1 ? '0' + hex : hex; + } + + var hex = '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]); + + return hex; + + } + + function defineColor (name, hueRange, lowerBounds) { + + var sMin = lowerBounds[0][0], + sMax = lowerBounds[lowerBounds.length - 1][0], + + bMin = lowerBounds[lowerBounds.length - 1][1], + bMax = lowerBounds[0][1]; + + colorDictionary[name] = { + hueRange: hueRange, + lowerBounds: lowerBounds, + saturationRange: [sMin, sMax], + brightnessRange: [bMin, bMax] + }; + + } + + function loadColorBounds () { + + defineColor( + 'monochrome', + null, + [[0,0],[100,0]] + ); + + defineColor( + 'red', + [-26,18], + [[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]] + ); + + defineColor( + 'orange', + [18,46], + [[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]] + ); + + defineColor( + 'yellow', + [46,62], + [[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]] + ); + + defineColor( + 'green', + [62,178], + [[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]] + ); + + defineColor( + 'blue', + [178, 257], + [[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]] + ); + + defineColor( + 'purple', + [257, 282], + [[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]] + ); + + defineColor( + 'pink', + [282, 334], + [[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]] + ); + + } + + function HSVtoRGB (hsv) { + + // this doesn't work for the values of 0 and 360 + // here's the hacky fix + var h = hsv[0]; + if (h === 0) {h = 1;} + if (h === 360) {h = 359;} + + // Rebase the h,s,v values + h = h/360; + var s = hsv[1]/100, + v = hsv[2]/100; + + var h_i = Math.floor(h*6), + f = h * 6 - h_i, + p = v * (1 - s), + q = v * (1 - f*s), + t = v * (1 - (1 - f)*s), + r = 256, + g = 256, + b = 256; + + switch(h_i) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } + + var result = [Math.floor(r*255), Math.floor(g*255), Math.floor(b*255)]; + return result; + } + + function HexToHSB (hex) { + hex = hex.replace(/^#/, ''); + hex = hex.length === 3 ? hex.replace(/(.)/g, '$1$1') : hex; + + var red = parseInt(hex.substr(0, 2), 16) / 255, + green = parseInt(hex.substr(2, 2), 16) / 255, + blue = parseInt(hex.substr(4, 2), 16) / 255; + + var cMax = Math.max(red, green, blue), + delta = cMax - Math.min(red, green, blue), + saturation = cMax ? (delta / cMax) : 0; + + switch (cMax) { + case red: return [ 60 * (((green - blue) / delta) % 6) || 0, saturation, cMax ]; + case green: return [ 60 * (((blue - red) / delta) + 2) || 0, saturation, cMax ]; + case blue: return [ 60 * (((red - green) / delta) + 4) || 0, saturation, cMax ]; + } + } + + function HSVtoHSL (hsv) { + var h = hsv[0], + s = hsv[1]/100, + v = hsv[2]/100, + k = (2-s)*v; + + return [ + h, + Math.round(s*v / (k<1 ? k : 2-k) * 10000) / 100, + k/2 * 100 + ]; + } + + function stringToInteger (string) { + var total = 0; + for (var i = 0; i !== string.length; i++) { + if (total >= Number.MAX_SAFE_INTEGER) break; + total += string.charCodeAt(i); + } + return total + } + + // get The range of given hue when options.count!=0 + function getRealHueRange(colorHue) + { if (!isNaN(colorHue)) { + var number = parseInt(colorHue); + + if (number < 360 && number > 0) { + return getColorInfo(colorHue).hueRange + } + } + else if (typeof colorHue === 'string') { + + if (colorDictionary[colorHue]) { + var color = colorDictionary[colorHue]; + + if (color.hueRange) { + return color.hueRange + } + } else if (colorHue.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) { + var hue = HexToHSB(colorHue)[0]; + return getColorInfo(hue).hueRange + } + } + + return [0,360] +} + return randomColor; +})); +}); + +class Layout { + constructor(node, direct, colors) { + this.layoutName = 'mindmap'; + this.direct = ''; + this.levelDis = 40; + this.nodeDis = 8; + this.firstLevelDis = 80; + this.firstNodeDis = 20; + this.isCache = true; + this.lefts = []; + this.rights = []; + this.colors = []; + this.lineWidth = 2; + this.root = node || null; + this.mind = (node === null || node === void 0 ? void 0 : node.mindmap) || null; + this.direct = direct || 'mindmap'; + this.colors = colors || []; + if (!this.svgDom) + this.svgDom = this.mind.edgeGroup.group(); + this.layout(); + } + setDirect() { + var me = this; + var len = this.root.children.length; + var root = this.root; + this.rights = []; + this.lefts = []; + if (this.direct == 'right') { + this.rights = root.children; + this.rights.forEach(r => { + this._setDirect(r, 'right'); + }); + } + else if (this.direct == 'left') { + this.lefts = root.children; + this.lefts.forEach(r => { + this._setDirect(r, 'left'); + }); + } + else if (this.direct == 'clockwise') { + root.children.forEach(function (child, i) { + if (i < len / 2) { + me.rights.push(child); + me._setDirect(child, 'right'); + } + else { + me.lefts.push(child); + me._setDirect(child, 'left'); + } + }); + me.lefts.reverse(); + } + else { + root.children.forEach(function (child, i) { + if (i < len / 2) { + me.rights.push(child); + me._setDirect(child, 'right'); + } + else { + me.lefts.push(child); + me._setDirect(child, 'left'); + } + }); + } + } + _setDirect(n, direct) { + n.stroke = ''; + n.direct = direct; + var flag = n.containEl.classList.contains('mm-node-second'); + n.containEl.setAttribute('class', ''); + n.containEl.classList.add('mm-node'); + n.containEl.classList.add('mm-node-' + direct); + if (n.isLeaf() && !n.containEl.classList.contains('mm-node-leaf')) { + n.containEl.classList.add('mm-node-leaf'); + } + else { + if (n.containEl.classList.contains('mm-node-leaf')) { + n.containEl.classList.remove('mm-node-leaf'); + } + } + if (n.getLevel() == 1) { + n.containEl.classList.add('mm-node-second'); + n.refreshBox(); + } + if (flag) { + n.refreshBox(); + } + if (!n.isExpand) { + n.containEl.classList.add('mm-node-collapse'); + } + n.children.forEach(c => { + this._setDirect(c, direct); + }); + } + layout(node, direct) { + if (node) + this.root = node; + if (direct) + this.direct = direct; + this.setDirect(); + if (this.direct == 'right') { + this.layoutRight(); + } + else if (this.direct == 'left') { + this.layoutLeft(); + } + else { + this.layoutMindMap(); + } + this._dolayout(); + // balance layout + this._doRefresh(); + this.createLink(); + } + layoutMindMap() { + this.layoutRight(); + this.layoutLeft(); + } + layoutRight(arr, parent) { + var rights = arr || this.rights; + var p = parent || this.root; + var pos = p.getPosition(); + var box = p.getBox(); + var plevel = p.getLevel(); + if (plevel == 0) { + var dis = this.firstLevelDis; + var nodeDis = this.firstNodeDis; + } + else { + var dis = this.levelDis; + var nodeDis = this.nodeDis; + } + var { disHeight, height } = this._getNodesHeight(rights); + var h = height / rights.length; + if (plevel == 0) { + var next = [parseInt(pos.x + box.width + dis + ''), parseInt(pos.y + box.height / 2 - disHeight / 2 + '')]; + } + else if (plevel == 1) { + var next = [parseInt(pos.x + box.width + dis + ''), parseInt(pos.y + box.height / 2 - disHeight / 2 - h / 2 - this.lineWidth / 2 + '')]; + } + else { + var next = [parseInt(pos.x + box.width + dis + ''), parseInt(pos.y + box.height - disHeight / 2 - h / 2 + '')]; + } + rights.forEach((child) => { + child.setPosition(next[0], next[1]); + var childBox = child.getBox(); + next[1] += parseInt(childBox.height + nodeDis + ''); + }); + rights.forEach((item) => { + if (item.isExpand) { + this.layoutRight(item.children, item); + } + }); + } + layoutLeft(arr, parent) { + var lefts = arr || this.lefts; + var p = parent || this.root; + var pos = p.getPosition(); + var box = p.getBox(); + var plevel = p.getLevel(); + if (plevel == 0) { + var dis = this.firstLevelDis; + var nodeDis = this.firstNodeDis; + } + else { + var dis = this.levelDis; + var nodeDis = this.nodeDis; + } + var { disHeight, height } = this._getNodesHeight(lefts); + var h = height / lefts.length; + if (plevel == 0) { + var next = [parseInt(pos.x - dis + ''), parseInt(pos.y + box.height / 2 - disHeight / 2 + '')]; + } + else if (plevel == 1) { + var next = [parseInt(pos.x - dis + ''), parseInt(pos.y + box.height / 2 - disHeight / 2 - h / 2 - this.lineWidth / 2 + '')]; + } + else { + var next = [parseInt(pos.x - dis + ''), parseInt(pos.y + box.height - disHeight / 2 - h / 2 + '')]; + } + // var next = [parseInt(pos.x - dis+''), parseInt(pos.y - disHeight / 2 +'')]; + lefts.forEach((child) => { + var childBox = child.getBox(); + child.setPosition(parseInt(next[0] - childBox.width + ''), parseInt(next[1] + '')); + next[1] += childBox.height + nodeDis; + }); + lefts.forEach((item) => { + if (item.isExpand) { + this.layoutLeft(item.children, item); + } + }); + } + _getNodesHeight(nodes) { + if (nodes[0] && nodes[0].getLevel() == 1) { + var dis = this.firstNodeDis; + } + else { + var dis = this.nodeDis; + } + var h = 0; + var h1 = 0; + if (nodes.length == 1) { + var h = nodes[0].getBox().height; + return { + disHeight: h, + height: h + }; + } + nodes.forEach((item, index) => { + var height = item.getBox().height; + h += height; + h1 += height; + if (index != nodes.length - 1) { + h += dis; + } + }); + return { + disHeight: h, + height: h1 + }; + } + _doRefresh() { + var root = this.root; + var rootPos = root.getPosition(); + var rootBox = root.getBox(); + var center = rootPos.y + rootBox.height / 2; + var rights = this.rights; + var lefts = this.lefts; + if (rights.length >= 2) { + var firstNode = rights[0]; + var lastNode = rights[rights.length - 1]; + var firstPos = firstNode.getPosition(); + var lastPos = lastNode.getPosition(); + var lastBox = lastNode.getBox(); + var dis1 = lastPos.y + lastBox.height - center; + var dis2 = center - firstPos.y; + if (Math.abs(dis1) != Math.abs(dis2)) { + var dy = Math.abs(Math.abs(dis1) - Math.abs(dis2)) / 2 + ''; + if (Math.abs(dis1) > Math.abs(dis2)) { + rights.forEach(c => { + this.moveNode(c, 0, -parseInt(dy)); + }); + } + else { + rights.forEach(c => { + this.moveNode(c, 0, parseInt(dy)); + }); + } + } + } + if (lefts.length >= 2) { + var firstNode = lefts[0]; + var lastNode = lefts[lefts.length - 1]; + var firstPos = firstNode.getPosition(); + var lastPos = lastNode.getPosition(); + var lastBox = lastNode.getBox(); + var dis1 = lastPos.y + lastBox.height - center; + var dis2 = center - firstPos.y; + if (Math.abs(dis1) != Math.abs(dis2)) { + var dy = Math.abs(Math.abs(dis1) - Math.abs(dis2)) / 2 + ''; + if (Math.abs(dis1) > Math.abs(dis2)) { + lefts.forEach(c => { + this.moveNode(c, 0, -parseInt(dy)); + }); + } + else { + lefts.forEach(c => { + this.moveNode(c, 0, parseInt(dy)); + }); + } + } + } + } + moveNode(node, dx, dy) { + node.move(dx, dy); + node && node.children && node.children.forEach((child) => { + this.moveNode(child, dx, dy); + }); + } + //fix 0.5 line width bug + linePoint(arr, lineWidth) { + let num = 0; + var func; + if (lineWidth % 2 == 1) { + num = 0.5; + func = parseInt; + } + else { + func = Math.ceil; + } + var p = arr.map((item) => { + return [func(item[0]) + num, func(item[1]) + num]; + }); + return p; + } + _dolayout() { + var me = this; + var mind = this.mind; + mind.traverseDF((n) => { + if (n == me.root) + return; + if (!n.isExpand) { + return; + } + var box = n.getCBox(); + if (me.isCache && n.boundingRect) { + var cbox = n.boundingRect; + } + else { + var list = n.getShowNodeList(); + if (list.length) { + cbox = mind.getBoundingRect(list); + } + } + if (!cbox) + return; + if (n.boundingRect && me.isCache) { + var topDy = cbox.topDy, downDy = cbox.downDy; + } + else { + topDy = Math.abs(cbox.y - box.y); + downDy = Math.abs(cbox.y + cbox.height - box.y - box.height); + cbox.topDy = topDy; + cbox.downDy = downDy; + n.boundingRect = cbox; + } + me._adjustNode(n, 0, topDy, downDy); + }); + } + _adjustNode(node, dx, dy1, dy2) { + if (!node) { + return; + } + var direct = node.direct; + if (node && node != this.root) { + var sibs = node.getSiblings(); + var pos = node.getPosition(); + sibs.forEach((sib) => { + if (sib.direct == direct) { + var sibPos = sib.getPosition(); + if (sibPos.y > pos.y) { + this.moveNode(sib, dx, dy2); + } + else { + this.moveNode(sib, dx, -dy1); + } + } + }); + } + } + refresh(node, direct) { + this.layout(node, direct); + } + createLink() { + var me = this; + this.svgDom && this.svgDom.clear(); + if (this.root.getChildren().length == 0) { + return; + } + var dis = this.levelDis; + var root = this.root; + var lineWidth = this.lineWidth; + var rootLevel = this.root.getLevel(); + function createLine(node) { + if (!node.isExpand) { + return; + } + var children = node.getChildren(); + var pos = node.getPosition(); + var box = node.getBox(); + box.height = box.height + lineWidth; + var level = node.getLevel(); + children.length && children.forEach(function (child) { + var direct = child.direct; + var childPos = child.getPosition(); + var childBox = Object.assign({}, child.getBox()); + childBox.height = childBox.height + lineWidth; + let _stroke = node.stroke ? node.stroke : (child.stroke ? child.stroke : randomColor()); + if (!child.stroke) { + child.stroke = _stroke; + } + child._barDom.style.backgroundColor = _stroke; + child._barDom.style.borderColor = _stroke; + if (level == rootLevel) { + var from = { + x: pos.x + box.width / 2, + y: pos.y + box.height / 2 + }; + } + else if (level == 1 + rootLevel) { + if (direct == 'right') { + from = { + x: pos.x + box.width, + y: pos.y + box.height / 2 + }; + } + else { + from = { + x: pos.x, + y: pos.y + box.height / 2 + }; + } + } + else { + if (direct == 'right') { + from = { + x: pos.x + box.width, + y: pos.y + box.height + }; + } + else { + from = { + x: pos.x, + y: pos.y + box.height + }; + } + } + if (level == rootLevel) { + if (direct == 'right') { + var to = { + x: childPos.x, + y: childBox.height / 2 + childPos.y + }; + } + else { + to = { + x: childPos.x + childBox.width, + y: childBox.height / 2 + childPos.y + }; + } + } + else { + if (direct == 'right') { + to = { + x: childPos.x, + y: childBox.height + childPos.y + }; + } + else { + to = { + x: childPos.x + childBox.width, + y: childBox.height + childPos.y + }; + } + } + if (lineWidth % 2 == 1) { + var x1 = parseInt(from.x + '') - 0.5; + var x2 = parseInt(to.x + '') - 0.5; + var y1 = parseInt(from.y + '') - 0.5; + var y2 = parseInt(to.y + '') - 0.5; + } + else { + var x1 = parseInt(from.x + ''); + var y1 = parseInt(from.y + ''); + var x2 = parseInt(to.x + ''); + var y2 = parseInt(to.y + ''); + } + if (level == rootLevel) { + var line1 = me.svgDom.path().stroke({ + color: _stroke, + width: lineWidth + 1, + linecap: 'round', + linejoin: 'round' + }).fill('none'); + } + else { + var line1 = me.svgDom.path().stroke({ + color: _stroke, + width: lineWidth, + linecap: 'round', + linejoin: 'round' + }).fill('none'); + } + if (lineWidth % 2 == 1) { + var x11 = parseInt(childPos.x + '') - 0.5; + var x22 = parseInt(childPos.x + childBox.width + '') - 0.5; + var y11 = y2; + var y22 = y2; + } + else { + var x11 = parseInt(childPos.x + ''); + var y11 = parseInt(childBox.height + childPos.y + ''); + var x22 = parseInt(childPos.x + childBox.width + ''); + var y22 = parseInt(childBox.height + childPos.y + ''); + } + if (level == rootLevel) { + var cpx1 = parseInt(from.x + '') + (to.x - from.x) / 9; + var cpy1 = parseInt(from.y + '') + (to.y - from.y) / 9 * 8; + var cpx2 = parseInt(from.x + (to.x - from.x) / 9 * 8 + ''); + var cpy2 = parseInt(to.y + ''); + var pathStr = `M${x1} ${y1} C ${cpx1} ${cpy1}, ${cpx2} ${cpy2}, ${x2} ${y2}`; + line1.plot(pathStr); + } + else { + me.svgDom.line(x11, y11, x22, y22).stroke({ + color: _stroke, + width: lineWidth, + linecap: 'miter', + linejoin: 'miter' + }).fill('none'); + //var c = parseInt((to.y - from.y) / 6+''); + var cpx11 = { + x: from.x + dis / 2, + y: from.y + }; + var cpx12 = { + x: from.x + dis / 2, + y: to.y + }; + if (direct == 'left') { + cpx11.x = from.x - dis / 2; + cpx12.x = from.x - dis / 2; + } + cpx11.x = parseInt(cpx11.x + ''); + cpx11.y = parseInt(cpx11.y + ''); + cpx12.x = parseInt(cpx12.x + ''); + cpx12.y = parseInt(cpx12.y + ''); + var path = `M${x1} ${y1} C ${cpx11.x} ${cpx11.y}, ${cpx12.x} ${cpx12.y}, ${x2} ${y2}`; + line1.plot(path); + } + createLine(child); + }); + } + //Set Node link Color + this.root.children.forEach((c, i) => { + c.stroke = this.colors[i] || randomColor(); + }); + createLine(root); + } +} + +/*! +* svg.js - A lightweight library for manipulating and animating SVG. +* @version 2.7.1 +* https://svgdotjs.github.io/ +* +* @copyright Wout Fierens +* @license MIT +* +* BUILT: Fri Nov 30 2018 10:01:55 GMT+0100 (GMT+01:00) +*/ + +var svg = createCommonjsModule(function (module, exports) { +(function(root, factory) { + /* istanbul ignore next */ + { + module.exports = root.document ? factory(root, root.document) : function(w){ return factory(w, w.document) }; + } +}(typeof window !== "undefined" ? window : commonjsGlobal, function(window, document) { + +// Find global reference - uses 'this' by default when available, +// falls back to 'window' otherwise (for bundlers like Webpack) +var globalRef = (typeof this !== "undefined") ? this : window; + +// The main wrapping element +var SVG = globalRef.SVG = function(element) { + if (SVG.supported) { + element = new SVG.Doc(element); + + if(!SVG.parser.draw) + SVG.prepare(); + + return element + } +}; + +// Default namespaces +SVG.ns = 'http://www.w3.org/2000/svg'; +SVG.xmlns = 'http://www.w3.org/2000/xmlns/'; +SVG.xlink = 'http://www.w3.org/1999/xlink'; +SVG.svgjs = 'http://svgjs.com/svgjs'; + +// Svg support test +SVG.supported = (function() { + return !! document.createElementNS && + !! document.createElementNS(SVG.ns,'svg').createSVGRect +})(); + +// Don't bother to continue if SVG is not supported +if (!SVG.supported) return false + +// Element id sequence +SVG.did = 1000; + +// Get next named element id +SVG.eid = function(name) { + return 'Svgjs' + capitalize(name) + (SVG.did++) +}; + +// Method for element creation +SVG.create = function(name) { + // create element + var element = document.createElementNS(this.ns, name); + + // apply unique id + element.setAttribute('id', this.eid(name)); + + return element +}; + +// Method for extending objects +SVG.extend = function() { + var modules, methods, key, i; + + // Get list of modules + modules = [].slice.call(arguments); + + // Get object with extensions + methods = modules.pop(); + + for (i = modules.length - 1; i >= 0; i--) + if (modules[i]) + for (key in methods) + modules[i].prototype[key] = methods[key]; + + // Make sure SVG.Set inherits any newly added methods + if (SVG.Set && SVG.Set.inherit) + SVG.Set.inherit(); +}; + +// Invent new element +SVG.invent = function(config) { + // Create element initializer + var initializer = typeof config.create == 'function' ? + config.create : + function() { + this.constructor.call(this, SVG.create(config.create)); + }; + + // Inherit prototype + if (config.inherit) + initializer.prototype = new config.inherit; + + // Extend with methods + if (config.extend) + SVG.extend(initializer, config.extend); + + // Attach construct method to parent + if (config.construct) + SVG.extend(config.parent || SVG.Container, config.construct); + + return initializer +}; + +// Adopt existing svg elements +SVG.adopt = function(node) { + // check for presence of node + if (!node) return null + + // make sure a node isn't already adopted + if (node.instance) return node.instance + + // initialize variables + var element; + + // adopt with element-specific settings + if (node.nodeName == 'svg') + element = node.parentNode instanceof window.SVGElement ? new SVG.Nested : new SVG.Doc; + else if (node.nodeName == 'linearGradient') + element = new SVG.Gradient('linear'); + else if (node.nodeName == 'radialGradient') + element = new SVG.Gradient('radial'); + else if (SVG[capitalize(node.nodeName)]) + element = new SVG[capitalize(node.nodeName)]; + else + element = new SVG.Element(node); + + // ensure references + element.type = node.nodeName; + element.node = node; + node.instance = element; + + // SVG.Class specific preparations + if (element instanceof SVG.Doc) + element.namespace().defs(); + + // pull svgjs data from the dom (getAttributeNS doesn't work in html5) + element.setData(JSON.parse(node.getAttribute('svgjs:data')) || {}); + + return element +}; + +// Initialize parsing element +SVG.prepare = function() { + // Select document body and create invisible svg element + var body = document.getElementsByTagName('body')[0] + , draw = (body ? new SVG.Doc(body) : SVG.adopt(document.documentElement).nested()).size(2, 0); + + // Create parser object + SVG.parser = { + body: body || document.documentElement + , draw: draw.style('opacity:0;position:absolute;left:-100%;top:-100%;overflow:hidden').attr('focusable', 'false').node + , poly: draw.polyline().node + , path: draw.path().node + , native: SVG.create('svg') + }; +}; + +SVG.parser = { + native: SVG.create('svg') +}; + +document.addEventListener('DOMContentLoaded', function() { + if(!SVG.parser.draw) + SVG.prepare(); +}, false); + +// Storage for regular expressions +SVG.regex = { + // Parse unit value + numberAndUnit: /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i + + // Parse hex value +, hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i + + // Parse rgb value +, rgb: /rgb\((\d+),(\d+),(\d+)\)/ + + // Parse reference id +, reference: /#([a-z0-9\-_]+)/i + + // splits a transformation chain +, transforms: /\)\s*,?\s*/ + + // Whitespace +, whitespace: /\s/g + + // Test hex value +, isHex: /^#[a-f0-9]{3,6}$/i + + // Test rgb value +, isRgb: /^rgb\(/ + + // Test css declaration +, isCss: /[^:]+:[^;]+;?/ + + // Test for blank string +, isBlank: /^(\s+)?$/ + + // Test for numeric string +, isNumber: /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i + + // Test for percent value +, isPercent: /^-?[\d\.]+%$/ + + // Test for image url +, isImage: /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i + + // split at whitespace and comma +, delimiter: /[\s,]+/ + + // The following regex are used to parse the d attribute of a path + + // Matches all hyphens which are not after an exponent +, hyphen: /([^e])\-/gi + + // Replaces and tests for all path letters +, pathLetters: /[MLHVCSQTAZ]/gi + + // yes we need this one, too +, isPathLetter: /[MLHVCSQTAZ]/i + + // matches 0.154.23.45 +, numbersWithDots: /((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi + + // matches . +, dots: /\./g +}; + +SVG.utils = { + // Map function + map: function(array, block) { + var i + , il = array.length + , result = []; + + for (i = 0; i < il; i++) + result.push(block(array[i])); + + return result + } + + // Filter function +, filter: function(array, block) { + var i + , il = array.length + , result = []; + + for (i = 0; i < il; i++) + if (block(array[i])) + result.push(array[i]); + + return result + } + + // Degrees to radians +, radians: function(d) { + return d % 360 * Math.PI / 180 + } + + // Radians to degrees +, degrees: function(r) { + return r * 180 / Math.PI % 360 + } + +, filterSVGElements: function(nodes) { + return this.filter( nodes, function(el) { return el instanceof window.SVGElement }) + } + +}; + +SVG.defaults = { + // Default attribute values + attrs: { + // fill and stroke + 'fill-opacity': 1 + , 'stroke-opacity': 1 + , 'stroke-width': 0 + , 'stroke-linejoin': 'miter' + , 'stroke-linecap': 'butt' + , fill: '#000000' + , stroke: '#000000' + , opacity: 1 + // position + , x: 0 + , y: 0 + , cx: 0 + , cy: 0 + // size + , width: 0 + , height: 0 + // radius + , r: 0 + , rx: 0 + , ry: 0 + // gradient + , offset: 0 + , 'stop-opacity': 1 + , 'stop-color': '#000000' + // text + , 'font-size': 16 + , 'font-family': 'Helvetica, Arial, sans-serif' + , 'text-anchor': 'start' + } + +}; +// Module for color convertions +SVG.Color = function(color) { + var match; + + // initialize defaults + this.r = 0; + this.g = 0; + this.b = 0; + + if(!color) return + + // parse color + if (typeof color === 'string') { + if (SVG.regex.isRgb.test(color)) { + // get rgb values + match = SVG.regex.rgb.exec(color.replace(SVG.regex.whitespace,'')); + + // parse numeric values + this.r = parseInt(match[1]); + this.g = parseInt(match[2]); + this.b = parseInt(match[3]); + + } else if (SVG.regex.isHex.test(color)) { + // get hex values + match = SVG.regex.hex.exec(fullHex(color)); + + // parse numeric values + this.r = parseInt(match[1], 16); + this.g = parseInt(match[2], 16); + this.b = parseInt(match[3], 16); + + } + + } else if (typeof color === 'object') { + this.r = color.r; + this.g = color.g; + this.b = color.b; + + } + +}; + +SVG.extend(SVG.Color, { + // Default to hex conversion + toString: function() { + return this.toHex() + } + // Build hex value +, toHex: function() { + return '#' + + compToHex(this.r) + + compToHex(this.g) + + compToHex(this.b) + } + // Build rgb value +, toRgb: function() { + return 'rgb(' + [this.r, this.g, this.b].join() + ')' + } + // Calculate true brightness +, brightness: function() { + return (this.r / 255 * 0.30) + + (this.g / 255 * 0.59) + + (this.b / 255 * 0.11) + } + // Make color morphable +, morph: function(color) { + this.destination = new SVG.Color(color); + + return this + } + // Get morphed color at given position +, at: function(pos) { + // make sure a destination is defined + if (!this.destination) return this + + // normalise pos + pos = pos < 0 ? 0 : pos > 1 ? 1 : pos; + + // generate morphed color + return new SVG.Color({ + r: ~~(this.r + (this.destination.r - this.r) * pos) + , g: ~~(this.g + (this.destination.g - this.g) * pos) + , b: ~~(this.b + (this.destination.b - this.b) * pos) + }) + } + +}); + +// Testers + +// Test if given value is a color string +SVG.Color.test = function(color) { + color += ''; + return SVG.regex.isHex.test(color) + || SVG.regex.isRgb.test(color) +}; + +// Test if given value is a rgb object +SVG.Color.isRgb = function(color) { + return color && typeof color.r == 'number' + && typeof color.g == 'number' + && typeof color.b == 'number' +}; + +// Test if given value is a color +SVG.Color.isColor = function(color) { + return SVG.Color.isRgb(color) || SVG.Color.test(color) +}; +// Module for array conversion +SVG.Array = function(array, fallback) { + array = (array || []).valueOf(); + + // if array is empty and fallback is provided, use fallback + if (array.length == 0 && fallback) + array = fallback.valueOf(); + + // parse array + this.value = this.parse(array); +}; + +SVG.extend(SVG.Array, { + // Make array morphable + morph: function(array) { + this.destination = this.parse(array); + + // normalize length of arrays + if (this.value.length != this.destination.length) { + var lastValue = this.value[this.value.length - 1] + , lastDestination = this.destination[this.destination.length - 1]; + + while(this.value.length > this.destination.length) + this.destination.push(lastDestination); + while(this.value.length < this.destination.length) + this.value.push(lastValue); + } + + return this + } + // Clean up any duplicate points +, settle: function() { + // find all unique values + for (var i = 0, il = this.value.length, seen = []; i < il; i++) + if (seen.indexOf(this.value[i]) == -1) + seen.push(this.value[i]); + + // set new value + return this.value = seen + } + // Get morphed array at given position +, at: function(pos) { + // make sure a destination is defined + if (!this.destination) return this + + // generate morphed array + for (var i = 0, il = this.value.length, array = []; i < il; i++) + array.push(this.value[i] + (this.destination[i] - this.value[i]) * pos); + + return new SVG.Array(array) + } + // Convert array to string +, toString: function() { + return this.value.join(' ') + } + // Real value +, valueOf: function() { + return this.value + } + // Parse whitespace separated string +, parse: function(array) { + array = array.valueOf(); + + // if already is an array, no need to parse it + if (Array.isArray(array)) return array + + return this.split(array) + } + // Strip unnecessary whitespace +, split: function(string) { + return string.trim().split(SVG.regex.delimiter).map(parseFloat) + } + // Reverse array +, reverse: function() { + this.value.reverse(); + + return this + } +, clone: function() { + var clone = new this.constructor(); + clone.value = array_clone(this.value); + return clone + } +}); +// Poly points array +SVG.PointArray = function(array, fallback) { + SVG.Array.call(this, array, fallback || [[0,0]]); +}; + +// Inherit from SVG.Array +SVG.PointArray.prototype = new SVG.Array; +SVG.PointArray.prototype.constructor = SVG.PointArray; + +SVG.extend(SVG.PointArray, { + // Convert array to string + toString: function() { + // convert to a poly point string + for (var i = 0, il = this.value.length, array = []; i < il; i++) + array.push(this.value[i].join(',')); + + return array.join(' ') + } + // Convert array to line object +, toLine: function() { + return { + x1: this.value[0][0] + , y1: this.value[0][1] + , x2: this.value[1][0] + , y2: this.value[1][1] + } + } + // Get morphed array at given position +, at: function(pos) { + // make sure a destination is defined + if (!this.destination) return this + + // generate morphed point string + for (var i = 0, il = this.value.length, array = []; i < il; i++) + array.push([ + this.value[i][0] + (this.destination[i][0] - this.value[i][0]) * pos + , this.value[i][1] + (this.destination[i][1] - this.value[i][1]) * pos + ]); + + return new SVG.PointArray(array) + } + // Parse point string and flat array +, parse: function(array) { + var points = []; + + array = array.valueOf(); + + // if it is an array + if (Array.isArray(array)) { + // and it is not flat, there is no need to parse it + if(Array.isArray(array[0])) { + // make sure to use a clone + return array.map(function (el) { return el.slice() }) + } else if (array[0].x != null){ + // allow point objects to be passed + return array.map(function (el) { return [el.x, el.y] }) + } + } else { // Else, it is considered as a string + // parse points + array = array.trim().split(SVG.regex.delimiter).map(parseFloat); + } + + // validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints + // Odd number of coordinates is an error. In such cases, drop the last odd coordinate. + if (array.length % 2 !== 0) array.pop(); + + // wrap points in two-tuples and parse points as floats + for(var i = 0, len = array.length; i < len; i = i + 2) + points.push([ array[i], array[i+1] ]); + + return points + } + // Move point string +, move: function(x, y) { + var box = this.bbox(); + + // get relative offset + x -= box.x; + y -= box.y; + + // move every point + if (!isNaN(x) && !isNaN(y)) + for (var i = this.value.length - 1; i >= 0; i--) + this.value[i] = [this.value[i][0] + x, this.value[i][1] + y]; + + return this + } + // Resize poly string +, size: function(width, height) { + var i, box = this.bbox(); + + // recalculate position of all points according to new size + for (i = this.value.length - 1; i >= 0; i--) { + if(box.width) this.value[i][0] = ((this.value[i][0] - box.x) * width) / box.width + box.x; + if(box.height) this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y; + } + + return this + } + // Get bounding box of points +, bbox: function() { + SVG.parser.poly.setAttribute('points', this.toString()); + + return SVG.parser.poly.getBBox() + } +}); + +var pathHandlers = { + M: function(c, p, p0) { + p.x = p0.x = c[0]; + p.y = p0.y = c[1]; + + return ['M', p.x, p.y] + }, + L: function(c, p) { + p.x = c[0]; + p.y = c[1]; + return ['L', c[0], c[1]] + }, + H: function(c, p) { + p.x = c[0]; + return ['H', c[0]] + }, + V: function(c, p) { + p.y = c[0]; + return ['V', c[0]] + }, + C: function(c, p) { + p.x = c[4]; + p.y = c[5]; + return ['C', c[0], c[1], c[2], c[3], c[4], c[5]] + }, + S: function(c, p) { + p.x = c[2]; + p.y = c[3]; + return ['S', c[0], c[1], c[2], c[3]] + }, + Q: function(c, p) { + p.x = c[2]; + p.y = c[3]; + return ['Q', c[0], c[1], c[2], c[3]] + }, + T: function(c, p) { + p.x = c[0]; + p.y = c[1]; + return ['T', c[0], c[1]] + }, + Z: function(c, p, p0) { + p.x = p0.x; + p.y = p0.y; + return ['Z'] + }, + A: function(c, p) { + p.x = c[5]; + p.y = c[6]; + return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]] + } +}; + +var mlhvqtcsa = 'mlhvqtcsaz'.split(''); + +for(var i = 0, il = mlhvqtcsa.length; i < il; ++i){ + pathHandlers[mlhvqtcsa[i]] = (function(i){ + return function(c, p, p0) { + if(i == 'H') c[0] = c[0] + p.x; + else if(i == 'V') c[0] = c[0] + p.y; + else if(i == 'A'){ + c[5] = c[5] + p.x, + c[6] = c[6] + p.y; + } + else + for(var j = 0, jl = c.length; j < jl; ++j) { + c[j] = c[j] + (j%2 ? p.y : p.x); + } + + return pathHandlers[i](c, p, p0) + } + })(mlhvqtcsa[i].toUpperCase()); +} + +// Path points array +SVG.PathArray = function(array, fallback) { + SVG.Array.call(this, array, fallback || [['M', 0, 0]]); +}; + +// Inherit from SVG.Array +SVG.PathArray.prototype = new SVG.Array; +SVG.PathArray.prototype.constructor = SVG.PathArray; + +SVG.extend(SVG.PathArray, { + // Convert array to string + toString: function() { + return arrayToString(this.value) + } + // Move path string +, move: function(x, y) { + // get bounding box of current situation + var box = this.bbox(); + + // get relative offset + x -= box.x; + y -= box.y; + + if (!isNaN(x) && !isNaN(y)) { + // move every point + for (var l, i = this.value.length - 1; i >= 0; i--) { + l = this.value[i][0]; + + if (l == 'M' || l == 'L' || l == 'T') { + this.value[i][1] += x; + this.value[i][2] += y; + + } else if (l == 'H') { + this.value[i][1] += x; + + } else if (l == 'V') { + this.value[i][1] += y; + + } else if (l == 'C' || l == 'S' || l == 'Q') { + this.value[i][1] += x; + this.value[i][2] += y; + this.value[i][3] += x; + this.value[i][4] += y; + + if (l == 'C') { + this.value[i][5] += x; + this.value[i][6] += y; + } + + } else if (l == 'A') { + this.value[i][6] += x; + this.value[i][7] += y; + } + + } + } + + return this + } + // Resize path string +, size: function(width, height) { + // get bounding box of current situation + var i, l, box = this.bbox(); + + // recalculate position of all points according to new size + for (i = this.value.length - 1; i >= 0; i--) { + l = this.value[i][0]; + + if (l == 'M' || l == 'L' || l == 'T') { + this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x; + this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y; + + } else if (l == 'H') { + this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x; + + } else if (l == 'V') { + this.value[i][1] = ((this.value[i][1] - box.y) * height) / box.height + box.y; + + } else if (l == 'C' || l == 'S' || l == 'Q') { + this.value[i][1] = ((this.value[i][1] - box.x) * width) / box.width + box.x; + this.value[i][2] = ((this.value[i][2] - box.y) * height) / box.height + box.y; + this.value[i][3] = ((this.value[i][3] - box.x) * width) / box.width + box.x; + this.value[i][4] = ((this.value[i][4] - box.y) * height) / box.height + box.y; + + if (l == 'C') { + this.value[i][5] = ((this.value[i][5] - box.x) * width) / box.width + box.x; + this.value[i][6] = ((this.value[i][6] - box.y) * height) / box.height + box.y; + } + + } else if (l == 'A') { + // resize radii + this.value[i][1] = (this.value[i][1] * width) / box.width; + this.value[i][2] = (this.value[i][2] * height) / box.height; + + // move position values + this.value[i][6] = ((this.value[i][6] - box.x) * width) / box.width + box.x; + this.value[i][7] = ((this.value[i][7] - box.y) * height) / box.height + box.y; + } + + } + + return this + } + // Test if the passed path array use the same path data commands as this path array +, equalCommands: function(pathArray) { + var i, il, equalCommands; + + pathArray = new SVG.PathArray(pathArray); + + equalCommands = this.value.length === pathArray.value.length; + for(i = 0, il = this.value.length; equalCommands && i < il; i++) { + equalCommands = this.value[i][0] === pathArray.value[i][0]; + } + + return equalCommands + } + // Make path array morphable +, morph: function(pathArray) { + pathArray = new SVG.PathArray(pathArray); + + if(this.equalCommands(pathArray)) { + this.destination = pathArray; + } else { + this.destination = null; + } + + return this + } + // Get morphed path array at given position +, at: function(pos) { + // make sure a destination is defined + if (!this.destination) return this + + var sourceArray = this.value + , destinationArray = this.destination.value + , array = [], pathArray = new SVG.PathArray() + , i, il, j, jl; + + // Animate has specified in the SVG spec + // See: https://www.w3.org/TR/SVG11/paths.html#PathElement + for (i = 0, il = sourceArray.length; i < il; i++) { + array[i] = [sourceArray[i][0]]; + for(j = 1, jl = sourceArray[i].length; j < jl; j++) { + array[i][j] = sourceArray[i][j] + (destinationArray[i][j] - sourceArray[i][j]) * pos; + } + // For the two flags of the elliptical arc command, the SVG spec say: + // Flags and booleans are interpolated as fractions between zero and one, with any non-zero value considered to be a value of one/true + // Elliptical arc command as an array followed by corresponding indexes: + // ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y] + // 0 1 2 3 4 5 6 7 + if(array[i][0] === 'A') { + array[i][4] = +(array[i][4] != 0); + array[i][5] = +(array[i][5] != 0); + } + } + + // Directly modify the value of a path array, this is done this way for performance + pathArray.value = array; + return pathArray + } + // Absolutize and parse path to array +, parse: function(array) { + // if it's already a patharray, no need to parse it + if (array instanceof SVG.PathArray) return array.valueOf() + + // prepare for parsing + var s, arr + , paramCnt = { 'M':2, 'L':2, 'H':1, 'V':1, 'C':6, 'S':4, 'Q':4, 'T':2, 'A':7, 'Z':0 }; + + if(typeof array == 'string'){ + + array = array + .replace(SVG.regex.numbersWithDots, pathRegReplace) // convert 45.123.123 to 45.123 .123 + .replace(SVG.regex.pathLetters, ' $& ') // put some room between letters and numbers + .replace(SVG.regex.hyphen, '$1 -') // add space before hyphen + .trim() // trim + .split(SVG.regex.delimiter); // split into array + + }else { + array = array.reduce(function(prev, curr){ + return [].concat.call(prev, curr) + }, []); + } + + // array now is an array containing all parts of a path e.g. ['M', '0', '0', 'L', '30', '30' ...] + var arr = [] + , p = new SVG.Point() + , p0 = new SVG.Point() + , index = 0 + , len = array.length; + + do{ + // Test if we have a path letter + if(SVG.regex.isPathLetter.test(array[index])){ + s = array[index]; + ++index; + // If last letter was a move command and we got no new, it defaults to [L]ine + }else if(s == 'M'){ + s = 'L'; + }else if(s == 'm'){ + s = 'l'; + } + + arr.push(pathHandlers[s].call(null, + array.slice(index, (index = index + paramCnt[s.toUpperCase()])).map(parseFloat), + p, p0 + ) + ); + + }while(len > index) + + return arr + + } + // Get bounding box of path +, bbox: function() { + SVG.parser.path.setAttribute('d', this.toString()); + + return SVG.parser.path.getBBox() + } + +}); + +// Module for unit convertions +SVG.Number = SVG.invent({ + // Initialize + create: function(value, unit) { + // initialize defaults + this.value = 0; + this.unit = unit || ''; + + // parse value + if (typeof value === 'number') { + // ensure a valid numeric value + this.value = isNaN(value) ? 0 : !isFinite(value) ? (value < 0 ? -3.4e+38 : +3.4e+38) : value; + + } else if (typeof value === 'string') { + unit = value.match(SVG.regex.numberAndUnit); + + if (unit) { + // make value numeric + this.value = parseFloat(unit[1]); + + // normalize + if (unit[5] == '%') + this.value /= 100; + else if (unit[5] == 's') + this.value *= 1000; + + // store unit + this.unit = unit[5]; + } + + } else { + if (value instanceof SVG.Number) { + this.value = value.valueOf(); + this.unit = value.unit; + } + } + + } + // Add methods +, extend: { + // Stringalize + toString: function() { + return ( + this.unit == '%' ? + ~~(this.value * 1e8) / 1e6: + this.unit == 's' ? + this.value / 1e3 : + this.value + ) + this.unit + } + , toJSON: function() { + return this.toString() + } + , // Convert to primitive + valueOf: function() { + return this.value + } + // Add number + , plus: function(number) { + number = new SVG.Number(number); + return new SVG.Number(this + number, this.unit || number.unit) + } + // Subtract number + , minus: function(number) { + number = new SVG.Number(number); + return new SVG.Number(this - number, this.unit || number.unit) + } + // Multiply number + , times: function(number) { + number = new SVG.Number(number); + return new SVG.Number(this * number, this.unit || number.unit) + } + // Divide number + , divide: function(number) { + number = new SVG.Number(number); + return new SVG.Number(this / number, this.unit || number.unit) + } + // Convert to different unit + , to: function(unit) { + var number = new SVG.Number(this); + + if (typeof unit === 'string') + number.unit = unit; + + return number + } + // Make number morphable + , morph: function(number) { + this.destination = new SVG.Number(number); + + if(number.relative) { + this.destination.value += this.value; + } + + return this + } + // Get morphed number at given position + , at: function(pos) { + // Make sure a destination is defined + if (!this.destination) return this + + // Generate new morphed number + return new SVG.Number(this.destination) + .minus(this) + .times(pos) + .plus(this) + } + + } +}); + + +SVG.Element = SVG.invent({ + // Initialize node + create: function(node) { + // make stroke value accessible dynamically + this._stroke = SVG.defaults.attrs.stroke; + this._event = null; + this._events = {}; + + // initialize data object + this.dom = {}; + + // create circular reference + if (this.node = node) { + this.type = node.nodeName; + this.node.instance = this; + this._events = node._events || {}; + + // store current attribute value + this._stroke = node.getAttribute('stroke') || this._stroke; + } + } + + // Add class methods +, extend: { + // Move over x-axis + x: function(x) { + return this.attr('x', x) + } + // Move over y-axis + , y: function(y) { + return this.attr('y', y) + } + // Move by center over x-axis + , cx: function(x) { + return x == null ? this.x() + this.width() / 2 : this.x(x - this.width() / 2) + } + // Move by center over y-axis + , cy: function(y) { + return y == null ? this.y() + this.height() / 2 : this.y(y - this.height() / 2) + } + // Move element to given x and y values + , move: function(x, y) { + return this.x(x).y(y) + } + // Move element by its center + , center: function(x, y) { + return this.cx(x).cy(y) + } + // Set width of element + , width: function(width) { + return this.attr('width', width) + } + // Set height of element + , height: function(height) { + return this.attr('height', height) + } + // Set element size to given width and height + , size: function(width, height) { + var p = proportionalSize(this, width, height); + + return this + .width(new SVG.Number(p.width)) + .height(new SVG.Number(p.height)) + } + // Clone element + , clone: function(parent) { + // write dom data to the dom so the clone can pickup the data + this.writeDataToDom(); + + // clone element and assign new id + var clone = assignNewId(this.node.cloneNode(true)); + + // insert the clone in the given parent or after myself + if(parent) parent.add(clone); + else this.after(clone); + + return clone + } + // Remove element + , remove: function() { + if (this.parent()) + this.parent().removeElement(this); + + return this + } + // Replace element + , replace: function(element) { + this.after(element).remove(); + + return element + } + // Add element to given container and return self + , addTo: function(parent) { + return parent.put(this) + } + // Add element to given container and return container + , putIn: function(parent) { + return parent.add(this) + } + // Get / set id + , id: function(id) { + return this.attr('id', id) + } + // Checks whether the given point inside the bounding box of the element + , inside: function(x, y) { + var box = this.bbox(); + + return x > box.x + && y > box.y + && x < box.x + box.width + && y < box.y + box.height + } + // Show element + , show: function() { + return this.style('display', '') + } + // Hide element + , hide: function() { + return this.style('display', 'none') + } + // Is element visible? + , visible: function() { + return this.style('display') != 'none' + } + // Return id on string conversion + , toString: function() { + return this.attr('id') + } + // Return array of classes on the node + , classes: function() { + var attr = this.attr('class'); + + return attr == null ? [] : attr.trim().split(SVG.regex.delimiter) + } + // Return true if class exists on the node, false otherwise + , hasClass: function(name) { + return this.classes().indexOf(name) != -1 + } + // Add class to the node + , addClass: function(name) { + if (!this.hasClass(name)) { + var array = this.classes(); + array.push(name); + this.attr('class', array.join(' ')); + } + + return this + } + // Remove class from the node + , removeClass: function(name) { + if (this.hasClass(name)) { + this.attr('class', this.classes().filter(function(c) { + return c != name + }).join(' ')); + } + + return this + } + // Toggle the presence of a class on the node + , toggleClass: function(name) { + return this.hasClass(name) ? this.removeClass(name) : this.addClass(name) + } + // Get referenced element form attribute value + , reference: function(attr) { + return SVG.get(this.attr(attr)) + } + // Returns the parent element instance + , parent: function(type) { + var parent = this; + + // check for parent + if(!parent.node.parentNode) return null + + // get parent element + parent = SVG.adopt(parent.node.parentNode); + + if(!type) return parent + + // loop trough ancestors if type is given + while(parent && parent.node instanceof window.SVGElement){ + if(typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent + if(!parent.node.parentNode || parent.node.parentNode.nodeName == '#document' || parent.node.parentNode.nodeName == '#document-fragment') return null // #759, #720 + parent = SVG.adopt(parent.node.parentNode); + } + } + // Get parent document + , doc: function() { + return this instanceof SVG.Doc ? this : this.parent(SVG.Doc) + } + // return array of all ancestors of given type up to the root svg + , parents: function(type) { + var parents = [], parent = this; + + do{ + parent = parent.parent(type); + if(!parent || !parent.node) break + + parents.push(parent); + } while(parent.parent) + + return parents + } + // matches the element vs a css selector + , matches: function(selector){ + return matches(this.node, selector) + } + // Returns the svg node to call native svg methods on it + , native: function() { + return this.node + } + // Import raw svg + , svg: function(svg) { + // create temporary holder + var well = document.createElement('svg'); + + // act as a setter if svg is given + if (svg && this instanceof SVG.Parent) { + // dump raw svg + well.innerHTML = '' + svg.replace(/\n/, '').replace(/<([\w:-]+)([^<]+?)\/>/g, '<$1$2>') + ''; + + // transplant nodes + for (var i = 0, il = well.firstChild.childNodes.length; i < il; i++) + this.node.appendChild(well.firstChild.firstChild); + + // otherwise act as a getter + } else { + // create a wrapping svg element in case of partial content + well.appendChild(svg = document.createElement('svg')); + + // write svgjs data to the dom + this.writeDataToDom(); + + // insert a copy of this node + svg.appendChild(this.node.cloneNode(true)); + + // return target element + return well.innerHTML.replace(/^/, '').replace(/<\/svg>$/, '') + } + + return this + } + // write svgjs data to the dom + , writeDataToDom: function() { + + // dump variables recursively + if(this.each || this.lines){ + var fn = this.each ? this : this.lines(); + fn.each(function(){ + this.writeDataToDom(); + }); + } + + // remove previously set data + this.node.removeAttribute('svgjs:data'); + + if(Object.keys(this.dom).length) + this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)); // see #428 + + return this + } + // set given data to the elements data property + , setData: function(o){ + this.dom = o; + return this + } + , is: function(obj){ + return is(this, obj) + } + } +}); + +SVG.easing = { + '-': function(pos){return pos} +, '<>':function(pos){return -Math.cos(pos * Math.PI) / 2 + 0.5} +, '>': function(pos){return Math.sin(pos * Math.PI / 2)} +, '<': function(pos){return -Math.cos(pos * Math.PI / 2) + 1} +}; + +SVG.morph = function(pos){ + return function(from, to) { + return new SVG.MorphObj(from, to).at(pos) + } +}; + +SVG.Situation = SVG.invent({ + + create: function(o){ + this.init = false; + this.reversed = false; + this.reversing = false; + + this.duration = new SVG.Number(o.duration).valueOf(); + this.delay = new SVG.Number(o.delay).valueOf(); + + this.start = +new Date() + this.delay; + this.finish = this.start + this.duration; + this.ease = o.ease; + + // this.loop is incremented from 0 to this.loops + // it is also incremented when in an infinite loop (when this.loops is true) + this.loop = 0; + this.loops = false; + + this.animations = { + // functionToCall: [list of morphable objects] + // e.g. move: [SVG.Number, SVG.Number] + }; + + this.attrs = { + // holds all attributes which are not represented from a function svg.js provides + // e.g. someAttr: SVG.Number + }; + + this.styles = { + // holds all styles which should be animated + // e.g. fill-color: SVG.Color + }; + + this.transforms = [ + // holds all transformations as transformation objects + // e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix] + ]; + + this.once = { + // functions to fire at a specific position + // e.g. "0.5": function foo(){} + }; + + } + +}); + + +SVG.FX = SVG.invent({ + + create: function(element) { + this._target = element; + this.situations = []; + this.active = false; + this.situation = null; + this.paused = false; + this.lastPos = 0; + this.pos = 0; + // The absolute position of an animation is its position in the context of its complete duration (including delay and loops) + // When performing a delay, absPos is below 0 and when performing a loop, its value is above 1 + this.absPos = 0; + this._speed = 1; + } + +, extend: { + + /** + * sets or returns the target of this animation + * @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation + * @param ease function || string Function which should be used for easing or easing keyword + * @param delay Number indicating the delay before the animation starts + * @return target || this + */ + animate: function(o, ease, delay){ + + if(typeof o == 'object'){ + ease = o.ease; + delay = o.delay; + o = o.duration; + } + + var situation = new SVG.Situation({ + duration: o || 1000, + delay: delay || 0, + ease: SVG.easing[ease || '-'] || ease + }); + + this.queue(situation); + + return this + } + + /** + * sets a delay before the next element of the queue is called + * @param delay Duration of delay in milliseconds + * @return this.target() + */ + , delay: function(delay){ + // The delay is performed by an empty situation with its duration + // attribute set to the duration of the delay + var situation = new SVG.Situation({ + duration: delay, + delay: 0, + ease: SVG.easing['-'] + }); + + return this.queue(situation) + } + + /** + * sets or returns the target of this animation + * @param null || target SVG.Element which should be set as new target + * @return target || this + */ + , target: function(target){ + if(target && target instanceof SVG.Element){ + this._target = target; + return this + } + + return this._target + } + + // returns the absolute position at a given time + , timeToAbsPos: function(timestamp){ + return (timestamp - this.situation.start) / (this.situation.duration/this._speed) + } + + // returns the timestamp from a given absolute positon + , absPosToTime: function(absPos){ + return this.situation.duration/this._speed * absPos + this.situation.start + } + + // starts the animationloop + , startAnimFrame: function(){ + this.stopAnimFrame(); + this.animationFrame = window.requestAnimationFrame(function(){ this.step(); }.bind(this)); + } + + // cancels the animationframe + , stopAnimFrame: function(){ + window.cancelAnimationFrame(this.animationFrame); + } + + // kicks off the animation - only does something when the queue is currently not active and at least one situation is set + , start: function(){ + // dont start if already started + if(!this.active && this.situation){ + this.active = true; + this.startCurrent(); + } + + return this + } + + // start the current situation + , startCurrent: function(){ + this.situation.start = +new Date + this.situation.delay/this._speed; + this.situation.finish = this.situation.start + this.situation.duration/this._speed; + return this.initAnimations().step() + } + + /** + * adds a function / Situation to the animation queue + * @param fn function / situation to add + * @return this + */ + , queue: function(fn){ + if(typeof fn == 'function' || fn instanceof SVG.Situation) + this.situations.push(fn); + + if(!this.situation) this.situation = this.situations.shift(); + + return this + } + + /** + * pulls next element from the queue and execute it + * @return this + */ + , dequeue: function(){ + // stop current animation + this.stop(); + + // get next animation from queue + this.situation = this.situations.shift(); + + if(this.situation){ + if(this.situation instanceof SVG.Situation) { + this.start(); + } else { + // If it is not a SVG.Situation, then it is a function, we execute it + this.situation.call(this); + } + } + + return this + } + + // updates all animations to the current state of the element + // this is important when one property could be changed from another property + , initAnimations: function() { + var i, j, source; + var s = this.situation; + + if(s.init) return this + + for(i in s.animations){ + source = this.target()[i](); + + if(!Array.isArray(source)) { + source = [source]; + } + + if(!Array.isArray(s.animations[i])) { + s.animations[i] = [s.animations[i]]; + } + + //if(s.animations[i].length > source.length) { + // source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length)) + //} + + for(j = source.length; j--;) { + // The condition is because some methods return a normal number instead + // of a SVG.Number + if(s.animations[i][j] instanceof SVG.Number) + source[j] = new SVG.Number(source[j]); + + s.animations[i][j] = source[j].morph(s.animations[i][j]); + } + } + + for(i in s.attrs){ + s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i]); + } + + for(i in s.styles){ + s.styles[i] = new SVG.MorphObj(this.target().style(i), s.styles[i]); + } + + s.initialTransformation = this.target().matrixify(); + + s.init = true; + return this + } + , clearQueue: function(){ + this.situations = []; + return this + } + , clearCurrent: function(){ + this.situation = null; + return this + } + /** stops the animation immediately + * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. + * @param clearQueue A Boolean indicating whether to remove queued animation as well. + * @return this + */ + , stop: function(jumpToEnd, clearQueue){ + var active = this.active; + this.active = false; + + if(clearQueue){ + this.clearQueue(); + } + + if(jumpToEnd && this.situation){ + // initialize the situation if it was not + !active && this.startCurrent(); + this.atEnd(); + } + + this.stopAnimFrame(); + + return this.clearCurrent() + } + + /** resets the element to the state where the current element has started + * @return this + */ + , reset: function(){ + if(this.situation){ + var temp = this.situation; + this.stop(); + this.situation = temp; + this.atStart(); + } + return this + } + + // Stop the currently-running animation, remove all queued animations, and complete all animations for the element. + , finish: function(){ + + this.stop(true, false); + + while(this.dequeue().situation && this.stop(true, false)); + + this.clearQueue().clearCurrent(); + + return this + } + + // set the internal animation pointer at the start position, before any loops, and updates the visualisation + , atStart: function() { + return this.at(0, true) + } + + // set the internal animation pointer at the end position, after all the loops, and updates the visualisation + , atEnd: function() { + if (this.situation.loops === true) { + // If in a infinite loop, we end the current iteration + this.situation.loops = this.situation.loop + 1; + } + + if(typeof this.situation.loops == 'number') { + // If performing a finite number of loops, we go after all the loops + return this.at(this.situation.loops, true) + } else { + // If no loops, we just go at the end + return this.at(1, true) + } + } + + // set the internal animation pointer to the specified position and updates the visualisation + // if isAbsPos is true, pos is treated as an absolute position + , at: function(pos, isAbsPos){ + var durDivSpd = this.situation.duration/this._speed; + + this.absPos = pos; + // If pos is not an absolute position, we convert it into one + if (!isAbsPos) { + if (this.situation.reversed) this.absPos = 1 - this.absPos; + this.absPos += this.situation.loop; + } + + this.situation.start = +new Date - this.absPos * durDivSpd; + this.situation.finish = this.situation.start + durDivSpd; + + return this.step(true) + } + + /** + * sets or returns the speed of the animations + * @param speed null || Number The new speed of the animations + * @return Number || this + */ + , speed: function(speed){ + if (speed === 0) return this.pause() + + if (speed) { + this._speed = speed; + // We use an absolute position here so that speed can affect the delay before the animation + return this.at(this.absPos, true) + } else return this._speed + } + + // Make loopable + , loop: function(times, reverse) { + var c = this.last(); + + // store total loops + c.loops = (times != null) ? times : true; + c.loop = 0; + + if(reverse) c.reversing = true; + return this + } + + // pauses the animation + , pause: function(){ + this.paused = true; + this.stopAnimFrame(); + + return this + } + + // unpause the animation + , play: function(){ + if(!this.paused) return this + this.paused = false; + // We use an absolute position here so that the delay before the animation can be paused + return this.at(this.absPos, true) + } + + /** + * toggle or set the direction of the animation + * true sets direction to backwards while false sets it to forwards + * @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status) + * @return this + */ + , reverse: function(reversed){ + var c = this.last(); + + if(typeof reversed == 'undefined') c.reversed = !c.reversed; + else c.reversed = reversed; + + return this + } + + + /** + * returns a float from 0-1 indicating the progress of the current animation + * @param eased Boolean indicating whether the returned position should be eased or not + * @return number + */ + , progress: function(easeIt){ + return easeIt ? this.situation.ease(this.pos) : this.pos + } + + /** + * adds a callback function which is called when the current animation is finished + * @param fn Function which should be executed as callback + * @return number + */ + , after: function(fn){ + var c = this.last() + , wrapper = function wrapper(e){ + if(e.detail.situation == c){ + fn.call(this, c); + this.off('finished.fx', wrapper); // prevent memory leak + } + }; + + this.target().on('finished.fx', wrapper); + + return this._callStart() + } + + // adds a callback which is called whenever one animation step is performed + , during: function(fn){ + var c = this.last() + , wrapper = function(e){ + if(e.detail.situation == c){ + fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c); + } + }; + + // see above + this.target().off('during.fx', wrapper).on('during.fx', wrapper); + + this.after(function(){ + this.off('during.fx', wrapper); + }); + + return this._callStart() + } + + // calls after ALL animations in the queue are finished + , afterAll: function(fn){ + var wrapper = function wrapper(e){ + fn.call(this); + this.off('allfinished.fx', wrapper); + }; + + // see above + this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper); + + return this._callStart() + } + + // calls on every animation step for all animations + , duringAll: function(fn){ + var wrapper = function(e){ + fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation); + }; + + this.target().off('during.fx', wrapper).on('during.fx', wrapper); + + this.afterAll(function(){ + this.off('during.fx', wrapper); + }); + + return this._callStart() + } + + , last: function(){ + return this.situations.length ? this.situations[this.situations.length-1] : this.situation + } + + // adds one property to the animations + , add: function(method, args, type){ + this.last()[type || 'animations'][method] = args; + return this._callStart() + } + + /** perform one step of the animation + * @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time + * @return this + */ + , step: function(ignoreTime){ + + // convert current time to an absolute position + if(!ignoreTime) this.absPos = this.timeToAbsPos(+new Date); + + // This part convert an absolute position to a position + if(this.situation.loops !== false) { + var absPos, absPosInt, lastLoop; + + // If the absolute position is below 0, we just treat it as if it was 0 + absPos = Math.max(this.absPos, 0); + absPosInt = Math.floor(absPos); + + if(this.situation.loops === true || absPosInt < this.situation.loops) { + this.pos = absPos - absPosInt; + lastLoop = this.situation.loop; + this.situation.loop = absPosInt; + } else { + this.absPos = this.situation.loops; + this.pos = 1; + // The -1 here is because we don't want to toggle reversed when all the loops have been completed + lastLoop = this.situation.loop - 1; + this.situation.loop = this.situation.loops; + } + + if(this.situation.reversing) { + // Toggle reversed if an odd number of loops as occured since the last call of step + this.situation.reversed = this.situation.reversed != Boolean((this.situation.loop - lastLoop) % 2); + } + + } else { + // If there are no loop, the absolute position must not be above 1 + this.absPos = Math.min(this.absPos, 1); + this.pos = this.absPos; + } + + // while the absolute position can be below 0, the position must not be below 0 + if(this.pos < 0) this.pos = 0; + + if(this.situation.reversed) this.pos = 1 - this.pos; + + + // apply easing + var eased = this.situation.ease(this.pos); + + // call once-callbacks + for(var i in this.situation.once){ + if(i > this.lastPos && i <= eased){ + this.situation.once[i].call(this.target(), this.pos, eased); + delete this.situation.once[i]; + } + } + + // fire during callback with position, eased position and current situation as parameter + if(this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation}); + + // the user may call stop or finish in the during callback + // so make sure that we still have a valid situation + if(!this.situation){ + return this + } + + // apply the actual animation to every property + this.eachAt(); + + // do final code when situation is finished + if((this.pos == 1 && !this.situation.reversed) || (this.situation.reversed && this.pos == 0)){ + + // stop animation callback + this.stopAnimFrame(); + + // fire finished callback with current situation as parameter + this.target().fire('finished', {fx:this, situation: this.situation}); + + if(!this.situations.length){ + this.target().fire('allfinished'); + + // Recheck the length since the user may call animate in the afterAll callback + if(!this.situations.length){ + this.target().off('.fx'); // there shouldnt be any binding left, but to make sure... + this.active = false; + } + } + + // start next animation + if(this.active) this.dequeue(); + else this.clearCurrent(); + + }else if(!this.paused && this.active){ + // we continue animating when we are not at the end + this.startAnimFrame(); + } + + // save last eased position for once callback triggering + this.lastPos = eased; + return this + + } + + // calculates the step for every property and calls block with it + , eachAt: function(){ + var i, len, at, self = this, target = this.target(), s = this.situation; + + // apply animations which can be called trough a method + for(i in s.animations){ + + at = [].concat(s.animations[i]).map(function(el){ + return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el + }); + + target[i].apply(target, at); + + } + + // apply animation which has to be applied with attr() + for(i in s.attrs){ + + at = [i].concat(s.attrs[i]).map(function(el){ + return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el + }); + + target.attr.apply(target, at); + + } + + // apply animation which has to be applied with style() + for(i in s.styles){ + + at = [i].concat(s.styles[i]).map(function(el){ + return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el + }); + + target.style.apply(target, at); + + } + + // animate initialTransformation which has to be chained + if(s.transforms.length){ + + // get initial initialTransformation + at = s.initialTransformation; + for(i = 0, len = s.transforms.length; i < len; i++){ + + // get next transformation in chain + var a = s.transforms[i]; + + // multiply matrix directly + if(a instanceof SVG.Matrix){ + + if(a.relative){ + at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos))); + }else { + at = at.morph(a).at(s.ease(this.pos)); + } + continue + } + + // when transformation is absolute we have to reset the needed transformation first + if(!a.relative) + a.undo(at.extract()); + + // and reapply it after + at = at.multiply(a.at(s.ease(this.pos))); + + } + + // set new matrix on element + target.matrix(at); + } + + return this + + } + + + // adds an once-callback which is called at a specific position and never again + , once: function(pos, fn, isEased){ + var c = this.last(); + if(!isEased) pos = c.ease(pos); + + c.once[pos] = fn; + + return this + } + + , _callStart: function() { + setTimeout(function(){this.start();}.bind(this), 0); + return this + } + + } + +, parent: SVG.Element + + // Add method to parent elements +, construct: { + // Get fx module or create a new one, then animate with given duration and ease + animate: function(o, ease, delay) { + return (this.fx || (this.fx = new SVG.FX(this))).animate(o, ease, delay) + } + , delay: function(delay){ + return (this.fx || (this.fx = new SVG.FX(this))).delay(delay) + } + , stop: function(jumpToEnd, clearQueue) { + if (this.fx) + this.fx.stop(jumpToEnd, clearQueue); + + return this + } + , finish: function() { + if (this.fx) + this.fx.finish(); + + return this + } + // Pause current animation + , pause: function() { + if (this.fx) + this.fx.pause(); + + return this + } + // Play paused current animation + , play: function() { + if (this.fx) + this.fx.play(); + + return this + } + // Set/Get the speed of the animations + , speed: function(speed) { + if (this.fx) + if (speed == null) + return this.fx.speed() + else + this.fx.speed(speed); + + return this + } + } + +}); + +// MorphObj is used whenever no morphable object is given +SVG.MorphObj = SVG.invent({ + + create: function(from, to){ + // prepare color for morphing + if(SVG.Color.isColor(to)) return new SVG.Color(from).morph(to) + // check if we have a list of values + if(SVG.regex.delimiter.test(from)) { + // prepare path for morphing + if(SVG.regex.pathLetters.test(from)) return new SVG.PathArray(from).morph(to) + // prepare value list for morphing + else return new SVG.Array(from).morph(to) + } + // prepare number for morphing + if(SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to) + + // prepare for plain morphing + this.value = from; + this.destination = to; + } + +, extend: { + at: function(pos, real){ + return real < 1 ? this.value : this.destination + }, + + valueOf: function(){ + return this.value + } + } + +}); + +SVG.extend(SVG.FX, { + // Add animatable attributes + attr: function(a, v, relative) { + // apply attributes individually + if (typeof a == 'object') { + for (var key in a) + this.attr(key, a[key]); + + } else { + this.add(a, v, 'attrs'); + } + + return this + } + // Add animatable styles +, style: function(s, v) { + if (typeof s == 'object') + for (var key in s) + this.style(key, s[key]); + + else + this.add(s, v, 'styles'); + + return this + } + // Animatable x-axis +, x: function(x, relative) { + if(this.target() instanceof SVG.G){ + this.transform({x:x}, relative); + return this + } + + var num = new SVG.Number(x); + num.relative = relative; + return this.add('x', num) + } + // Animatable y-axis +, y: function(y, relative) { + if(this.target() instanceof SVG.G){ + this.transform({y:y}, relative); + return this + } + + var num = new SVG.Number(y); + num.relative = relative; + return this.add('y', num) + } + // Animatable center x-axis +, cx: function(x) { + return this.add('cx', new SVG.Number(x)) + } + // Animatable center y-axis +, cy: function(y) { + return this.add('cy', new SVG.Number(y)) + } + // Add animatable move +, move: function(x, y) { + return this.x(x).y(y) + } + // Add animatable center +, center: function(x, y) { + return this.cx(x).cy(y) + } + // Add animatable size +, size: function(width, height) { + if (this.target() instanceof SVG.Text) { + // animate font size for Text elements + this.attr('font-size', width); + + } else { + // animate bbox based size for all other elements + var box; + + if(!width || !height){ + box = this.target().bbox(); + } + + if(!width){ + width = box.width / box.height * height; + } + + if(!height){ + height = box.height / box.width * width; + } + + this.add('width' , new SVG.Number(width)) + .add('height', new SVG.Number(height)); + + } + + return this + } + // Add animatable width +, width: function(width) { + return this.add('width', new SVG.Number(width)) + } + // Add animatable height +, height: function(height) { + return this.add('height', new SVG.Number(height)) + } + // Add animatable plot +, plot: function(a, b, c, d) { + // Lines can be plotted with 4 arguments + if(arguments.length == 4) { + return this.plot([a, b, c, d]) + } + + return this.add('plot', new (this.target().morphArray)(a)) + } + // Add leading method +, leading: function(value) { + return this.target().leading ? + this.add('leading', new SVG.Number(value)) : + this + } + // Add animatable viewbox +, viewbox: function(x, y, width, height) { + if (this.target() instanceof SVG.Container) { + this.add('viewbox', new SVG.ViewBox(x, y, width, height)); + } + + return this + } +, update: function(o) { + if (this.target() instanceof SVG.Stop) { + if (typeof o == 'number' || o instanceof SVG.Number) { + return this.update({ + offset: arguments[0] + , color: arguments[1] + , opacity: arguments[2] + }) + } + + if (o.opacity != null) this.attr('stop-opacity', o.opacity); + if (o.color != null) this.attr('stop-color', o.color); + if (o.offset != null) this.attr('offset', o.offset); + } + + return this + } +}); + +SVG.Box = SVG.invent({ + create: function(x, y, width, height) { + if (typeof x == 'object' && !(x instanceof SVG.Element)) { + // chromes getBoundingClientRect has no x and y property + return SVG.Box.call(this, x.left != null ? x.left : x.x , x.top != null ? x.top : x.y, x.width, x.height) + } else if (arguments.length == 4) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + // add center, right, bottom... + fullBox(this); + } +, extend: { + // Merge rect box with another, return a new instance + merge: function(box) { + var b = new this.constructor(); + + // merge boxes + b.x = Math.min(this.x, box.x); + b.y = Math.min(this.y, box.y); + b.width = Math.max(this.x + this.width, box.x + box.width) - b.x; + b.height = Math.max(this.y + this.height, box.y + box.height) - b.y; + + return fullBox(b) + } + + , transform: function(m) { + var xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, bbox; + + var pts = [ + new SVG.Point(this.x, this.y), + new SVG.Point(this.x2, this.y), + new SVG.Point(this.x, this.y2), + new SVG.Point(this.x2, this.y2) + ]; + + pts.forEach(function(p) { + p = p.transform(m); + xMin = Math.min(xMin,p.x); + xMax = Math.max(xMax,p.x); + yMin = Math.min(yMin,p.y); + yMax = Math.max(yMax,p.y); + }); + + bbox = new this.constructor(); + bbox.x = xMin; + bbox.width = xMax-xMin; + bbox.y = yMin; + bbox.height = yMax-yMin; + + fullBox(bbox); + + return bbox + } + } +}); + +SVG.BBox = SVG.invent({ + // Initialize + create: function(element) { + SVG.Box.apply(this, [].slice.call(arguments)); + + // get values if element is given + if (element instanceof SVG.Element) { + var box; + + // yes this is ugly, but Firefox can be a pain when it comes to elements that are not yet rendered + try { + + if (!document.documentElement.contains){ + // This is IE - it does not support contains() for top-level SVGs + var topParent = element.node; + while (topParent.parentNode){ + topParent = topParent.parentNode; + } + if (topParent != document) throw new Exception('Element not in the dom') + } else { + // the element is NOT in the dom, throw error + if(!document.documentElement.contains(element.node)) throw new Exception('Element not in the dom') + } + + // find native bbox + box = element.node.getBBox(); + } catch(e) { + if(element instanceof SVG.Shape){ + var clone = element.clone(SVG.parser.draw.instance).show(); + box = clone.node.getBBox(); + clone.remove(); + }else { + box = { + x: element.node.clientLeft + , y: element.node.clientTop + , width: element.node.clientWidth + , height: element.node.clientHeight + }; + } + } + + SVG.Box.call(this, box); + } + + } + + // Define ancestor +, inherit: SVG.Box + + // Define Parent +, parent: SVG.Element + + // Constructor +, construct: { + // Get bounding box + bbox: function() { + return new SVG.BBox(this) + } + } + +}); + +SVG.BBox.prototype.constructor = SVG.BBox; + + +SVG.extend(SVG.Element, { + tbox: function(){ + console.warn('Use of TBox is deprecated and mapped to RBox. Use .rbox() instead.'); + return this.rbox(this.doc()) + } +}); + +SVG.RBox = SVG.invent({ + // Initialize + create: function(element) { + SVG.Box.apply(this, [].slice.call(arguments)); + + if (element instanceof SVG.Element) { + SVG.Box.call(this, element.node.getBoundingClientRect()); + } + } + +, inherit: SVG.Box + + // define Parent +, parent: SVG.Element + +, extend: { + addOffset: function() { + // offset by window scroll position, because getBoundingClientRect changes when window is scrolled + this.x += window.pageXOffset; + this.y += window.pageYOffset; + return this + } + } + + // Constructor +, construct: { + // Get rect box + rbox: function(el) { + if (el) return new SVG.RBox(this).transform(el.screenCTM().inverse()) + return new SVG.RBox(this).addOffset() + } + } + +}); + +SVG.RBox.prototype.constructor = SVG.RBox; + +SVG.Matrix = SVG.invent({ + // Initialize + create: function(source) { + var i, base = arrayToMatrix([1, 0, 0, 1, 0, 0]); + + // ensure source as object + source = source instanceof SVG.Element ? + source.matrixify() : + typeof source === 'string' ? + arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat)) : + arguments.length == 6 ? + arrayToMatrix([].slice.call(arguments)) : + Array.isArray(source) ? + arrayToMatrix(source) : + typeof source === 'object' ? + source : base; + + // merge source + for (i = abcdef.length - 1; i >= 0; --i) + this[abcdef[i]] = source[abcdef[i]] != null ? + source[abcdef[i]] : base[abcdef[i]]; + } + + // Add methods +, extend: { + // Extract individual transformations + extract: function() { + // find delta transform points + var px = deltaTransformPoint(this, 0, 1) + , py = deltaTransformPoint(this, 1, 0) + , skewX = 180 / Math.PI * Math.atan2(px.y, px.x) - 90; + + return { + // translation + x: this.e + , y: this.f + , transformedX:(this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b) + , transformedY:(this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d) + // skew + , skewX: -skewX + , skewY: 180 / Math.PI * Math.atan2(py.y, py.x) + // scale + , scaleX: Math.sqrt(this.a * this.a + this.b * this.b) + , scaleY: Math.sqrt(this.c * this.c + this.d * this.d) + // rotation + , rotation: skewX + , a: this.a + , b: this.b + , c: this.c + , d: this.d + , e: this.e + , f: this.f + , matrix: new SVG.Matrix(this) + } + } + // Clone matrix + , clone: function() { + return new SVG.Matrix(this) + } + // Morph one matrix into another + , morph: function(matrix) { + // store new destination + this.destination = new SVG.Matrix(matrix); + + return this + } + // Get morphed matrix at a given position + , at: function(pos) { + // make sure a destination is defined + if (!this.destination) return this + + // calculate morphed matrix at a given position + var matrix = new SVG.Matrix({ + a: this.a + (this.destination.a - this.a) * pos + , b: this.b + (this.destination.b - this.b) * pos + , c: this.c + (this.destination.c - this.c) * pos + , d: this.d + (this.destination.d - this.d) * pos + , e: this.e + (this.destination.e - this.e) * pos + , f: this.f + (this.destination.f - this.f) * pos + }); + + return matrix + } + // Multiplies by given matrix + , multiply: function(matrix) { + return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native())) + } + // Inverses matrix + , inverse: function() { + return new SVG.Matrix(this.native().inverse()) + } + // Translate matrix + , translate: function(x, y) { + return new SVG.Matrix(this.native().translate(x || 0, y || 0)) + } + // Scale matrix + , scale: function(x, y, cx, cy) { + // support uniformal scale + if (arguments.length == 1) { + y = x; + } else if (arguments.length == 3) { + cy = cx; + cx = y; + y = x; + } + + return this.around(cx, cy, new SVG.Matrix(x, 0, 0, y, 0, 0)) + } + // Rotate matrix + , rotate: function(r, cx, cy) { + // convert degrees to radians + r = SVG.utils.radians(r); + + return this.around(cx, cy, new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0)) + } + // Flip matrix on x or y, at a given offset + , flip: function(a, o) { + return a == 'x' ? + this.scale(-1, 1, o, 0) : + a == 'y' ? + this.scale(1, -1, 0, o) : + this.scale(-1, -1, a, o != null ? o : a) + } + // Skew + , skew: function(x, y, cx, cy) { + // support uniformal skew + if (arguments.length == 1) { + y = x; + } else if (arguments.length == 3) { + cy = cx; + cx = y; + y = x; + } + + // convert degrees to radians + x = SVG.utils.radians(x); + y = SVG.utils.radians(y); + + return this.around(cx, cy, new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0)) + } + // SkewX + , skewX: function(x, cx, cy) { + return this.skew(x, 0, cx, cy) + } + // SkewY + , skewY: function(y, cx, cy) { + return this.skew(0, y, cx, cy) + } + // Transform around a center point + , around: function(cx, cy, matrix) { + return this + .multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0)) + .multiply(matrix) + .multiply(new SVG.Matrix(1, 0, 0, 1, -cx || 0, -cy || 0)) + } + // Convert to native SVGMatrix + , native: function() { + // create new matrix + var matrix = SVG.parser.native.createSVGMatrix(); + + // update with current values + for (var i = abcdef.length - 1; i >= 0; i--) + matrix[abcdef[i]] = this[abcdef[i]]; + + return matrix + } + // Convert matrix to string + , toString: function() { + // Construct the matrix directly, avoid values that are too small + return 'matrix(' + float32String(this.a) + ',' + float32String(this.b) + + ',' + float32String(this.c) + ',' + float32String(this.d) + + ',' + float32String(this.e) + ',' + float32String(this.f) + + ')' + } + } + + // Define parent +, parent: SVG.Element + + // Add parent method +, construct: { + // Get current matrix + ctm: function() { + return new SVG.Matrix(this.node.getCTM()) + }, + // Get current screen matrix + screenCTM: function() { + /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537 + This is needed because FF does not return the transformation matrix + for the inner coordinate system when getScreenCTM() is called on nested svgs. + However all other Browsers do that */ + if(this instanceof SVG.Nested) { + var rect = this.rect(1,1); + var m = rect.node.getScreenCTM(); + rect.remove(); + return new SVG.Matrix(m) + } + return new SVG.Matrix(this.node.getScreenCTM()) + } + + } + +}); + +SVG.Point = SVG.invent({ + // Initialize + create: function(x,y) { + var source, base = {x:0, y:0}; + + // ensure source as object + source = Array.isArray(x) ? + {x:x[0], y:x[1]} : + typeof x === 'object' ? + {x:x.x, y:x.y} : + x != null ? + {x:x, y:(y != null ? y : x)} : base; // If y has no value, then x is used has its value + + // merge source + this.x = source.x; + this.y = source.y; + } + + // Add methods +, extend: { + // Clone point + clone: function() { + return new SVG.Point(this) + } + // Morph one point into another + , morph: function(x, y) { + // store new destination + this.destination = new SVG.Point(x, y); + + return this + } + // Get morphed point at a given position + , at: function(pos) { + // make sure a destination is defined + if (!this.destination) return this + + // calculate morphed matrix at a given position + var point = new SVG.Point({ + x: this.x + (this.destination.x - this.x) * pos + , y: this.y + (this.destination.y - this.y) * pos + }); + + return point + } + // Convert to native SVGPoint + , native: function() { + // create new point + var point = SVG.parser.native.createSVGPoint(); + + // update with current values + point.x = this.x; + point.y = this.y; + + return point + } + // transform point with matrix + , transform: function(matrix) { + return new SVG.Point(this.native().matrixTransform(matrix.native())) + } + + } + +}); + +SVG.extend(SVG.Element, { + + // Get point + point: function(x, y) { + return new SVG.Point(x,y).transform(this.screenCTM().inverse()); + } + +}); + +SVG.extend(SVG.Element, { + // Set svg element attribute + attr: function(a, v, n) { + // act as full getter + if (a == null) { + // get an object of attributes + a = {}; + v = this.node.attributes; + for (n = v.length - 1; n >= 0; n--) + a[v[n].nodeName] = SVG.regex.isNumber.test(v[n].nodeValue) ? parseFloat(v[n].nodeValue) : v[n].nodeValue; + + return a + + } else if (typeof a == 'object') { + // apply every attribute individually if an object is passed + for (v in a) this.attr(v, a[v]); + + } else if (v === null) { + // remove value + this.node.removeAttribute(a); + + } else if (v == null) { + // act as a getter if the first and only argument is not an object + v = this.node.getAttribute(a); + return v == null ? + SVG.defaults.attrs[a] : + SVG.regex.isNumber.test(v) ? + parseFloat(v) : v + + } else { + // BUG FIX: some browsers will render a stroke if a color is given even though stroke width is 0 + if (a == 'stroke-width') + this.attr('stroke', parseFloat(v) > 0 ? this._stroke : null); + else if (a == 'stroke') + this._stroke = v; + + // convert image fill and stroke to patterns + if (a == 'fill' || a == 'stroke') { + if (SVG.regex.isImage.test(v)) + v = this.doc().defs().image(v, 0, 0); + + if (v instanceof SVG.Image) + v = this.doc().defs().pattern(0, 0, function() { + this.add(v); + }); + } + + // ensure correct numeric values (also accepts NaN and Infinity) + if (typeof v === 'number') + v = new SVG.Number(v); + + // ensure full hex color + else if (SVG.Color.isColor(v)) + v = new SVG.Color(v); + + // parse array values + else if (Array.isArray(v)) + v = new SVG.Array(v); + + // if the passed attribute is leading... + if (a == 'leading') { + // ... call the leading method instead + if (this.leading) + this.leading(v); + } else { + // set given attribute on node + typeof n === 'string' ? + this.node.setAttributeNS(n, a, v.toString()) : + this.node.setAttribute(a, v.toString()); + } + + // rebuild if required + if (this.rebuild && (a == 'font-size' || a == 'x')) + this.rebuild(a, v); + } + + return this + } +}); +SVG.extend(SVG.Element, { + // Add transformations + transform: function(o, relative) { + // get target in case of the fx module, otherwise reference this + var target = this + , matrix, bbox; + + // act as a getter + if (typeof o !== 'object') { + // get current matrix + matrix = new SVG.Matrix(target).extract(); + + return typeof o === 'string' ? matrix[o] : matrix + } + + // get current matrix + matrix = new SVG.Matrix(target); + + // ensure relative flag + relative = !!relative || !!o.relative; + + // act on matrix + if (o.a != null) { + matrix = relative ? + // relative + matrix.multiply(new SVG.Matrix(o)) : + // absolute + new SVG.Matrix(o); + + // act on rotation + } else if (o.rotation != null) { + // ensure centre point + ensureCentre(o, target); + + // apply transformation + matrix = relative ? + // relative + matrix.rotate(o.rotation, o.cx, o.cy) : + // absolute + matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy); + + // act on scale + } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { + // ensure centre point + ensureCentre(o, target); + + // ensure scale values on both axes + o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1; + o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1; + + if (!relative) { + // absolute; multiply inversed values + var e = matrix.extract(); + o.scaleX = o.scaleX * 1 / e.scaleX; + o.scaleY = o.scaleY * 1 / e.scaleY; + } + + matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy); + + // act on skew + } else if (o.skew != null || o.skewX != null || o.skewY != null) { + // ensure centre point + ensureCentre(o, target); + + // ensure skew values on both axes + o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0; + o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0; + + if (!relative) { + // absolute; reset skew values + var e = matrix.extract(); + matrix = matrix.multiply(new SVG.Matrix().skew(e.skewX, e.skewY, o.cx, o.cy).inverse()); + } + + matrix = matrix.skew(o.skewX, o.skewY, o.cx, o.cy); + + // act on flip + } else if (o.flip) { + if(o.flip == 'x' || o.flip == 'y') { + o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset; + } else { + if(o.offset == null) { + bbox = target.bbox(); + o.flip = bbox.cx; + o.offset = bbox.cy; + } else { + o.flip = o.offset; + } + } + + matrix = new SVG.Matrix().flip(o.flip, o.offset); + + // act on translate + } else if (o.x != null || o.y != null) { + if (relative) { + // relative + matrix = matrix.translate(o.x, o.y); + } else { + // absolute + if (o.x != null) matrix.e = o.x; + if (o.y != null) matrix.f = o.y; + } + } + + return this.attr('transform', matrix) + } +}); + +SVG.extend(SVG.FX, { + transform: function(o, relative) { + // get target in case of the fx module, otherwise reference this + var target = this.target() + , matrix, bbox; + + // act as a getter + if (typeof o !== 'object') { + // get current matrix + matrix = new SVG.Matrix(target).extract(); + + return typeof o === 'string' ? matrix[o] : matrix + } + + // ensure relative flag + relative = !!relative || !!o.relative; + + // act on matrix + if (o.a != null) { + matrix = new SVG.Matrix(o); + + // act on rotation + } else if (o.rotation != null) { + // ensure centre point + ensureCentre(o, target); + + // apply transformation + matrix = new SVG.Rotate(o.rotation, o.cx, o.cy); + + // act on scale + } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { + // ensure centre point + ensureCentre(o, target); + + // ensure scale values on both axes + o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1; + o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1; + + matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy); + + // act on skew + } else if (o.skewX != null || o.skewY != null) { + // ensure centre point + ensureCentre(o, target); + + // ensure skew values on both axes + o.skewX = o.skewX != null ? o.skewX : 0; + o.skewY = o.skewY != null ? o.skewY : 0; + + matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy); + + // act on flip + } else if (o.flip) { + if(o.flip == 'x' || o.flip == 'y') { + o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset; + } else { + if(o.offset == null) { + bbox = target.bbox(); + o.flip = bbox.cx; + o.offset = bbox.cy; + } else { + o.flip = o.offset; + } + } + + matrix = new SVG.Matrix().flip(o.flip, o.offset); + + // act on translate + } else if (o.x != null || o.y != null) { + matrix = new SVG.Translate(o.x, o.y); + } + + if(!matrix) return this + + matrix.relative = relative; + + this.last().transforms.push(matrix); + + return this._callStart() + } +}); + +SVG.extend(SVG.Element, { + // Reset all transformations + untransform: function() { + return this.attr('transform', null) + }, + // merge the whole transformation chain into one matrix and returns it + matrixify: function() { + + var matrix = (this.attr('transform') || '') + // split transformations + .split(SVG.regex.transforms).slice(0,-1).map(function(str){ + // generate key => value pairs + var kv = str.trim().split('('); + return [kv[0], kv[1].split(SVG.regex.delimiter).map(function(str){ return parseFloat(str) })] + }) + // merge every transformation into one matrix + .reduce(function(matrix, transform){ + + if(transform[0] == 'matrix') return matrix.multiply(arrayToMatrix(transform[1])) + return matrix[transform[0]].apply(matrix, transform[1]) + + }, new SVG.Matrix()); + + return matrix + }, + // add an element to another parent without changing the visual representation on the screen + toParent: function(parent) { + if(this == parent) return this + var ctm = this.screenCTM(); + var pCtm = parent.screenCTM().inverse(); + + this.addTo(parent).untransform().transform(pCtm.multiply(ctm)); + + return this + }, + // same as above with parent equals root-svg + toDoc: function() { + return this.toParent(this.doc()) + } + +}); + +SVG.Transformation = SVG.invent({ + + create: function(source, inversed){ + + if(arguments.length > 1 && typeof inversed != 'boolean'){ + return this.constructor.call(this, [].slice.call(arguments)) + } + + if(Array.isArray(source)){ + for(var i = 0, len = this.arguments.length; i < len; ++i){ + this[this.arguments[i]] = source[i]; + } + } else if(typeof source == 'object'){ + for(var i = 0, len = this.arguments.length; i < len; ++i){ + this[this.arguments[i]] = source[this.arguments[i]]; + } + } + + this.inversed = false; + + if(inversed === true){ + this.inversed = true; + } + + } + +, extend: { + + arguments: [] + , method: '' + + , at: function(pos){ + + var params = []; + + for(var i = 0, len = this.arguments.length; i < len; ++i){ + params.push(this[this.arguments[i]]); + } + + var m = this._undo || new SVG.Matrix(); + + m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos); + + return this.inversed ? m.inverse() : m + + } + + , undo: function(o){ + for(var i = 0, len = this.arguments.length; i < len; ++i){ + o[this.arguments[i]] = typeof this[this.arguments[i]] == 'undefined' ? 0 : o[this.arguments[i]]; + } + + // The method SVG.Matrix.extract which was used before calling this + // method to obtain a value for the parameter o doesn't return a cx and + // a cy so we use the ones that were provided to this object at its creation + o.cx = this.cx; + o.cy = this.cy; + + this._undo = new SVG[capitalize(this.method)](o, true).at(1); + + return this + } + + } + +}); + +SVG.Translate = SVG.invent({ + + parent: SVG.Matrix +, inherit: SVG.Transformation + +, create: function(source, inversed){ + this.constructor.apply(this, [].slice.call(arguments)); + } + +, extend: { + arguments: ['transformedX', 'transformedY'] + , method: 'translate' + } + +}); + +SVG.Rotate = SVG.invent({ + + parent: SVG.Matrix +, inherit: SVG.Transformation + +, create: function(source, inversed){ + this.constructor.apply(this, [].slice.call(arguments)); + } + +, extend: { + arguments: ['rotation', 'cx', 'cy'] + , method: 'rotate' + , at: function(pos){ + var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy); + return this.inversed ? m.inverse() : m + } + , undo: function(o){ + this._undo = o; + return this + } + } + +}); + +SVG.Scale = SVG.invent({ + + parent: SVG.Matrix +, inherit: SVG.Transformation + +, create: function(source, inversed){ + this.constructor.apply(this, [].slice.call(arguments)); + } + +, extend: { + arguments: ['scaleX', 'scaleY', 'cx', 'cy'] + , method: 'scale' + } + +}); + +SVG.Skew = SVG.invent({ + + parent: SVG.Matrix +, inherit: SVG.Transformation + +, create: function(source, inversed){ + this.constructor.apply(this, [].slice.call(arguments)); + } + +, extend: { + arguments: ['skewX', 'skewY', 'cx', 'cy'] + , method: 'skew' + } + +}); + +SVG.extend(SVG.Element, { + // Dynamic style generator + style: function(s, v) { + if (arguments.length == 0) { + // get full style + return this.node.style.cssText || '' + + } else if (arguments.length < 2) { + // apply every style individually if an object is passed + if (typeof s == 'object') { + for (v in s) this.style(v, s[v]); + + } else if (SVG.regex.isCss.test(s)) { + // parse css string + s = s.split(/\s*;\s*/) + // filter out suffix ; and stuff like ;; + .filter(function(e) { return !!e }) + .map(function(e){ return e.split(/\s*:\s*/) }); + + // apply every definition individually + while (v = s.pop()) { + this.style(v[0], v[1]); + } + } else { + // act as a getter if the first and only argument is not an object + return this.node.style[camelCase(s)] + } + + } else { + this.node.style[camelCase(s)] = v === null || SVG.regex.isBlank.test(v) ? '' : v; + } + + return this + } +}); +SVG.Parent = SVG.invent({ + // Initialize node + create: function(element) { + this.constructor.call(this, element); + } + + // Inherit from +, inherit: SVG.Element + + // Add class methods +, extend: { + // Returns all child elements + children: function() { + return SVG.utils.map(SVG.utils.filterSVGElements(this.node.childNodes), function(node) { + return SVG.adopt(node) + }) + } + // Add given element at a position + , add: function(element, i) { + if (i == null) + this.node.appendChild(element.node); + else if (element.node != this.node.childNodes[i]) + this.node.insertBefore(element.node, this.node.childNodes[i]); + + return this + } + // Basically does the same as `add()` but returns the added element instead + , put: function(element, i) { + this.add(element, i); + return element + } + // Checks if the given element is a child + , has: function(element) { + return this.index(element) >= 0 + } + // Gets index of given element + , index: function(element) { + return [].slice.call(this.node.childNodes).indexOf(element.node) + } + // Get a element at the given index + , get: function(i) { + return SVG.adopt(this.node.childNodes[i]) + } + // Get first child + , first: function() { + return this.get(0) + } + // Get the last child + , last: function() { + return this.get(this.node.childNodes.length - 1) + } + // Iterates over all children and invokes a given block + , each: function(block, deep) { + var i, il + , children = this.children(); + + for (i = 0, il = children.length; i < il; i++) { + if (children[i] instanceof SVG.Element) + block.apply(children[i], [i, children]); + + if (deep && (children[i] instanceof SVG.Container)) + children[i].each(block, deep); + } + + return this + } + // Remove a given child + , removeElement: function(element) { + this.node.removeChild(element.node); + + return this + } + // Remove all elements in this container + , clear: function() { + // remove children + while(this.node.hasChildNodes()) + this.node.removeChild(this.node.lastChild); + + // remove defs reference + delete this._defs; + + return this + } + , // Get defs + defs: function() { + return this.doc().defs() + } + } + +}); + +SVG.extend(SVG.Parent, { + + ungroup: function(parent, depth) { + if(depth === 0 || this instanceof SVG.Defs || this.node == SVG.parser.draw) return this + + parent = parent || (this instanceof SVG.Doc ? this : this.parent(SVG.Parent)); + depth = depth || Infinity; + + this.each(function(){ + if(this instanceof SVG.Defs) return this + if(this instanceof SVG.Parent) return this.ungroup(parent, depth-1) + return this.toParent(parent) + }); + + this.node.firstChild || this.remove(); + + return this + }, + + flatten: function(parent, depth) { + return this.ungroup(parent, depth) + } + +}); +SVG.Container = SVG.invent({ + // Initialize node + create: function(element) { + this.constructor.call(this, element); + } + + // Inherit from +, inherit: SVG.Parent + +}); + +SVG.ViewBox = SVG.invent({ + + create: function(source) { + var base = [0, 0, 0, 0]; + + var x, y, width, height, view, we, he + , wm = 1 // width multiplier + , hm = 1 // height multiplier + , reg = /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/gi; + + if(source instanceof SVG.Element){ + + we = source; + he = source; + view = (source.attr('viewBox') || '').match(reg); + source.bbox; + + // get dimensions of current node + width = new SVG.Number(source.width()); + height = new SVG.Number(source.height()); + + // find nearest non-percentual dimensions + while (width.unit == '%') { + wm *= width.value; + width = new SVG.Number(we instanceof SVG.Doc ? we.parent().offsetWidth : we.parent().width()); + we = we.parent(); + } + while (height.unit == '%') { + hm *= height.value; + height = new SVG.Number(he instanceof SVG.Doc ? he.parent().offsetHeight : he.parent().height()); + he = he.parent(); + } + + // ensure defaults + this.x = 0; + this.y = 0; + this.width = width * wm; + this.height = height * hm; + this.zoom = 1; + + if (view) { + // get width and height from viewbox + x = parseFloat(view[0]); + y = parseFloat(view[1]); + width = parseFloat(view[2]); + height = parseFloat(view[3]); + + // calculate zoom accoring to viewbox + this.zoom = ((this.width / this.height) > (width / height)) ? + this.height / height : + this.width / width; + + // calculate real pixel dimensions on parent SVG.Doc element + this.x = x; + this.y = y; + this.width = width; + this.height = height; + + } + + }else { + + // ensure source as object + source = typeof source === 'string' ? + source.match(reg).map(function(el){ return parseFloat(el) }) : + Array.isArray(source) ? + source : + typeof source == 'object' ? + [source.x, source.y, source.width, source.height] : + arguments.length == 4 ? + [].slice.call(arguments) : + base; + + this.x = source[0]; + this.y = source[1]; + this.width = source[2]; + this.height = source[3]; + } + + + } + +, extend: { + + toString: function() { + return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height + } + , morph: function(x, y, width, height){ + this.destination = new SVG.ViewBox(x, y, width, height); + return this + } + + , at: function(pos) { + + if(!this.destination) return this + + return new SVG.ViewBox([ + this.x + (this.destination.x - this.x) * pos + , this.y + (this.destination.y - this.y) * pos + , this.width + (this.destination.width - this.width) * pos + , this.height + (this.destination.height - this.height) * pos + ]) + + } + + } + + // Define parent +, parent: SVG.Container + + // Add parent method +, construct: { + + // get/set viewbox + viewbox: function(x, y, width, height) { + if (arguments.length == 0) + // act as a getter if there are no arguments + return new SVG.ViewBox(this) + + // otherwise act as a setter + return this.attr('viewBox', new SVG.ViewBox(x, y, width, height)) + } + + } + +}) +// Add events to elements + +;[ 'click', + 'dblclick', + 'mousedown', + 'mouseup', + 'mouseover', + 'mouseout', + 'mousemove', + 'mouseenter', + 'mouseleave', + 'touchstart', + 'touchmove', + 'touchleave', + 'touchend', + 'touchcancel' ].forEach(function (event) { + // add event to SVG.Element + SVG.Element.prototype[event] = function (f) { + // bind event to element rather than element node + if (f == null) { + SVG.off(this, event); + } else { + SVG.on(this, event, f); + } + return this + }; + }); + +SVG.listenerId = 0; + +// Add event binder in the SVG namespace +SVG.on = function (node, events, listener, binding, options) { + var l = listener.bind(binding || node); + var n = node instanceof SVG.Element ? node.node : node; + + // ensure instance object for nodes which are not adopted + n.instance = n.instance || {_events: {}}; + + var bag = n.instance._events; + + // add id to listener + if (!listener._svgjsListenerId) { listener._svgjsListenerId = ++SVG.listenerId; } + + events.split(SVG.regex.delimiter).forEach(function (event) { + var ev = event.split('.')[0]; + var ns = event.split('.')[1] || '*'; + + // ensure valid object + bag[ev] = bag[ev] || {}; + bag[ev][ns] = bag[ev][ns] || {}; + + // reference listener + bag[ev][ns][listener._svgjsListenerId] = l; + + // add listener + n.addEventListener(ev, l, options || false); + }); +}; + +// Add event unbinder in the SVG namespace +SVG.off = function (node, events, listener, options) { + var n = node instanceof SVG.Element ? node.node : node; + if (!n.instance) return + + // listener can be a function or a number + if (typeof listener === 'function') { + listener = listener._svgjsListenerId; + if (!listener) return + } + + var bag = n.instance._events + + ;(events || '').split(SVG.regex.delimiter).forEach(function (event) { + var ev = event && event.split('.')[0]; + var ns = event && event.split('.')[1]; + var namespace, l; + + if (listener) { + // remove listener reference + if (bag[ev] && bag[ev][ns || '*']) { + // removeListener + n.removeEventListener(ev, bag[ev][ns || '*'][listener], options || false); + + delete bag[ev][ns || '*'][listener]; + } + } else if (ev && ns) { + // remove all listeners for a namespaced event + if (bag[ev] && bag[ev][ns]) { + for (l in bag[ev][ns]) { SVG.off(n, [ev, ns].join('.'), l); } + + delete bag[ev][ns]; + } + } else if (ns) { + // remove all listeners for a specific namespace + for (event in bag) { + for (namespace in bag[event]) { + if (ns === namespace) { SVG.off(n, [event, ns].join('.')); } + } + } + } else if (ev) { + // remove all listeners for the event + if (bag[ev]) { + for (namespace in bag[ev]) { SVG.off(n, [ev, namespace].join('.')); } + + delete bag[ev]; + } + } else { + // remove all listeners on a given node + for (event in bag) { SVG.off(n, event); } + + n.instance._events = {}; + } + }); +}; + +SVG.extend(SVG.Element, { + // Bind given event to listener + on: function (event, listener, binding, options) { + SVG.on(this, event, listener, binding, options); + return this + }, + // Unbind event from listener + off: function (event, listener) { + SVG.off(this.node, event, listener); + return this + }, + fire: function (event, data) { + // Dispatch event + if (event instanceof window.Event) { + this.node.dispatchEvent(event); + } else { + this.node.dispatchEvent(event = new SVG.CustomEvent(event, {detail: data, cancelable: true})); + } + this._event = event; + return this + }, + event: function() { + return this._event + } +}); + + +SVG.Defs = SVG.invent({ + // Initialize node + create: 'defs' + + // Inherit from +, inherit: SVG.Container + +}); +SVG.G = SVG.invent({ + // Initialize node + create: 'g' + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Move over x-axis + x: function(x) { + return x == null ? this.transform('x') : this.transform({ x: x - this.x() }, true) + } + // Move over y-axis + , y: function(y) { + return y == null ? this.transform('y') : this.transform({ y: y - this.y() }, true) + } + // Move by center over x-axis + , cx: function(x) { + return x == null ? this.gbox().cx : this.x(x - this.gbox().width / 2) + } + // Move by center over y-axis + , cy: function(y) { + return y == null ? this.gbox().cy : this.y(y - this.gbox().height / 2) + } + , gbox: function() { + + var bbox = this.bbox() + , trans = this.transform(); + + bbox.x += trans.x; + bbox.x2 += trans.x; + bbox.cx += trans.x; + + bbox.y += trans.y; + bbox.y2 += trans.y; + bbox.cy += trans.y; + + return bbox + } + } + + // Add parent method +, construct: { + // Create a group element + group: function() { + return this.put(new SVG.G) + } + } +}); + +SVG.Doc = SVG.invent({ + // Initialize node + create: function(element) { + if (element) { + // ensure the presence of a dom element + element = typeof element == 'string' ? + document.getElementById(element) : + element; + + // If the target is an svg element, use that element as the main wrapper. + // This allows svg.js to work with svg documents as well. + if (element.nodeName == 'svg') { + this.constructor.call(this, element); + } else { + this.constructor.call(this, SVG.create('svg')); + element.appendChild(this.node); + this.size('100%', '100%'); + } + + // set svg element attributes and ensure defs node + this.namespace().defs(); + } + } + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Add namespaces + namespace: function() { + return this + .attr({ xmlns: SVG.ns, version: '1.1' }) + .attr('xmlns:xlink', SVG.xlink, SVG.xmlns) + .attr('xmlns:svgjs', SVG.svgjs, SVG.xmlns) + } + // Creates and returns defs element + , defs: function() { + if (!this._defs) { + var defs; + + // Find or create a defs element in this instance + if (defs = this.node.getElementsByTagName('defs')[0]) + this._defs = SVG.adopt(defs); + else + this._defs = new SVG.Defs; + + // Make sure the defs node is at the end of the stack + this.node.appendChild(this._defs.node); + } + + return this._defs + } + // custom parent method + , parent: function() { + if(!this.node.parentNode || this.node.parentNode.nodeName == '#document' || this.node.parentNode.nodeName == '#document-fragment') return null + return this.node.parentNode + } + // Fix for possible sub-pixel offset. See: + // https://bugzilla.mozilla.org/show_bug.cgi?id=608812 + , spof: function() { + var pos = this.node.getScreenCTM(); + + if (pos) + this + .style('left', (-pos.e % 1) + 'px') + .style('top', (-pos.f % 1) + 'px'); + + return this + } + + // Removes the doc from the DOM + , remove: function() { + if(this.parent()) { + this.parent().removeChild(this.node); + } + + return this + } + , clear: function() { + // remove children + while(this.node.hasChildNodes()) + this.node.removeChild(this.node.lastChild); + + // remove defs reference + delete this._defs; + + // add back parser + if(!SVG.parser.draw.parentNode) + this.node.appendChild(SVG.parser.draw); + + return this + } + , clone: function (parent) { + // write dom data to the dom so the clone can pickup the data + this.writeDataToDom(); + + // get reference to node + var node = this.node; + + // clone element and assign new id + var clone = assignNewId(node.cloneNode(true)); + + // insert the clone in the given parent or after myself + if(parent) { + (parent.node || parent).appendChild(clone.node); + } else { + node.parentNode.insertBefore(clone.node, node.nextSibling); + } + + return clone + } + } + +}); + +// ### This module adds backward / forward functionality to elements. + +// +SVG.extend(SVG.Element, { + // Get all siblings, including myself + siblings: function() { + return this.parent().children() + } + // Get the curent position siblings +, position: function() { + return this.parent().index(this) + } + // Get the next element (will return null if there is none) +, next: function() { + return this.siblings()[this.position() + 1] + } + // Get the next element (will return null if there is none) +, previous: function() { + return this.siblings()[this.position() - 1] + } + // Send given element one step forward +, forward: function() { + var i = this.position() + 1 + , p = this.parent(); + + // move node one step forward + p.removeElement(this).add(this, i); + + // make sure defs node is always at the top + if (p instanceof SVG.Doc) + p.node.appendChild(p.defs().node); + + return this + } + // Send given element one step backward +, backward: function() { + var i = this.position(); + + if (i > 0) + this.parent().removeElement(this).add(this, i - 1); + + return this + } + // Send given element all the way to the front +, front: function() { + var p = this.parent(); + + // Move node forward + p.node.appendChild(this.node); + + // Make sure defs node is always at the top + if (p instanceof SVG.Doc) + p.node.appendChild(p.defs().node); + + return this + } + // Send given element all the way to the back +, back: function() { + if (this.position() > 0) + this.parent().removeElement(this).add(this, 0); + + return this + } + // Inserts a given element before the targeted element +, before: function(element) { + element.remove(); + + var i = this.position(); + + this.parent().add(element, i); + + return this + } + // Insters a given element after the targeted element +, after: function(element) { + element.remove(); + + var i = this.position(); + + this.parent().add(element, i + 1); + + return this + } + +}); +SVG.Mask = SVG.invent({ + // Initialize node + create: function() { + this.constructor.call(this, SVG.create('mask')); + + // keep references to masked elements + this.targets = []; + } + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Unmask all masked elements and remove itself + remove: function() { + // unmask all targets + for (var i = this.targets.length - 1; i >= 0; i--) + if (this.targets[i]) + this.targets[i].unmask(); + this.targets = []; + + // remove mask from parent + SVG.Element.prototype.remove.call(this); + + return this + } + } + + // Add parent method +, construct: { + // Create masking element + mask: function() { + return this.defs().put(new SVG.Mask) + } + } +}); + + +SVG.extend(SVG.Element, { + // Distribute mask to svg element + maskWith: function(element) { + // use given mask or create a new one + this.masker = element instanceof SVG.Mask ? element : this.parent().mask().add(element); + + // store reverence on self in mask + this.masker.targets.push(this); + + // apply mask + return this.attr('mask', 'url("#' + this.masker.attr('id') + '")') + } + // Unmask element +, unmask: function() { + delete this.masker; + return this.attr('mask', null) + } + +}); + +SVG.ClipPath = SVG.invent({ + // Initialize node + create: function() { + this.constructor.call(this, SVG.create('clipPath')); + + // keep references to clipped elements + this.targets = []; + } + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Unclip all clipped elements and remove itself + remove: function() { + // unclip all targets + for (var i = this.targets.length - 1; i >= 0; i--) + if (this.targets[i]) + this.targets[i].unclip(); + this.targets = []; + + // remove clipPath from parent + this.parent().removeElement(this); + + return this + } + } + + // Add parent method +, construct: { + // Create clipping element + clip: function() { + return this.defs().put(new SVG.ClipPath) + } + } +}); + +// +SVG.extend(SVG.Element, { + // Distribute clipPath to svg element + clipWith: function(element) { + // use given clip or create a new one + this.clipper = element instanceof SVG.ClipPath ? element : this.parent().clip().add(element); + + // store reverence on self in mask + this.clipper.targets.push(this); + + // apply mask + return this.attr('clip-path', 'url("#' + this.clipper.attr('id') + '")') + } + // Unclip element +, unclip: function() { + delete this.clipper; + return this.attr('clip-path', null) + } + +}); +SVG.Gradient = SVG.invent({ + // Initialize node + create: function(type) { + this.constructor.call(this, SVG.create(type + 'Gradient')); + + // store type + this.type = type; + } + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Add a color stop + at: function(offset, color, opacity) { + return this.put(new SVG.Stop).update(offset, color, opacity) + } + // Update gradient + , update: function(block) { + // remove all stops + this.clear(); + + // invoke passed block + if (typeof block == 'function') + block.call(this, this); + + return this + } + // Return the fill id + , fill: function() { + return 'url(#' + this.id() + ')' + } + // Alias string convertion to fill + , toString: function() { + return this.fill() + } + // custom attr to handle transform + , attr: function(a, b, c) { + if(a == 'transform') a = 'gradientTransform'; + return SVG.Container.prototype.attr.call(this, a, b, c) + } + } + + // Add parent method +, construct: { + // Create gradient element in defs + gradient: function(type, block) { + return this.defs().gradient(type, block) + } + } +}); + +// Add animatable methods to both gradient and fx module +SVG.extend(SVG.Gradient, SVG.FX, { + // From position + from: function(x, y) { + return (this._target || this).type == 'radial' ? + this.attr({ fx: new SVG.Number(x), fy: new SVG.Number(y) }) : + this.attr({ x1: new SVG.Number(x), y1: new SVG.Number(y) }) + } + // To position +, to: function(x, y) { + return (this._target || this).type == 'radial' ? + this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) }) : + this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) }) + } +}); + +// Base gradient generation +SVG.extend(SVG.Defs, { + // define gradient + gradient: function(type, block) { + return this.put(new SVG.Gradient(type)).update(block) + } + +}); + +SVG.Stop = SVG.invent({ + // Initialize node + create: 'stop' + + // Inherit from +, inherit: SVG.Element + + // Add class methods +, extend: { + // add color stops + update: function(o) { + if (typeof o == 'number' || o instanceof SVG.Number) { + o = { + offset: arguments[0] + , color: arguments[1] + , opacity: arguments[2] + }; + } + + // set attributes + if (o.opacity != null) this.attr('stop-opacity', o.opacity); + if (o.color != null) this.attr('stop-color', o.color); + if (o.offset != null) this.attr('offset', new SVG.Number(o.offset)); + + return this + } + } + +}); + +SVG.Pattern = SVG.invent({ + // Initialize node + create: 'pattern' + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Return the fill id + fill: function() { + return 'url(#' + this.id() + ')' + } + // Update pattern by rebuilding + , update: function(block) { + // remove content + this.clear(); + + // invoke passed block + if (typeof block == 'function') + block.call(this, this); + + return this + } + // Alias string convertion to fill + , toString: function() { + return this.fill() + } + // custom attr to handle transform + , attr: function(a, b, c) { + if(a == 'transform') a = 'patternTransform'; + return SVG.Container.prototype.attr.call(this, a, b, c) + } + + } + + // Add parent method +, construct: { + // Create pattern element in defs + pattern: function(width, height, block) { + return this.defs().pattern(width, height, block) + } + } +}); + +SVG.extend(SVG.Defs, { + // Define gradient + pattern: function(width, height, block) { + return this.put(new SVG.Pattern).update(block).attr({ + x: 0 + , y: 0 + , width: width + , height: height + , patternUnits: 'userSpaceOnUse' + }) + } + +}); +SVG.Shape = SVG.invent({ + // Initialize node + create: function(element) { + this.constructor.call(this, element); + } + + // Inherit from +, inherit: SVG.Element + +}); + +SVG.Bare = SVG.invent({ + // Initialize + create: function(element, inherit) { + // construct element + this.constructor.call(this, SVG.create(element)); + + // inherit custom methods + if (inherit) + for (var method in inherit.prototype) + if (typeof inherit.prototype[method] === 'function') + this[method] = inherit.prototype[method]; + } + + // Inherit from +, inherit: SVG.Element + + // Add methods +, extend: { + // Insert some plain text + words: function(text) { + // remove contents + while (this.node.hasChildNodes()) + this.node.removeChild(this.node.lastChild); + + // create text node + this.node.appendChild(document.createTextNode(text)); + + return this + } + } +}); + + +SVG.extend(SVG.Parent, { + // Create an element that is not described by SVG.js + element: function(element, inherit) { + return this.put(new SVG.Bare(element, inherit)) + } +}); + +SVG.Symbol = SVG.invent({ + // Initialize node + create: 'symbol' + + // Inherit from +, inherit: SVG.Container + +, construct: { + // create symbol + symbol: function() { + return this.put(new SVG.Symbol) + } + } +}); + +SVG.Use = SVG.invent({ + // Initialize node + create: 'use' + + // Inherit from +, inherit: SVG.Shape + + // Add class methods +, extend: { + // Use element as a reference + element: function(element, file) { + // Set lined element + return this.attr('href', (file || '') + '#' + element, SVG.xlink) + } + } + + // Add parent method +, construct: { + // Create a use element + use: function(element, file) { + return this.put(new SVG.Use).element(element, file) + } + } +}); +SVG.Rect = SVG.invent({ + // Initialize node + create: 'rect' + + // Inherit from +, inherit: SVG.Shape + + // Add parent method +, construct: { + // Create a rect element + rect: function(width, height) { + return this.put(new SVG.Rect()).size(width, height) + } + } +}); +SVG.Circle = SVG.invent({ + // Initialize node + create: 'circle' + + // Inherit from +, inherit: SVG.Shape + + // Add parent method +, construct: { + // Create circle element, based on ellipse + circle: function(size) { + return this.put(new SVG.Circle).rx(new SVG.Number(size).divide(2)).move(0, 0) + } + } +}); + +SVG.extend(SVG.Circle, SVG.FX, { + // Radius x value + rx: function(rx) { + return this.attr('r', rx) + } + // Alias radius x value +, ry: function(ry) { + return this.rx(ry) + } +}); + +SVG.Ellipse = SVG.invent({ + // Initialize node + create: 'ellipse' + + // Inherit from +, inherit: SVG.Shape + + // Add parent method +, construct: { + // Create an ellipse + ellipse: function(width, height) { + return this.put(new SVG.Ellipse).size(width, height).move(0, 0) + } + } +}); + +SVG.extend(SVG.Ellipse, SVG.Rect, SVG.FX, { + // Radius x value + rx: function(rx) { + return this.attr('rx', rx) + } + // Radius y value +, ry: function(ry) { + return this.attr('ry', ry) + } +}); + +// Add common method +SVG.extend(SVG.Circle, SVG.Ellipse, { + // Move over x-axis + x: function(x) { + return x == null ? this.cx() - this.rx() : this.cx(x + this.rx()) + } + // Move over y-axis + , y: function(y) { + return y == null ? this.cy() - this.ry() : this.cy(y + this.ry()) + } + // Move by center over x-axis + , cx: function(x) { + return x == null ? this.attr('cx') : this.attr('cx', x) + } + // Move by center over y-axis + , cy: function(y) { + return y == null ? this.attr('cy') : this.attr('cy', y) + } + // Set width of element + , width: function(width) { + return width == null ? this.rx() * 2 : this.rx(new SVG.Number(width).divide(2)) + } + // Set height of element + , height: function(height) { + return height == null ? this.ry() * 2 : this.ry(new SVG.Number(height).divide(2)) + } + // Custom size function + , size: function(width, height) { + var p = proportionalSize(this, width, height); + + return this + .rx(new SVG.Number(p.width).divide(2)) + .ry(new SVG.Number(p.height).divide(2)) + } +}); +SVG.Line = SVG.invent({ + // Initialize node + create: 'line' + + // Inherit from +, inherit: SVG.Shape + + // Add class methods +, extend: { + // Get array + array: function() { + return new SVG.PointArray([ + [ this.attr('x1'), this.attr('y1') ] + , [ this.attr('x2'), this.attr('y2') ] + ]) + } + // Overwrite native plot() method + , plot: function(x1, y1, x2, y2) { + if (x1 == null) + return this.array() + else if (typeof y1 !== 'undefined') + x1 = { x1: x1, y1: y1, x2: x2, y2: y2 }; + else + x1 = new SVG.PointArray(x1).toLine(); + + return this.attr(x1) + } + // Move by left top corner + , move: function(x, y) { + return this.attr(this.array().move(x, y).toLine()) + } + // Set element size to given width and height + , size: function(width, height) { + var p = proportionalSize(this, width, height); + + return this.attr(this.array().size(p.width, p.height).toLine()) + } + } + + // Add parent method +, construct: { + // Create a line element + line: function(x1, y1, x2, y2) { + // make sure plot is called as a setter + // x1 is not necessarily a number, it can also be an array, a string and a SVG.PointArray + return SVG.Line.prototype.plot.apply( + this.put(new SVG.Line) + , x1 != null ? [x1, y1, x2, y2] : [0, 0, 0, 0] + ) + } + } +}); + +SVG.Polyline = SVG.invent({ + // Initialize node + create: 'polyline' + + // Inherit from +, inherit: SVG.Shape + + // Add parent method +, construct: { + // Create a wrapped polyline element + polyline: function(p) { + // make sure plot is called as a setter + return this.put(new SVG.Polyline).plot(p || new SVG.PointArray) + } + } +}); + +SVG.Polygon = SVG.invent({ + // Initialize node + create: 'polygon' + + // Inherit from +, inherit: SVG.Shape + + // Add parent method +, construct: { + // Create a wrapped polygon element + polygon: function(p) { + // make sure plot is called as a setter + return this.put(new SVG.Polygon).plot(p || new SVG.PointArray) + } + } +}); + +// Add polygon-specific functions +SVG.extend(SVG.Polyline, SVG.Polygon, { + // Get array + array: function() { + return this._array || (this._array = new SVG.PointArray(this.attr('points'))) + } + // Plot new path +, plot: function(p) { + return (p == null) ? + this.array() : + this.clear().attr('points', typeof p == 'string' ? p : (this._array = new SVG.PointArray(p))) + } + // Clear array cache +, clear: function() { + delete this._array; + return this + } + // Move by left top corner +, move: function(x, y) { + return this.attr('points', this.array().move(x, y)) + } + // Set element size to given width and height +, size: function(width, height) { + var p = proportionalSize(this, width, height); + + return this.attr('points', this.array().size(p.width, p.height)) + } + +}); + +// unify all point to point elements +SVG.extend(SVG.Line, SVG.Polyline, SVG.Polygon, { + // Define morphable array + morphArray: SVG.PointArray + // Move by left top corner over x-axis +, x: function(x) { + return x == null ? this.bbox().x : this.move(x, this.bbox().y) + } + // Move by left top corner over y-axis +, y: function(y) { + return y == null ? this.bbox().y : this.move(this.bbox().x, y) + } + // Set width of element +, width: function(width) { + var b = this.bbox(); + + return width == null ? b.width : this.size(width, b.height) + } + // Set height of element +, height: function(height) { + var b = this.bbox(); + + return height == null ? b.height : this.size(b.width, height) + } +}); +SVG.Path = SVG.invent({ + // Initialize node + create: 'path' + + // Inherit from +, inherit: SVG.Shape + + // Add class methods +, extend: { + // Define morphable array + morphArray: SVG.PathArray + // Get array + , array: function() { + return this._array || (this._array = new SVG.PathArray(this.attr('d'))) + } + // Plot new path + , plot: function(d) { + return (d == null) ? + this.array() : + this.clear().attr('d', typeof d == 'string' ? d : (this._array = new SVG.PathArray(d))) + } + // Clear array cache + , clear: function() { + delete this._array; + return this + } + // Move by left top corner + , move: function(x, y) { + return this.attr('d', this.array().move(x, y)) + } + // Move by left top corner over x-axis + , x: function(x) { + return x == null ? this.bbox().x : this.move(x, this.bbox().y) + } + // Move by left top corner over y-axis + , y: function(y) { + return y == null ? this.bbox().y : this.move(this.bbox().x, y) + } + // Set element size to given width and height + , size: function(width, height) { + var p = proportionalSize(this, width, height); + + return this.attr('d', this.array().size(p.width, p.height)) + } + // Set width of element + , width: function(width) { + return width == null ? this.bbox().width : this.size(width, this.bbox().height) + } + // Set height of element + , height: function(height) { + return height == null ? this.bbox().height : this.size(this.bbox().width, height) + } + + } + + // Add parent method +, construct: { + // Create a wrapped path element + path: function(d) { + // make sure plot is called as a setter + return this.put(new SVG.Path).plot(d || new SVG.PathArray) + } + } +}); + +SVG.Image = SVG.invent({ + // Initialize node + create: 'image' + + // Inherit from +, inherit: SVG.Shape + + // Add class methods +, extend: { + // (re)load image + load: function(url) { + if (!url) return this + + var self = this + , img = new window.Image(); + + // preload image + SVG.on(img, 'load', function() { + SVG.off(img); + + var p = self.parent(SVG.Pattern); + + if(p === null) return + + // ensure image size + if (self.width() == 0 && self.height() == 0) + self.size(img.width, img.height); + + // ensure pattern size if not set + if (p && p.width() == 0 && p.height() == 0) + p.size(self.width(), self.height()); + + // callback + if (typeof self._loaded === 'function') + self._loaded.call(self, { + width: img.width + , height: img.height + , ratio: img.width / img.height + , url: url + }); + }); + + SVG.on(img, 'error', function(e){ + SVG.off(img); + + if (typeof self._error === 'function'){ + self._error.call(self, e); + } + }); + + return this.attr('href', (img.src = this.src = url), SVG.xlink) + } + // Add loaded callback + , loaded: function(loaded) { + this._loaded = loaded; + return this + } + + , error: function(error) { + this._error = error; + return this + } + } + + // Add parent method +, construct: { + // create image element, load image and set its size + image: function(source, width, height) { + return this.put(new SVG.Image).load(source).size(width || 0, height || width || 0) + } + } + +}); +SVG.Text = SVG.invent({ + // Initialize node + create: function() { + this.constructor.call(this, SVG.create('text')); + + this.dom.leading = new SVG.Number(1.3); // store leading value for rebuilding + this._rebuild = true; // enable automatic updating of dy values + this._build = false; // disable build mode for adding multiple lines + + // set default font + this.attr('font-family', SVG.defaults.attrs['font-family']); + } + + // Inherit from +, inherit: SVG.Shape + + // Add class methods +, extend: { + // Move over x-axis + x: function(x) { + // act as getter + if (x == null) + return this.attr('x') + + return this.attr('x', x) + } + // Move over y-axis + , y: function(y) { + var oy = this.attr('y') + , o = typeof oy === 'number' ? oy - this.bbox().y : 0; + + // act as getter + if (y == null) + return typeof oy === 'number' ? oy - o : oy + + return this.attr('y', typeof y.valueOf() === 'number' ? y + o : y) + } + // Move center over x-axis + , cx: function(x) { + return x == null ? this.bbox().cx : this.x(x - this.bbox().width / 2) + } + // Move center over y-axis + , cy: function(y) { + return y == null ? this.bbox().cy : this.y(y - this.bbox().height / 2) + } + // Set the text content + , text: function(text) { + // act as getter + if (typeof text === 'undefined'){ + var text = ''; + var children = this.node.childNodes; + for(var i = 0, len = children.length; i < len; ++i){ + + // add newline if its not the first child and newLined is set to true + if(i != 0 && children[i].nodeType != 3 && SVG.adopt(children[i]).dom.newLined == true){ + text += '\n'; + } + + // add content of this node + text += children[i].textContent; + } + + return text + } + + // remove existing content + this.clear().build(true); + + if (typeof text === 'function') { + // call block + text.call(this, this); + + } else { + // store text and make sure text is not blank + text = text.split('\n'); + + // build new lines + for (var i = 0, il = text.length; i < il; i++) + this.tspan(text[i]).newLine(); + } + + // disable build mode and rebuild lines + return this.build(false).rebuild() + } + // Set font size + , size: function(size) { + return this.attr('font-size', size).rebuild() + } + // Set / get leading + , leading: function(value) { + // act as getter + if (value == null) + return this.dom.leading + + // act as setter + this.dom.leading = new SVG.Number(value); + + return this.rebuild() + } + // Get all the first level lines + , lines: function() { + var node = (this.textPath && this.textPath() || this).node; + + // filter tspans and map them to SVG.js instances + var lines = SVG.utils.map(SVG.utils.filterSVGElements(node.childNodes), function(el){ + return SVG.adopt(el) + }); + + // return an instance of SVG.set + return new SVG.Set(lines) + } + // Rebuild appearance type + , rebuild: function(rebuild) { + // store new rebuild flag if given + if (typeof rebuild == 'boolean') + this._rebuild = rebuild; + + // define position of all lines + if (this._rebuild) { + var self = this + , blankLineOffset = 0 + , dy = this.dom.leading * new SVG.Number(this.attr('font-size')); + + this.lines().each(function() { + if (this.dom.newLined) { + if (!self.textPath()) + this.attr('x', self.attr('x')); + if(this.text() == '\n') { + blankLineOffset += dy; + }else { + this.attr('dy', dy + blankLineOffset); + blankLineOffset = 0; + } + } + }); + + this.fire('rebuild'); + } + + return this + } + // Enable / disable build mode + , build: function(build) { + this._build = !!build; + return this + } + // overwrite method from parent to set data properly + , setData: function(o){ + this.dom = o; + this.dom.leading = new SVG.Number(o.leading || 1.3); + return this + } + } + + // Add parent method +, construct: { + // Create text element + text: function(text) { + return this.put(new SVG.Text).text(text) + } + // Create plain text element + , plain: function(text) { + return this.put(new SVG.Text).plain(text) + } + } + +}); + +SVG.Tspan = SVG.invent({ + // Initialize node + create: 'tspan' + + // Inherit from +, inherit: SVG.Shape + + // Add class methods +, extend: { + // Set text content + text: function(text) { + if(text == null) return this.node.textContent + (this.dom.newLined ? '\n' : '') + + typeof text === 'function' ? text.call(this, this) : this.plain(text); + + return this + } + // Shortcut dx + , dx: function(dx) { + return this.attr('dx', dx) + } + // Shortcut dy + , dy: function(dy) { + return this.attr('dy', dy) + } + // Create new line + , newLine: function() { + // fetch text parent + var t = this.parent(SVG.Text); + + // mark new line + this.dom.newLined = true; + + // apply new hy¡n + return this.dy(t.dom.leading * t.attr('font-size')).attr('x', t.x()) + } + } + +}); + +SVG.extend(SVG.Text, SVG.Tspan, { + // Create plain text node + plain: function(text) { + // clear if build mode is disabled + if (this._build === false) + this.clear(); + + // create text node + this.node.appendChild(document.createTextNode(text)); + + return this + } + // Create a tspan +, tspan: function(text) { + var node = (this.textPath && this.textPath() || this).node + , tspan = new SVG.Tspan; + + // clear if build mode is disabled + if (this._build === false) + this.clear(); + + // add new tspan + node.appendChild(tspan.node); + + return tspan.text(text) + } + // Clear all lines +, clear: function() { + var node = (this.textPath && this.textPath() || this).node; + + // remove existing child nodes + while (node.hasChildNodes()) + node.removeChild(node.lastChild); + + return this + } + // Get length of text element +, length: function() { + return this.node.getComputedTextLength() + } +}); + +SVG.TextPath = SVG.invent({ + // Initialize node + create: 'textPath' + + // Inherit from +, inherit: SVG.Parent + + // Define parent class +, parent: SVG.Text + + // Add parent method +, construct: { + morphArray: SVG.PathArray + // Create path for text to run on + , path: function(d) { + // create textPath element + var path = new SVG.TextPath + , track = this.doc().defs().path(d); + + // move lines to textpath + while (this.node.hasChildNodes()) + path.node.appendChild(this.node.firstChild); + + // add textPath element as child node + this.node.appendChild(path.node); + + // link textPath to path and add content + path.attr('href', '#' + track, SVG.xlink); + + return this + } + // return the array of the path track element + , array: function() { + var track = this.track(); + + return track ? track.array() : null + } + // Plot path if any + , plot: function(d) { + var track = this.track() + , pathArray = null; + + if (track) { + pathArray = track.plot(d); + } + + return (d == null) ? pathArray : this + } + // Get the path track element + , track: function() { + var path = this.textPath(); + + if (path) + return path.reference('href') + } + // Get the textPath child + , textPath: function() { + if (this.node.firstChild && this.node.firstChild.nodeName == 'textPath') + return SVG.adopt(this.node.firstChild) + } + } +}); + +SVG.Nested = SVG.invent({ + // Initialize node + create: function() { + this.constructor.call(this, SVG.create('svg')); + + this.style('overflow', 'visible'); + } + + // Inherit from +, inherit: SVG.Container + + // Add parent method +, construct: { + // Create nested svg document + nested: function() { + return this.put(new SVG.Nested) + } + } +}); +SVG.A = SVG.invent({ + // Initialize node + create: 'a' + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Link url + to: function(url) { + return this.attr('href', url, SVG.xlink) + } + // Link show attribute + , show: function(target) { + return this.attr('show', target, SVG.xlink) + } + // Link target attribute + , target: function(target) { + return this.attr('target', target) + } + } + + // Add parent method +, construct: { + // Create a hyperlink element + link: function(url) { + return this.put(new SVG.A).to(url) + } + } +}); + +SVG.extend(SVG.Element, { + // Create a hyperlink element + linkTo: function(url) { + var link = new SVG.A; + + if (typeof url == 'function') + url.call(link, link); + else + link.to(url); + + return this.parent().put(link).put(this) + } + +}); +SVG.Marker = SVG.invent({ + // Initialize node + create: 'marker' + + // Inherit from +, inherit: SVG.Container + + // Add class methods +, extend: { + // Set width of element + width: function(width) { + return this.attr('markerWidth', width) + } + // Set height of element + , height: function(height) { + return this.attr('markerHeight', height) + } + // Set marker refX and refY + , ref: function(x, y) { + return this.attr('refX', x).attr('refY', y) + } + // Update marker + , update: function(block) { + // remove all content + this.clear(); + + // invoke passed block + if (typeof block == 'function') + block.call(this, this); + + return this + } + // Return the fill id + , toString: function() { + return 'url(#' + this.id() + ')' + } + } + + // Add parent method +, construct: { + marker: function(width, height, block) { + // Create marker element in defs + return this.defs().marker(width, height, block) + } + } + +}); + +SVG.extend(SVG.Defs, { + // Create marker + marker: function(width, height, block) { + // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto + return this.put(new SVG.Marker) + .size(width, height) + .ref(width / 2, height / 2) + .viewbox(0, 0, width, height) + .attr('orient', 'auto') + .update(block) + } + +}); + +SVG.extend(SVG.Line, SVG.Polyline, SVG.Polygon, SVG.Path, { + // Create and attach markers + marker: function(marker, width, height, block) { + var attr = ['marker']; + + // Build attribute name + if (marker != 'all') attr.push(marker); + attr = attr.join('-'); + + // Set marker attribute + marker = arguments[1] instanceof SVG.Marker ? + arguments[1] : + this.doc().marker(width, height, block); + + return this.attr(attr, marker) + } + +}); +// Define list of available attributes for stroke and fill +var sugar = { + stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'] +, fill: ['color', 'opacity', 'rule'] +, prefix: function(t, a) { + return a == 'color' ? t : t + '-' + a + } +} + +// Add sugar for fill and stroke +;['fill', 'stroke'].forEach(function(m) { + var i, extension = {}; + + extension[m] = function(o) { + if (typeof o == 'undefined') + return this + if (typeof o == 'string' || SVG.Color.isRgb(o) || (o && typeof o.fill === 'function')) + this.attr(m, o); + + else + // set all attributes from sugar.fill and sugar.stroke list + for (i = sugar[m].length - 1; i >= 0; i--) + if (o[sugar[m][i]] != null) + this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]]); + + return this + }; + + SVG.extend(SVG.Element, SVG.FX, extension); + +}); + +SVG.extend(SVG.Element, SVG.FX, { + // Map rotation to transform + rotate: function(d, cx, cy) { + return this.transform({ rotation: d, cx: cx, cy: cy }) + } + // Map skew to transform +, skew: function(x, y, cx, cy) { + return arguments.length == 1 || arguments.length == 3 ? + this.transform({ skew: x, cx: y, cy: cx }) : + this.transform({ skewX: x, skewY: y, cx: cx, cy: cy }) + } + // Map scale to transform +, scale: function(x, y, cx, cy) { + return arguments.length == 1 || arguments.length == 3 ? + this.transform({ scale: x, cx: y, cy: cx }) : + this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy }) + } + // Map translate to transform +, translate: function(x, y) { + return this.transform({ x: x, y: y }) + } + // Map flip to transform +, flip: function(a, o) { + o = typeof a == 'number' ? a : o; + return this.transform({ flip: a || 'both', offset: o }) + } + // Map matrix to transform +, matrix: function(m) { + return this.attr('transform', new SVG.Matrix(arguments.length == 6 ? [].slice.call(arguments) : m)) + } + // Opacity +, opacity: function(value) { + return this.attr('opacity', value) + } + // Relative move over x axis +, dx: function(x) { + return this.x(new SVG.Number(x).plus(this instanceof SVG.FX ? 0 : this.x()), true) + } + // Relative move over y axis +, dy: function(y) { + return this.y(new SVG.Number(y).plus(this instanceof SVG.FX ? 0 : this.y()), true) + } + // Relative move over x and y axes +, dmove: function(x, y) { + return this.dx(x).dy(y) + } +}); + +SVG.extend(SVG.Rect, SVG.Ellipse, SVG.Circle, SVG.Gradient, SVG.FX, { + // Add x and y radius + radius: function(x, y) { + var type = (this._target || this).type; + return type == 'radial' || type == 'circle' ? + this.attr('r', new SVG.Number(x)) : + this.rx(x).ry(y == null ? x : y) + } +}); + +SVG.extend(SVG.Path, { + // Get path length + length: function() { + return this.node.getTotalLength() + } + // Get point at length +, pointAt: function(length) { + return this.node.getPointAtLength(length) + } +}); + +SVG.extend(SVG.Parent, SVG.Text, SVG.Tspan, SVG.FX, { + // Set font + font: function(a, v) { + if (typeof a == 'object') { + for (v in a) this.font(v, a[v]); + } + + return a == 'leading' ? + this.leading(v) : + a == 'anchor' ? + this.attr('text-anchor', v) : + a == 'size' || a == 'family' || a == 'weight' || a == 'stretch' || a == 'variant' || a == 'style' ? + this.attr('font-'+ a, v) : + this.attr(a, v) + } +}); + +SVG.Set = SVG.invent({ + // Initialize + create: function(members) { + if (members instanceof SVG.Set) { + this.members = members.members.slice(); + } else { + Array.isArray(members) ? this.members = members : this.clear(); + } + } + + // Add class methods +, extend: { + // Add element to set + add: function() { + var i, il, elements = [].slice.call(arguments); + + for (i = 0, il = elements.length; i < il; i++) + this.members.push(elements[i]); + + return this + } + // Remove element from set + , remove: function(element) { + var i = this.index(element); + + // remove given child + if (i > -1) + this.members.splice(i, 1); + + return this + } + // Iterate over all members + , each: function(block) { + for (var i = 0, il = this.members.length; i < il; i++) + block.apply(this.members[i], [i, this.members]); + + return this + } + // Restore to defaults + , clear: function() { + // initialize store + this.members = []; + + return this + } + // Get the length of a set + , length: function() { + return this.members.length + } + // Checks if a given element is present in set + , has: function(element) { + return this.index(element) >= 0 + } + // retuns index of given element in set + , index: function(element) { + return this.members.indexOf(element) + } + // Get member at given index + , get: function(i) { + return this.members[i] + } + // Get first member + , first: function() { + return this.get(0) + } + // Get last member + , last: function() { + return this.get(this.members.length - 1) + } + // Default value + , valueOf: function() { + return this.members + } + // Get the bounding box of all members included or empty box if set has no items + , bbox: function(){ + // return an empty box of there are no members + if (this.members.length == 0) + return new SVG.RBox() + + // get the first rbox and update the target bbox + var rbox = this.members[0].rbox(this.members[0].doc()); + + this.each(function() { + // user rbox for correct position and visual representation + rbox = rbox.merge(this.rbox(this.doc())); + }); + + return rbox + } + } + + // Add parent method +, construct: { + // Create a new set + set: function(members) { + return new SVG.Set(members) + } + } +}); + +SVG.FX.Set = SVG.invent({ + // Initialize node + create: function(set) { + // store reference to set + this.set = set; + } + +}); + +// Alias methods +SVG.Set.inherit = function() { + var m + , methods = []; + + // gather shape methods + for(var m in SVG.Shape.prototype) + if (typeof SVG.Shape.prototype[m] == 'function' && typeof SVG.Set.prototype[m] != 'function') + methods.push(m); + + // apply shape aliasses + methods.forEach(function(method) { + SVG.Set.prototype[method] = function() { + for (var i = 0, il = this.members.length; i < il; i++) + if (this.members[i] && typeof this.members[i][method] == 'function') + this.members[i][method].apply(this.members[i], arguments); + + return method == 'animate' ? (this.fx || (this.fx = new SVG.FX.Set(this))) : this + }; + }); + + // clear methods for the next round + methods = []; + + // gather fx methods + for(var m in SVG.FX.prototype) + if (typeof SVG.FX.prototype[m] == 'function' && typeof SVG.FX.Set.prototype[m] != 'function') + methods.push(m); + + // apply fx aliasses + methods.forEach(function(method) { + SVG.FX.Set.prototype[method] = function() { + for (var i = 0, il = this.set.members.length; i < il; i++) + this.set.members[i].fx[method].apply(this.set.members[i].fx, arguments); + + return this + }; + }); +}; + + +SVG.extend(SVG.Element, { + // Store data values on svg nodes + data: function(a, v, r) { + if (typeof a == 'object') { + for (v in a) + this.data(v, a[v]); + + } else if (arguments.length < 2) { + try { + return JSON.parse(this.attr('data-' + a)) + } catch(e) { + return this.attr('data-' + a) + } + + } else { + this.attr( + 'data-' + a + , v === null ? + null : + r === true || typeof v === 'string' || typeof v === 'number' ? + v : + JSON.stringify(v) + ); + } + + return this + } +}); +SVG.extend(SVG.Element, { + // Remember arbitrary data + remember: function(k, v) { + // remember every item in an object individually + if (typeof arguments[0] == 'object') + for (var v in k) + this.remember(v, k[v]); + + // retrieve memory + else if (arguments.length == 1) + return this.memory()[k] + + // store memory + else + this.memory()[k] = v; + + return this + } + + // Erase a given memory +, forget: function() { + if (arguments.length == 0) + this._memory = {}; + else + for (var i = arguments.length - 1; i >= 0; i--) + delete this.memory()[arguments[i]]; + + return this + } + + // Initialize or return local memory object +, memory: function() { + return this._memory || (this._memory = {}) + } + +}); +// Method for getting an element by id +SVG.get = function(id) { + var node = document.getElementById(idFromReference(id) || id); + return SVG.adopt(node) +}; + +// Select elements by query string +SVG.select = function(query, parent) { + return new SVG.Set( + SVG.utils.map((parent || document).querySelectorAll(query), function(node) { + return SVG.adopt(node) + }) + ) +}; + +SVG.extend(SVG.Parent, { + // Scoped select method + select: function(query) { + return SVG.select(query, this.node) + } + +}); +function pathRegReplace(a, b, c, d) { + return c + d.replace(SVG.regex.dots, ' .') +} + +// creates deep clone of array +function array_clone(arr){ + var clone = arr.slice(0); + for(var i = clone.length; i--;){ + if(Array.isArray(clone[i])){ + clone[i] = array_clone(clone[i]); + } + } + return clone +} + +// tests if a given element is instance of an object +function is(el, obj){ + return el instanceof obj +} + +// tests if a given selector matches an element +function matches(el, selector) { + return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); +} + +// Convert dash-separated-string to camelCase +function camelCase(s) { + return s.toLowerCase().replace(/-(.)/g, function(m, g) { + return g.toUpperCase() + }) +} + +// Capitalize first letter of a string +function capitalize(s) { + return s.charAt(0).toUpperCase() + s.slice(1) +} + +// Ensure to six-based hex +function fullHex(hex) { + return hex.length == 4 ? + [ '#', + hex.substring(1, 2), hex.substring(1, 2) + , hex.substring(2, 3), hex.substring(2, 3) + , hex.substring(3, 4), hex.substring(3, 4) + ].join('') : hex +} + +// Component to hex value +function compToHex(comp) { + var hex = comp.toString(16); + return hex.length == 1 ? '0' + hex : hex +} + +// Calculate proportional width and height values when necessary +function proportionalSize(element, width, height) { + if (width == null || height == null) { + var box = element.bbox(); + + if (width == null) + width = box.width / box.height * height; + else if (height == null) + height = box.height / box.width * width; + } + + return { + width: width + , height: height + } +} + +// Delta transform point +function deltaTransformPoint(matrix, x, y) { + return { + x: x * matrix.a + y * matrix.c + 0 + , y: x * matrix.b + y * matrix.d + 0 + } +} + +// Map matrix array to object +function arrayToMatrix(a) { + return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] } +} + +// Parse matrix if required +function parseMatrix(matrix) { + if (!(matrix instanceof SVG.Matrix)) + matrix = new SVG.Matrix(matrix); + + return matrix +} + +// Add centre point to transform object +function ensureCentre(o, target) { + o.cx = o.cx == null ? target.bbox().cx : o.cx; + o.cy = o.cy == null ? target.bbox().cy : o.cy; +} + +// PathArray Helpers +function arrayToString(a) { + for (var i = 0, il = a.length, s = ''; i < il; i++) { + s += a[i][0]; + + if (a[i][1] != null) { + s += a[i][1]; + + if (a[i][2] != null) { + s += ' '; + s += a[i][2]; + + if (a[i][3] != null) { + s += ' '; + s += a[i][3]; + s += ' '; + s += a[i][4]; + + if (a[i][5] != null) { + s += ' '; + s += a[i][5]; + s += ' '; + s += a[i][6]; + + if (a[i][7] != null) { + s += ' '; + s += a[i][7]; + } + } + } + } + } + } + + return s + ' ' +} + +// Deep new id assignment +function assignNewId(node) { + // do the same for SVG child nodes as well + for (var i = node.childNodes.length - 1; i >= 0; i--) + if (node.childNodes[i] instanceof window.SVGElement) + assignNewId(node.childNodes[i]); + + return SVG.adopt(node).id(SVG.eid(node.nodeName)) +} + +// Add more bounding box properties +function fullBox(b) { + if (b.x == null) { + b.x = 0; + b.y = 0; + b.width = 0; + b.height = 0; + } + + b.w = b.width; + b.h = b.height; + b.x2 = b.x + b.width; + b.y2 = b.y + b.height; + b.cx = b.x + b.width / 2; + b.cy = b.y + b.height / 2; + + return b +} + +// Get id from reference string +function idFromReference(url) { + var m = (url || '').toString().match(SVG.regex.reference); + + if (m) return m[1] +} + +// If values like 1e-88 are passed, this is not a valid 32 bit float, +// but in those cases, we are so close to 0 that 0 works well! +function float32String(v) { + return Math.abs(v) > 1e-37 ? v : 0 +} + +// Create matrix array for looping +var abcdef = 'abcdef'.split(''); + +// Add CustomEvent to IE9 and IE10 +if (typeof window.CustomEvent !== 'function') { + // Code from: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent + var CustomEventPoly = function(event, options) { + options = options || { bubbles: false, cancelable: false, detail: undefined }; + var e = document.createEvent('CustomEvent'); + e.initCustomEvent(event, options.bubbles, options.cancelable, options.detail); + return e + }; + + CustomEventPoly.prototype = window.Event.prototype; + + SVG.CustomEvent = CustomEventPoly; +} else { + SVG.CustomEvent = window.CustomEvent; +} + +// requestAnimationFrame / cancelAnimationFrame Polyfill with fallback based on Paul Irish +(function(w) { + var lastTime = 0; + var vendors = ['moz', 'webkit']; + + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + w.requestAnimationFrame = w[vendors[x] + 'RequestAnimationFrame']; + w.cancelAnimationFrame = w[vendors[x] + 'CancelAnimationFrame'] || + w[vendors[x] + 'CancelRequestAnimationFrame']; + } + + w.requestAnimationFrame = w.requestAnimationFrame || + function(callback) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + + var id = w.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + + lastTime = currTime + timeToCall; + return id + }; + + w.cancelAnimationFrame = w.cancelAnimationFrame || w.clearTimeout; + +}(window)); + +return SVG + +})); +}); + +class History { + constructor(limit) { + this.limit = 50; + this.undos = []; + this.redos = []; + this.saveCommand = null; + this.limit = limit || 50; + } + execute(command) { + this.clearRedo(); + command.execute(); + var length = this.undos.length; + if (length >= this.limit) { + this.undos.shift(); + } + this.undos.push(command); + this.change(command); + } + undo() { + if (this.canUndo()) { + var command = this.undos.pop(); + this.redos.push(command); + command.undo(); + this.change(command); + } + } + canUndo() { + return !!this.undos.length; + } + redo() { + if (this.canRedo()) { + var command = this.redos.pop(); + this.undos.push(command); + command.redo(); + this.change(command); + } + } + canRedo() { + return !!this.redos.length; + } + save() { + this.saveCommand = this.undos[this.undos.length - 1]; + } + dirty() { + return this.saveCommand != this.undos[this.undos.length - 1]; + } + clearRedo() { + this.redos = []; + } + clear() { + this.undos = []; + this.redos = []; + this.saveCommand = null; + this.change(); + } + change(cmd) { + } +} + +class Command { + constructor(name) { + this.name = name; + } + execute() { } + undo() { } + redo() { + this.execute(); + } + refresh(mind) { + var m = mind || this.mind; + if (m) { + m.emit('renderEditNode', {}); + m.emit('mindMapChange', {}); + } + } +} +class AddNode extends Command { + constructor(node, parent, mind) { + super('addNode'); + this.parent = null; + this.mind = null; + this.index = -1; + this.node = node; + this.parent = parent; + this.mind = mind || this.node.mindmap; + } + execute() { + if (this.index > -1) { + this.mind.addNode(this.node, this.parent, this.index); //add node to position of parent children + } + else { + this.mind.addNode(this.node, this.parent); + } + this.node.refreshBox(); + this.refresh(); + this.mind.clearSelectNode(); + setTimeout(() => { + this.node.select(); + this.node.edit(); + }, 0); + } + undo() { + var p = this.node.parent; + this.index = this.mind.removeNode(this.node); + this.mind.clearSelectNode(); + setTimeout(() => { + this.refresh(); + p && p.select(); + }, 0); + } +} +class RemoveNode extends Command { + constructor(node, mind) { + super('removeNode'); + this.parent = null; + this.mind = null; + this.index = -1; + this.node = node; + this.parent = this.node.parent || null; + this.mind = mind || this.node.mindmap; + } + execute() { + this.node.clearCacheData(); + this.mind.clearSelectNode(); + this.index = this.mind.removeNode(this.node); + this.refresh(); + this.parent && this.parent.select(); + } + undo() { + this.mind.addNode(this.node, this.parent, this.index); + this.node.clearCacheData(); + this.node.refreshBox(); + this.mind.clearSelectNode(); + this.refresh(); + setTimeout(() => { + this.node.select(); + }, 0); + } +} +class ChangeNodeText extends Command { + constructor(node, oldText, text) { + super('changeNodeText'); + this.node = node; + this.oldText = oldText; + this.text = text; + this.isFirst = true; + } + execute() { + if (!this.isFirst) { + this.node.setText(this.text); + } + this.node.refreshBox(); + this.node.clearCacheData(); + this.refresh(this.node.mindmap); + } + undo() { + this.node.setText(this.oldText); + this.node.clearCacheData(); + this.node.refreshBox(); + this.refresh(this.node.mindmap); + this.isFirst = false; + } +} +class MoveNode extends Command { + constructor(data) { + super('moveNode'); + this.data = {}; + this.index = -1; + this.data = data; + if (this.data.type.indexOf('child') > -1) { + this.node = this.data.node; + this.oldParent = this.data.oldParent; + this.parent = this.data.parent; + } + else { + this.node = this.data.node; + this.oldParent = this.node.parent; + this.dropNode = this.data.dropNode; + this.newParent = this.dropNode.parent; + this.type = this.data.direct; + } + } + execute() { + this.node.mindmap.clearSelectNode(); + if (this.data.type.indexOf('child') > -1) { + if (this.oldParent) { + this.index = this.oldParent.removeChild(this.node); + } + this.parent.addChild(this.node); + this.node.mindmap.traverseBF((n) => { + n.boundingRect = null; + n.stroke = ''; + }, this.node); + this.node.clearCacheData(); + this.oldParent.clearCacheData(); + this.refresh(this.node.mindmap); + this.node.select(); + } + else { + if (this.oldParent) { + this.index = this.oldParent.removeChild(this.node); + } + this.node.mindmap.traverseBF((n) => { + n.boundingRect = null; + n.stroke = ''; + }, this.node); + this.oldParent.clearCacheData(); + var dropNodeIndex = this.newParent.children.indexOf(this.dropNode); + if (this.type == 'top' || this.type == 'left') { + this.newParent.addChild(this.node, dropNodeIndex); + } + else { + this.newParent.addChild(this.node, dropNodeIndex + 1); + } + this.node.clearCacheData(); + this.refresh(this.node.mindmap); + this.node.select(); + } + } + undo() { + this.node.mindmap.clearSelectNode(); + if (this.data.type.indexOf('child') > -1) { + this.parent.removeChild(this.node); + if (this.oldParent) { + this.oldParent.addChild(this.node, this.index); + } + this.node.mindmap.traverseBF((n) => { + n.boundingRect = null; + n.stroke = ''; + }, this.node); + this.parent.clearCacheData(); + this.node.clearCacheData(); + this.refresh(this.node.mindmap); + this.node.select(); + } + else { + this.newParent.removeChild(this.node); + this.dropNode.clearCacheData(); + this.oldParent.addChild(this.node, this.index); + this.node.clearCacheData(); + this.refresh(this.node.mindmap); + this.node.select(); + } + } +} +class MovePos extends Command { + constructor(node, oldPos, newPos) { + super('movePos'); + this.node = node; + this.oldPos = oldPos; + this.newPos = newPos; + } + execute() { + this.node.setPosition(this.newPos.x, this.newPos.y); + this.refresh(this.node.mindmap); + } + undo() { + this.node.setPosition(this.oldPos.x, this.oldPos.y); + this.refresh(this.node.mindmap); + } +} +class CollapseNode extends Command { + constructor(node) { + super('collapseNOde'); + this.node = node; + this.node.mindmap.clearSelectNode(); + this.node.refreshBox(); + } + execute() { + this.node.clearCacheData(); + this.node.collapse(); + this.refresh(this.node.mindmap); + this.node.select(); + } + undo() { + this.node.clearCacheData(); + this.node.expand(); + this.refresh(this.node.mindmap); + this.node.select(); + } +} +class ExpandNode extends Command { + constructor(node) { + super('collapseNOde'); + this.node = node; + this.node.mindmap.clearSelectNode(); + this.node.refreshBox(); + } + execute() { + this.node.clearCacheData(); + this.node.expand(); + this.refresh(this.node.mindmap); + this.node.select(); + } + undo() { + this.node.clearCacheData(); + this.node.collapse(); + this.refresh(this.node.mindmap); + this.node.select(); + } +} +class PasteNode extends Command { + constructor(node, data) { + super('copyNode'); + this.waitCollapse = []; + this.node = node; + this.data = data; + this.mind = this.node.mindmap; + this.waitCollapse = []; + } + execute() { + this.paste(); + } + undo() { + if (this.firstNode) { + this.mind.removeNode(this.firstNode); + this.node.clearCacheData(); + // this.updateItems(this.node); + this.refresh(this.node.mindmap); + } + } + paste() { + this.data.forEach((d, i) => { + var n = new Node(d, this.mind); + n.mindmap = this.mind; + if (!d.isExpand) { + this.waitCollapse.push(n); + } + if (i == 0) { + n.data.pid = this.node.getId(); + this.mind.addNode(n, this.node); + this.firstNode = n; + n.setPosition(0, 0); + n.refreshBox(); + } + else { + var parent = this.mind.getNodeById(d.pid); + if (parent) { + this.mind.addNode(n, parent); + n.setPosition(0, 0); + n.refreshBox(); + } + } + if (i == this.data.length - 1) { + n.clearCacheData(); + this.refresh(this.mind); + } + }); + } +} + +class Exec { + constructor() { + this.history = new History(50); + } + execute(name, data) { + switch (name) { + case 'addChildNode': + case 'addSiblingNode': + if (data) { + var d = { + id: uuid(), + text: data.text || t('Sub title') + }; + var parent = data.parent; + var node = new Node(d, parent.mindmap); + this.history.execute(new AddNode(node, data.parent, parent.mindmap)); + } + break; + case 'deleteNodeAndChild': + if (data) { + var node = data.node; + this.history.execute(new RemoveNode(node, node.mindmap)); + } + break; + case 'deleteNodeExcludeChild': + break; + case 'changeNodeText': + if (data) { + this.history.execute(new ChangeNodeText(data.node, data.oldText, data.text)); + } + break; + case 'moveNode': + if (data) { + this.history.execute(new MoveNode(data)); + } + break; + case 'movePosition': + if (data) { + this.history.execute(new MovePos(data.node, data.oldPos, data.newPos)); + } + break; + case 'expandNode': + if (data) { + this.history.execute(new ExpandNode(data.node)); + } + break; + case 'collapseNode': + if (data) { + this.history.execute(new CollapseNode(data.node)); + } + break; + case 'pasteNode': + this.history.execute(new PasteNode(data.node, data.data)); + break; + } + } + undo() { + this.history.undo(); + } + redo() { + this.history.redo(); + } +} + +var mind = {}; +var color = ['#fda16c', '#74bdf7', '#71FF5E', 'orange', '#D4D4AA', 'yellow']; +var canvasWidth = 8000; +var canvasHeight = 8000; +const importXmind = function (data) { + mind = { + "theme": 'blue', + "mindData": [], + "induceData": [], + "wireFrameData": [], + "relateLink": [], + "background": '', + "relateLinkData": [], + "calloutData": [], + 'marks': [], + }; + var mainlist = []; + transferData(data.rootTopic, null, mainlist, true); + var root = mainlist[0]; + data.rootTopic.children && data.rootTopic.children.detached && data.rootTopic.children.detached.forEach(d => { + var list = []; + transferData(d, root.id, list); + mainlist = mainlist.concat(list); + }); + mind.mindData.push(mainlist); + mind.basicData = transferListToData(mainlist); + data.relationships && data.relationships.forEach(rl => { + var obj = { + startNodeId: rl.end1Id, + endNodeId: rl.end2Id, + nodeData: { + 'text': '', + 'nodeType': 'relateLink', + 'backgroundColor': '#f06' + } + }; + if (rl.title) { + obj.nodeData.text = rl.title; + } + mind.relateLinkData.push(obj); + }); + return mind; +}; +var task = { + 'task-start': '0', + 'task-oct': '10', + 'task-3oct': '30', + 'task-5oct': '50', + 'task-7oct': '70', + 'task-9oct': '90', + 'task-done': '100', +}; +function transferListToData(list) { + var obj = {}; + var root = null; + function transfer(data, i) { + var nodeData = { + id: data.id, + text: data.text, + children: [], + expanded: true + }; + if (i == 0) { + nodeData.main = true; + nodeData.isRoot = true; + root = nodeData; + } + return nodeData; + } + list.forEach((n, i) => { + var data = transfer(n, i); + if (!obj[n.id]) { + obj[n.id] = data; + } + if (obj[n.pid]) { + obj[n.pid].children.push(data); + } + }); + return root; +} +function transferData(data, parentId, list, mainFlag) { + var text = ''; + if (data.title) { + text = data.title; + } + var node = { + id: data.id, + pid: parentId, + text: text, + // percent:data.data.progress<=8?data.data.progress*10:'', + // priority:data.data.priority, + //link:data.href, + note: '', + //tag:data.data.resource + marks: [], + // resource:data.data.resource, + expanded: true, + image: '', + imageName: '', + x: 0, + y: 0 + }; + if (!parentId) { + node.layout = {}; + node.layout.layoutName = "mindmap"; + node.layout.direct = "right"; + if (mainFlag) { + node.isRoot = true; + node.main = true; + node.x = canvasWidth / 2; + node.y = canvasHeight / 2; + } + } + if (data.href) { + node.link = data.href; + } + if (data.notes) { + node.note = data.notes.plain.content.trim(); + } + // if(data.image){ + // node.isImageNode=true; + // node.image=''; + // node.imageName=data.image.src.replace('xap:resources/',''); + // } + if (data.labels) { + node.marks = []; + data.labels.forEach((lab) => { + node.marks.push({ + id: uuid(), + text: lab, + fill: color[parseInt(Math.random() * color.length + '')] + }); + }); + } + if (data.markers) { + data.markers.forEach((item) => { + if (item.markerId.indexOf('priority') > -1) { + node.priority = item.markerId.split('-')[1]; + } + if (item.markerId.indexOf('task') > -1) { + node.percent = task[item.markerId]; + } + }); + } + list.push(node); + data.children && data.children.attached && data.children.attached.forEach(c => { + transferData(c, data.id, list); + }); + //induce + data.summaries && data.summaries.forEach((sum) => { + var r = sum.range.substring(1, sum.range.length - 1); + // console.log(r,'induce'); + var s = r.split(',')[0]; + var e = r.split(',')[1]; + var induceData = { + induceData: { + nodeId: sum.topicId, + range: r, + id: sum.id, + } + }; + data.children.attached.forEach((c, i) => { + if (i == s) { + induceData.induceData.nodeId = c.id; + } + if (i == e) { + induceData.induceData.endNodeId = c.id; + } + }); + var mData = []; + var summary = data.children.summary; + var sumData = summary.filter((item) => { + return item.id == sum.topicId; + })[0]; + transferData(sumData, null, mData); + mData[0].nodeType = 'induce'; + induceData.mindData = mData; + mind.induceData.push(induceData); + }); + //wireframe + data.boundaries && data.boundaries.forEach(bum => { + var r = bum.range.substring(1, bum.range.length - 1); + var s = r.split(',')[0]; + var e = r.split(',')[1]; + var wf = { + stroke: "rgb(206, 214, 218)", + fill: "transparent", + lineDash: [6, 2], + radius: 10, + data: { + text: '', + nodeType: 'wireFrame' + } + }; + if (bum.title) { + wf.data = { + text: bum.title, + nodeType: 'wireFrame' + }; + } + data.children.attached.forEach((c, i) => { + if (i == s) { + wf.nodeId = c.id; + } + if (i == e) { + wf.endNodeId = c.id; + } + }); + wf.range = r; + mind.wireFrameData.push(wf); + }); + //collout + data.children && data.children.callout && data.children.callout.forEach(c => { + var callout = { + nodeId: data.id, + color: '#f06', + rootData: { + text: c.title, + id: c.id + } + }; + mind.calloutData.push(callout); + }); +} + +/*! + +JSZip v3.10.1 - A JavaScript class for generating and reading zip files + + +(c) 2009-2016 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/main/LICENSE +*/ + +var jszip_min = createCommonjsModule(function (module, exports) { +!function(e){module.exports=e();}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof commonjsRequire&&commonjsRequire;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h);}return o[r].exports}for(var l="function"==typeof commonjsRequire&&commonjsRequire,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l};},{"./support":30,"./utils":32}],2:[function(e,t,r){var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i;}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o;},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate");},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return -1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return -1^e}(0|t,e,e.length,0):0};},{"./utils":32}],5:[function(e,t,r){r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null;},{}],6:[function(e,t,r){var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n};},{lie:37}],7:[function(e,t,r){var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={};}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1);},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0);},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null;},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta});};},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})};},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){function A(e,t){var r,n="";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[];}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}));},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}});}else this.accumulate=!0;},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null;},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i;},{"../utils":32}],19:[function(e,t,r){var n=e("./Uint8ArrayReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){var n=e("./DataReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){var n=e("./ArrayReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)};},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b";},{}],24:[function(e,t,r){var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e;}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta});},t.exports=s;},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0);}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e);},t.exports=s;},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0);}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length;}i.prototype.processChunk.call(this,e);},t.exports=s;},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat();},function(e){t.error(e);});}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null;},s.prototype.resume=function(){return !!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0));},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return !1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t);}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s;},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null;}n.prototype={push:function(e){this.emit("data",e);},end:function(){if(this.isFinished)return !1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0;}catch(e){this.emit("error",e);}return !0},error:function(e){return !this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[];},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n;},{}],29:[function(e,t,r){var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter");}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t);}).on("error",function(e){n=[],r(e);}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n);}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length);}else t=this.leftOver.concat(t);this.leftOver=null;}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta});},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null);},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta});},s.Utf8EncodeWorker=l;},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0);},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4));}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i);}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t};},{"./common":41}],43:[function(e,t,r){t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e;}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return -1^e};},{}],46:[function(e,t,r){var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return (e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0));}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm);}function U(e,t){e.pending_buf[e.pending++]=t;}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t;}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f;}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else {var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1;}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73);}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91);}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103);}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead);}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else {if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0;}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30;}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3;}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else {if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2;}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3;}else {for(z=_+7;l>>=_)),u>>>=7,l-=7;}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k;}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v;}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra;}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v;}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra;}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window;}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]];}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255;}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o));}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8);}(e);};},{"../utils/common":41}],53:[function(e,t,r){t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0;};},{}],54:[function(e,t,r){(function(e){!function(r,n){if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e);});}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1;},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*");}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data);},function(e){t.port2.postMessage(e);}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null;},s.appendChild(t);}):function(e){setTimeout(c,0,e);},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r { + initNode(dd, false, n); + }); + } + } + initNode(data, true); + if (waitCollapseNodes.length) { + waitCollapseNodes.forEach(n => { + n.collapse(); + }); + } + } + traverseBF(callback, node) { + var array = []; + array.push(node || this.root); + var currentNode = array.shift(); + while (currentNode) { + for (let i = 0, len = currentNode.children.length; i < len; i++) { + array.push(currentNode.children[i]); + } + callback(currentNode); + currentNode = array.shift(); + } + } + traverseDF(callback, node, cbFirst) { + function recurse(currentNode) { + if (currentNode) { + if (cbFirst) { + callback(currentNode); + } + if (currentNode.children) { + for (var i = 0, length = currentNode.children.length; i < length; i++) { + recurse(currentNode.children[i]); + } + } + if (!cbFirst) { + callback(currentNode); + } + } + } + recurse(node || this.root); + } + getNodeById(id) { + var snode = null; + this.traverseDF((n) => { + if (n.getId() == id) { + snode = n; + } + }); + return snode; + } + clearSelectNode() { + if (this.selectNode) { + this.selectNode.unSelect(); + this.selectNode = null; + } + if (this.editNode) { + if (this.editNode.isEdit) { + this.editNode.cancelEdit(); + } + this.editNode = null; + } + } + initEvent() { + this.appEl.addEventListener('click', this.appClickFn); + this.appEl.addEventListener('mouseover', this.appMouseOverFn); + this.appEl.addEventListener('dblclick', this.appDblclickFn); + this.appEl.addEventListener('dragstart', this.appDragstart); + this.appEl.addEventListener('dragover', this.appDragover); + this.appEl.addEventListener('dragend', this.appDragend); + this.appEl.addEventListener('drop', this.appDrop); + document.addEventListener('keyup', this.appKeyup); + document.addEventListener('keydown', this.appKeydown); + document.addEventListener('compositionstart', this.compositionStart); + document.addEventListener('compositionend', this.compositionEnd); + document.body.addEventListener('mousewheel', this.appMousewheel); + if (obsidian.Platform.isDesktop) { + this.appEl.addEventListener('mousedown', this.appMouseDown); + this.appEl.addEventListener('mouseup', this.appMouseUp); + } + this.appEl.addEventListener('mousemove', this.appMouseMove); + //custom event + this.on('initNode', this.initNode); + this.on('renderEditNode', this.renderEditNode); + this.on('mindMapChange', this.mindMapChange); + } + removeEvent() { + this.appEl.removeEventListener('click', this.appClickFn); + this.appEl.removeEventListener('dragstart', this.appDragstart); + this.appEl.removeEventListener('dragover', this.appDragover); + this.appEl.removeEventListener('dragend', this.appDragend); + this.appEl.removeEventListener('dblClick', this.appDblclickFn); + this.appEl.removeEventListener('mouseover', this.appMouseOverFn); + this.appEl.removeEventListener('drop', this.appDrop); + document.removeEventListener('keyup', this.appKeyup); + document.removeEventListener('keydown', this.appKeydown); + document.removeEventListener('compositionstart', this.compositionStart); + document.removeEventListener('compositionend', this.compositionEnd); + document.body.removeEventListener('mousewheel', this.appMousewheel); + if (obsidian.Platform.isDesktop) { + this.appEl.removeEventListener('mousedown', this.appMouseDown); + this.appEl.removeEventListener('mouseup', this.appMouseUp); + } + this.appEl.removeEventListener('mousemove', this.appMouseMove); + this.off('initNode', this.initNode); + this.off('renderEditNode', this.renderEditNode); + this.off('mindMapChange', this.mindMapChange); + } + initNode(evt) { + this._tempNum++; + //console.log(this._nodeNum,this._tempNum); + if (this._tempNum == this._nodeNum) { + this.refresh(); + this.center(); + } + } + renderEditNode(evt) { + var node = evt.detail.node || null; + node === null || node === void 0 ? void 0 : node.clearCacheData(); + this.refresh(); + } + mindMapChange() { + var _a; + //console.log(this.view) + (_a = this.view) === null || _a === void 0 ? void 0 : _a.mindMapChange(); + } + appKeydown(e) { + var keyCode = e.keyCode || e.which || e.charCode; + var ctrlKey = e.ctrlKey || e.metaKey; + var shiftKey = e.shiftKey; + if (!ctrlKey && !shiftKey) { + //enter + if (keyCode == 13 || e.key == 'Enter') { + var node = this.selectNode; + if (node && !node.isEdit) { + e.preventDefault(); + e.stopPropagation(); + // node.edit(); + // this._menuDom.style.display = 'none'; + if (!node.isExpand) { + node.expand(); + } + if (!node.parent) + return; + node.mindmap.execute('addSiblingNode', { + parent: node.parent + }); + this._menuDom.style.display = 'none'; + } + else if (node && node.isEdit) { + if (this.isComposing || e.isComposing || e.key === 'Process' || e.keyCode === 229) { + return; + } + else { + node.cancelEdit(); + node.select(); + node.mindmap.editNode = null; + } + } + } + // tab + if (keyCode == 9 || keyCode == 45) { + e.preventDefault(); + e.stopPropagation(); + } + if (keyCode == 32) { + var node = this.selectNode; + if (node && !node.isEdit) { + e.preventDefault(); + e.stopPropagation(); + node.edit(); + this._menuDom.style.display = 'none'; + } + } + } + // if (!ctrlKey && shiftKey) { + // //enter > add node + // if (keyCode == 13 || e.key =='Enter') { + // var node = this.selectNode; + // if (node && !node.isEdit) { + // e.preventDefault(); + // e.stopPropagation(); + // if (!node.isExpand) { + // node.expand(); + // } + // if (!node.parent) return; + // node.mindmap.execute('addSiblingNode', { + // parent: node.parent + // }); + // this._menuDom.style.display='none'; + // } + // } + // } + if (ctrlKey && !shiftKey) { + //ctrl + y + if (keyCode == 89) { + e.preventDefault(); + e.stopPropagation(); + this.redo(); + } + //ctrl + z + if (keyCode == 90) { + e.preventDefault(); + e.stopPropagation(); + this.undo(); + } + } + } + compositionStart(e) { + this.isComposing = true; + } + compositionEnd(e) { + this.isComposing = false; + } + appKeyup(e) { + var keyCode = e.keyCode || e.which || e.charCode; + var ctrlKey = e.ctrlKey || e.metaKey; + var shiftKey = e.shiftKey; + if (!ctrlKey && !shiftKey) { + // //enter + // if (keyCode == 13 || e.key =='Enter') { + // var node = this.selectNode; + // if (node && !node.isEdit) { + // e.preventDefault(); + // e.stopPropagation(); + // if (!node.isExpand) { + // node.expand(); + // } + // if (!node.parent) return; + // node.mindmap.execute('addSiblingNode', { + // parent: node.parent + // }); + // this._menuDom.style.display='none'; + // } else if (node && node.isEdit) { + // if (this.isComposing || e.isComposing || e.key === 'Process' || e.keyCode === 229) { + // return + // } else { + // node.cancelEdit(); + // node.select(); + // node.mindmap.editNode=null; + // } + // } + // } + //delete + if (keyCode == 46 || e.key == 'Delete' || e.key == 'Backspace') { + var node = this.selectNode; + if (node && !node.isEdit) { + e.preventDefault(); + e.stopPropagation(); + node.mindmap.execute("deleteNodeAndChild", { node }); + this._menuDom.style.display = 'none'; + } + } + //tab + if (keyCode == 9 || keyCode == 45 || e.key == 'Tab') { + e.preventDefault(); + e.stopPropagation(); + var node = this.selectNode; + if (node && !node.isEdit) { + if (!node.isExpand) { + node.expand(); + } + node.mindmap.execute("addChildNode", { parent: node }); + this._menuDom.style.display = 'none'; + } + else if (node && node.isEdit) { + node.cancelEdit(); + node.select(); + node.mindmap.editNode = null; + } + } + // up + if (keyCode == 38 || e.key == 'ArrowUp') { + var node = this.selectNode; + if (node && !node.isEdit) { + this._selectNode(node, "up"); + } + } + if (keyCode == 40 || e.key == 'ArrowDown') { + var node = this.selectNode; + if (node && !node.isEdit) { + this._selectNode(node, "down"); + } + } + if (keyCode == 39 || e.key == 'ArrowRight') { + var node = this.selectNode; + if (node && !node.isEdit) { + this._selectNode(node, "right"); + } + } + if (keyCode == 37 || e.key == 'ArrowLeft') { + var node = this.selectNode; + if (node && !node.isEdit) { + this._selectNode(node, "left"); + } + } + } + if (ctrlKey && !shiftKey) { + //ctr + / toggle expand node + if (keyCode == 191) { + var node = this.selectNode; + if (node && !node.isEdit) { + if (node.isExpand) { + node.mindmap.execute('collapseNode', { + node + }); + } + else { + node.mindmap.execute('expandNode', { + node + }); + } + } + } + // ctrl + E center + if (keyCode == 69) { + this.center(); + } + } + } + _selectNode(node, direct) { + if (!node) { + return; + } + var minDis; + var waitNode = null; + var pos = node.getPosition(); + var mind = this; + mind.traverseDF((n) => { + var p = n.getPosition(); + var dx = Math.abs(p.x - pos.x); + var dy = Math.abs(p.y - pos.y); + var dis = Math.sqrt(dx * dx + dy * dy); + switch (direct) { + case "right": + if (p.x > pos.x) { + if (minDis) { + if (minDis > dis) { + minDis = dis; + waitNode = n; + } + } + else { + minDis = dis; + waitNode = n; + } + } + break; + case "left": + if (p.x < pos.x) { + if (minDis) { + if (minDis > dis) { + minDis = dis; + waitNode = n; + } + } + else { + minDis = dis; + waitNode = n; + } + } + break; + case "up": + if (p.y < pos.y) { + if (minDis) { + if (minDis > dis) { + minDis = dis; + waitNode = n; + } + } + else { + minDis = dis; + waitNode = n; + } + } + break; + case "down": + if (p.y > pos.y) { + if (minDis) { + if (minDis > dis) { + minDis = dis; + waitNode = n; + } + } + else { + minDis = dis; + waitNode = n; + } + } + break; + } + }); + if (waitNode) { + mind.clearSelectNode(); + waitNode.select(); + } + } + appClickFn(evt) { + var _a; + var targetEl = evt.target; + if (targetEl) { + if (targetEl.tagName == 'A' && targetEl.hasClass("internal-link")) { + evt.preventDefault(); + var targetEl = evt.target; + var href = targetEl.getAttr("href"); + if (href) { + this.view.app.workspace.openLinkText(href, this.view.file.path, evt.ctrlKey || evt.metaKey); + } + } + if (targetEl.hasClass('mm-node-bar')) { + evt.preventDefault(); + evt.stopPropagation(); + var id = targetEl.closest('.mm-node').getAttribute('data-id'); + var node = this.getNodeById(id); + if (node.isExpand) { + node.mindmap.execute('collapseNode', { + node + }); + } + else { + node.mindmap.execute('expandNode', { + node + }); + } + return; + } + if (targetEl.closest('.mm-node-menu')) { + if (targetEl.closest('.mm-icon-add-node')) { + var selectNode = this.selectNode; + if (selectNode) { + selectNode.mindmap.execute("addChildNode", { parent: selectNode }); + this._menuDom.style.display = 'none'; + } + } + if (targetEl.closest('.mm-icon-delete-node')) { + var selectNode = this.selectNode; + if (selectNode) { + selectNode.mindmap.execute("deleteNodeAndChild", { node: selectNode }); + this._menuDom.style.display = 'none'; + } + } + return; + } + if (targetEl.closest('.mm-node')) { + var id = targetEl.closest('.mm-node').getAttribute('data-id'); + var node = this.getNodeById(id); + if (!node.isSelect) { + this.clearSelectNode(); + this.selectNode = node; + (_a = this.selectNode) === null || _a === void 0 ? void 0 : _a.select(); + this._menuDom.style.display = 'block'; + var box = this.selectNode.getBox(); + this._menuDom.style.left = `${box.x + box.width + 10}px`; + this._menuDom.style.top = `${box.y + box.height / 2 - 14}px`; + } + } + else { + this.clearSelectNode(); + this._menuDom.style.display = 'none'; + } + } + } + appDragstart(evt) { + evt.stopPropagation(); + this.startX = evt.pageX; + this.startY = evt.pageY; + if (evt.target instanceof HTMLElement) { + if (evt.target.closest('.mm-node')) { + var id = evt.target.closest('.mm-node').getAttribute('data-id'); + this._dragNode = this.getNodeById(id); + this.drag = true; + } + } + } + appDragend(evt) { + this.drag = false; + this._indicateDom.style.display = 'none'; + this._menuDom.style.display = 'none'; + } + appDragover(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var target = evt.target; + var x = evt.pageX; + var y = evt.pageY; + if (this.drag) { + this.dx = x - this.startX; + this.dx = y - this.startY; + } + if (target.closest('.mm-node')) { + var nodeId = target.closest('.mm-node').getAttribute('data-id'); + var node = this.getNodeById(nodeId); + var box = node.getBox(); + this._dragType = this._getDragType(node, x, y); + this._indicateDom.style.display = 'block'; + this._indicateDom.style.left = box.x + box.width / 2 - 40 / 2 + 'px'; + this._indicateDom.style.top = box.y - 90 + 'px'; + this._indicateDom.className = 'mm-node-layout-indicate'; + if (this._dragType == 'top') { + this._indicateDom.classList.add('mm-arrow-top'); + } + else if (this._dragType == 'down') { + this._indicateDom.classList.add('mm-arrow-down'); + } + else if (this._dragType == 'left') { + this._indicateDom.classList.add('mm-arrow-left'); + } + else if (this._dragType == 'right') { + this._indicateDom.classList.add('mm-arrow-right'); + } + else { + this._indicateDom.classList.add('drag-type'); + var arr = this._dragType.split('-'); + if (arr[1]) { + this._indicateDom.classList.add('mm-arrow-' + arr[1]); + } + else { + this._indicateDom.classList.add('mm-arrow-right'); + } + } + } + else { + this._indicateDom.style.display = 'none'; + } + } + _getDragType(node, x, y) { + if (!node) + return; + var box = node.contentEl.getBoundingClientRect(); + box.x = box.x; + box.y = box.y; + var direct = node.direct; + switch (direct) { + case 'right': + if (y < box.y + box.height / 2 && x < box.x + box.width / 4 * 3) { + return 'top'; + } + if (y > box.y + box.height / 2 && x < box.x + box.width / 4 * 3) { + return 'down'; + } + return 'child-right'; + case 'left': + if (y < box.y + box.height / 2 && x > box.x + box.width / 4) { + return 'top'; + } + if (y > box.y + box.height / 2 && x > box.x + box.width / 4) { + return 'down'; + } + return 'child-left'; + case 'top': + case 'up': + if (x < box.x + box.width / 4) { + return 'left'; + } + if (x > box.x + box.width / 4 * 3) { + return 'right'; + } + return 'child-top'; + case 'down': + case 'bottom': + if (x < box.x + box.width / 4) { + return 'left'; + } + if (x > box.x + box.width / 4 * 3) { + return 'right'; + } + return 'child-down'; + default: + return 'child'; + } + } + appDrop(evt) { + if (evt.target instanceof HTMLElement) { + if (evt.target.closest('.mm-node')) { + evt.preventDefault(); + var dropNodeId = evt.target.closest('.mm-node').getAttribute('data-id'); + var dropNode = this.getNodeById(dropNodeId); + if (this._dragNode.isRoot) ; + else { + this.moveNode(this._dragNode, dropNode, this._dragType); + } + } + } + var files = evt.dataTransfer.files; + if (files.length) { + var f = files[0]; + if (f.name.toLowerCase().endsWith('.xmind')) { + try { + var me = this; + var reader = new FileReader(); + reader.onload = () => { + jszip_min.loadAsync(reader.result).then((e) => { + var files = e.files; + for (var k in files) { + if (k == "content.json") { + files[k].async("text").then((res) => { + var mindData = JSON.parse(res); + var data = importXmind(mindData[0]); + me.clearNode(); + me.data = data.basicData; + me.init(); + setTimeout(() => { + me.center(); + me.mindMapChange(); + }, 100); + }); + } + } + }); + }; + reader.readAsArrayBuffer(f); + } + catch (err) { + new obsidian.Notice('Parse xmind error'); + } + } + } + this._indicateDom.style.display = 'none'; + this._menuDom.style.display = 'none'; + } + appMouseOverFn(evt) { + const targetEl = evt.target; + if (targetEl.tagName !== "A") + return; + if (targetEl.hasClass("internal-link")) { + this.view.app.workspace.trigger("hover-link", { + event: evt, + source: frontMatterKey, + hoverParent: this.view, + targetEl, + linktext: targetEl.getAttr("href"), + sourcePath: this.view.file.path, + }); + } + } + appMouseMove(evt) { + const targetEl = evt.target; + this.scalePointer = []; + this.scalePointer.push(evt.offsetX, evt.offsetY); + if (targetEl.closest('.mm-node')) { + var id = targetEl.closest('.mm-node').getAttribute('data-id'); + var node = this.getNodeById(id); + if (node) { + var box = node.getBox(); + this.scalePointer = []; + this.scalePointer.push(box.x + box.width / 2, box.y + box.height / 2); + } + } + else { + if (this.drag) { + this.containerEL.scrollLeft = this._left - (evt.pageX - this.startX); + this.containerEL.scrollTop = this._top - (evt.pageY - this.startY); + } + } + } + appMouseDown(evt) { + const targetEl = evt.target; + if (!targetEl.closest('.mm-node')) { + this.drag = true; + this.startX = evt.pageX; + this.startY = evt.pageY; + this._left = this.containerEL.scrollLeft; + this._top = this.containerEL.scrollTop; + } + } + appMouseUp(evt) { + this.drag = false; + } + appDblclickFn(evt) { + var _a; + if (evt.target instanceof HTMLElement) { + if (evt.target.hasClass('mm-node-bar')) { + evt.preventDefault(); + evt.stopPropagation(); + return; + } + if (evt.target.closest('.mm-node') instanceof HTMLElement) { + var id = evt.target.closest('.mm-node').getAttribute('data-id'); + this.selectNode = this.getNodeById(id); + if (!this.editNode || (this.editNode && this.editNode != this.selectNode)) { + (_a = this.selectNode) === null || _a === void 0 ? void 0 : _a.edit(); + this.editNode = this.selectNode; + this._menuDom.style.display = 'none'; + } + } + } + } + appMousewheel(evt) { + // if(!evt) evt = window.event; + var ctrlKey = evt.ctrlKey || evt.metaKey; + var delta; + if (evt.wheelDelta) { + //IE、chrome -120 + delta = evt.wheelDelta / 120; + } + else if (evt.detail) { + //FF 3 + delta = -evt.detail / 3; + } + if (delta) { + if (delta < 0) { + if (ctrlKey) { + this.setScale("down"); + } + } + else { + if (ctrlKey) { + this.setScale("up"); + } + } + } + } + clearNode() { + var _a; + //delete node + this.traverseBF((n) => { + this.contentEL.removeChild(n.containEl); + }); + //delete line + if (this.mmLayout) { + (_a = this.mmLayout.svgDom) === null || _a === void 0 ? void 0 : _a.clear(); + } + } + clear() { + var _a; + this.clearNode(); + this.removeEvent(); + (_a = this.draw) === null || _a === void 0 ? void 0 : _a.clear(); + } + //get node list rect point + getBoundingRect(list) { + var box = { + x: 0, + y: 0, + width: 0, + height: 0, + right: 0, + bottom: 0 + }; + list.forEach((item, i) => { + var b = item.getBox(); + // console.log(b.x,b.y); + if (i == 0) { + box.x = b.x; + box.y = b.y; + box.right = b.x + b.width; + box.bottom = b.y + b.height; + } + else { + if (b.x < box.x) { + box.x = b.x; + } + if (b.y < box.y) { + box.y = b.y; + } + if (b.x + b.width > box.right) { + box.right = b.x + b.width; + } + if (b.y + b.height > box.bottom) { + box.bottom = b.y + b.height; + } + } + }); + box.width = box.right - box.x; + box.height = box.bottom - box.y; + return box; + } + moveNode(dragNode, dropNode, type) { + if (dragNode == dropNode || dragNode.isRoot) { + return; + } + var flag = false; + var p = dropNode.parent; + while (p) { + if (p == dragNode) { + flag = true; + break; + } + p = p.parent; + } + if (flag) { //parent can not change to child + return; + } + dropNode.clearCacheData(); + dragNode.clearCacheData(); + if (!dropNode.isExpand) { + dropNode.expand(); + } + if (type == 'top' || type == 'left' || type == 'down' || type == 'right') { + this.execute('moveNode', { type: 'siblings', node: dragNode, oldParent: dragNode.parent, dropNode, direct: type }); + } + else if (type.indexOf('child') > -1) { + var typeArr = type.split('-'); + if (typeArr[1]) { + this.execute('moveNode', { type: 'child', node: dragNode, oldParent: dragNode.parent, parent: dropNode, direct: typeArr[1] }); + } + else { + this.execute('moveNode', { type: 'child', node: dragNode, oldParent: dragNode.parent, parent: dropNode }); + } + } + // this.execute('moveNode', { type: 'child', node: dragNode, oldParent: dragNode.parent, parent: dropNode }) + } + //execute cmd , store history + execute(name, data) { + this.exec.execute(name, data); + } + undo() { + this.exec.undo(); + } + redo() { + this.exec.redo(); + } + addNode(node, parent, index = -1) { + if (parent) { + parent.addChild(node, index); + if (parent.direct) { + node.direct = parent.direct; + } + this._addNodeDom(node); + node.clearCacheData(); + } + } + _addNodeDom(node) { + this.traverseBF((n) => { + if (!this.contentEL.contains(n.containEl)) { + this.contentEL.appendChild(n.containEl); + } + }, node); + } + removeNode(node) { + if (node.parent) { + var p = node.parent; + var i = node.parent.removeChild(node); + this._removeChildDom(node); + p.clearCacheData(); + return i; + } + else { + this._removeChildDom(node); + return -1; + } + } + _removeChildDom(node) { + this.traverseBF((n) => { + if (this.contentEL.contains(n.containEl)) { + this.contentEL.removeChild(n.containEl); + } + }, node); + } + //layout + layout() { + if (!this.mmLayout) { + this.mmLayout = new Layout(this.root, this.setting.layoutDirect || 'mind map', this.colors); + return; + } + this.mmLayout.layout(this.root, this.setting.layoutDirect || this.mmLayout.direct || 'mind map'); + } + refresh() { + this.layout(); + } + emit(name, data) { + var evt = new CustomEvent(name, { + detail: data || {} + }); + this.appEl.dispatchEvent(evt); + } + on(name, fn) { + this.appEl.addEventListener(name, fn); + } + off(name, fn) { + if (name && fn) { + this.appEl.removeEventListener(name, fn); + } + } + center() { + this._setMindScalePointer(); + var oldScale = this.mindScale; + this.scale(100); + var w = this.containerEL.clientWidth; + var h = this.containerEL.clientHeight; + this.containerEL.scrollTop = this.setting.canvasSize / 2 - h / 2 - 60; + this.containerEL.scrollLeft = this.setting.canvasSize / 2 - w / 2 + 30; + this.scale(oldScale); + } + _setMindScalePointer() { + this.scalePointer = []; + var root = this.root; + if (root) { + var rbox = root.getBox(); + this.scalePointer.push(rbox.x + rbox.width / 2, rbox.y + rbox.height / 2); + } + } + getMarkdown() { + var md = ''; + var level = this.setting.headLevel; + this.traverseDF((n) => { + var l = n.getLevel() + 1; + var hPrefix = '', space = ''; + if (l > 1) { + hPrefix = '\n'; + } + const ending = n.isExpand ? '' : ` ^${n.getId()}`; + if (n.getLevel() < level) { + for (let i = 0; i < l; i++) { + hPrefix += '#'; + } + md += (hPrefix + ' '); + md += n.getData().text.trim() + ending + '\n'; + } + else { + for (var i = 0; i < n.getLevel() - level; i++) { + space += '\t'; + } + var text = n.getData().text.trim(); + if (text) { + var textArr = text.split('\n'); + var lineLength = textArr.length; + if (lineLength == 1) { + md += `${space}- ${text}${ending}\n`; + } + else if (lineLength > 1) { + //code + if (text.startsWith('```')) { + md += '\n'; + md += `${space}-\n`; + textArr.forEach((t, i) => { + md += `${space} ${t.trim()}${i === textArr.length - 1 ? ending : ''}\n`; + }); + md += '\n'; + } + else { + //text + md += `${space}- `; + textArr.forEach((t, i) => { + var contentText = "void"; + if (t.trim().length > 0) { + contentText = t.trim(); + } + if (i > 0) { + md += `${space}${contentText}${i === textArr.length - 1 ? ending : ''}\n`; + } + else { + md += `${contentText}\n`; + } + }); + } + } + } + else { + for (var i = 0; i < n.getLevel() - level; i++) { + space += '\t'; + } + md += `${space}-\n`; + } + } + }, this.root, true); + return md.trim(); + } + scale(num) { + if (num < 20) { + num = 20; + } + if (num > 300) { + num = 300; + } + this.mindScale = num; + if (this.scalePointer.length) { + this.appEl.style.transformOrigin = `${this.scalePointer[0]}px ${this.scalePointer[1]}px`; + this.appEl.style.transform = "scale(" + this.mindScale / 100 + ")"; + } + else { + this.appEl.style.transform = "scale(" + this.mindScale / 100 + ")"; + } + } + setScale(type) { + if (type == "up") { + var n = this.mindScale + 10; + } + else { + var n = this.mindScale - 10; + } + this.scale(n); + if (this.timeOut) { + clearTimeout(this.timeOut); + } + this.timeOut = setTimeout(() => { + new obsidian.Notice(`${n} %`); + }, 600); + } + copyNode(node) { + var n = node || this.selectNode; + if (n) { + var data = []; + function copyNode(n, pid) { + var d = n.getData(); + d.id = uuid(); + d.pid = pid; + data.push({ + id: d.id, + text: d.text, + pid: pid, + isExpand: d.isExpand, + note: d.note + }); + n.children.forEach((c) => { + copyNode(c, d.id); + }); + } + copyNode(n, null); + var _data = { + type: 'copyNode', + text: data + }; + return JSON.stringify(_data); + } + else { + return ''; + } + } + pasteNode(text) { + var node = this.selectNode; + if (text) { + try { + var json = JSON.parse(text); + if (json.type && json.type == 'copyNode') { + var data = json.text; + if (!node.isExpand) { + node.expand(); + node.clearCacheData(); + } + this.execute('pasteNode', { + node: node, + data: data + }); + navigator.clipboard.writeText(''); + } + } + catch (err) { + console.log(err); + } + } + } +} + +var katex = createCommonjsModule(function (module, exports) { +(function webpackUniversalModuleDefinition(root, factory) { + module.exports = factory(); +})((typeof self !== 'undefined' ? self : commonjsGlobal), function() { +return /******/ (function() { // webpackBootstrap +/******/ // The require scope +/******/ var __webpack_require__ = {}; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ !function() { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = function(exports, definition) { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ !function() { +/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; +/******/ }(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "default": function() { return /* binding */ katex_webpack; } +}); + + +/** + * This is the ParseError class, which is the main error thrown by KaTeX + * functions when something has gone wrong. This is used to distinguish internal + * errors from errors in the expression that the user provided. + * + * If possible, a caller should provide a Token or ParseNode with information + * about where in the source string the problem occurred. + */ +var ParseError = // Error position based on passed-in Token or ParseNode. +function ParseError(message, // The error message +token // An object providing position information +) { + this.position = void 0; + var error = "KaTeX parse error: " + message; + var start; + var loc = token && token.loc; + + if (loc && loc.start <= loc.end) { + // If we have the input and a position, make the error a bit fancier + // Get the input + var input = loc.lexer.input; // Prepend some information + + start = loc.start; + var end = loc.end; + + if (start === input.length) { + error += " at end of input: "; + } else { + error += " at position " + (start + 1) + ": "; + } // Underline token in question using combining underscores + + + var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332"); // Extract some context from the input and add it to the error + + var left; + + if (start > 15) { + left = "…" + input.slice(start - 15, start); + } else { + left = input.slice(0, start); + } + + var right; + + if (end + 15 < input.length) { + right = input.slice(end, end + 15) + "…"; + } else { + right = input.slice(end); + } + + error += left + underlined + right; + } // Some hackery to make ParseError a prototype of Error + // See http://stackoverflow.com/a/8460753 + + + var self = new Error(error); + self.name = "ParseError"; // $FlowFixMe + + self.__proto__ = ParseError.prototype; // $FlowFixMe + + self.position = start; + return self; +}; // $FlowFixMe More hackery + + +ParseError.prototype.__proto__ = Error.prototype; +/* harmony default export */ var src_ParseError = (ParseError); +/** + * This file contains a list of utility functions which are useful in other + * files. + */ + +/** + * Return whether an element is contained in a list + */ +var contains = function contains(list, elem) { + return list.indexOf(elem) !== -1; +}; +/** + * Provide a default value if a setting is undefined + * NOTE: Couldn't use `T` as the output type due to facebook/flow#5022. + */ + + +var deflt = function deflt(setting, defaultIfUndefined) { + return setting === undefined ? defaultIfUndefined : setting; +}; // hyphenate and escape adapted from Facebook's React under Apache 2 license + + +var uppercase = /([A-Z])/g; + +var hyphenate = function hyphenate(str) { + return str.replace(uppercase, "-$1").toLowerCase(); +}; + +var ESCAPE_LOOKUP = { + "&": "&", + ">": ">", + "<": "<", + "\"": """, + "'": "'" +}; +var ESCAPE_REGEX = /[&><"']/g; +/** + * Escapes text to prevent scripting attacks. + */ + +function utils_escape(text) { + return String(text).replace(ESCAPE_REGEX, function (match) { + return ESCAPE_LOOKUP[match]; + }); +} +/** + * Sometimes we want to pull out the innermost element of a group. In most + * cases, this will just be the group itself, but when ordgroups and colors have + * a single element, we want to pull that out. + */ + + +var getBaseElem = function getBaseElem(group) { + if (group.type === "ordgroup") { + if (group.body.length === 1) { + return getBaseElem(group.body[0]); + } else { + return group; + } + } else if (group.type === "color") { + if (group.body.length === 1) { + return getBaseElem(group.body[0]); + } else { + return group; + } + } else if (group.type === "font") { + return getBaseElem(group.body); + } else { + return group; + } +}; +/** + * TeXbook algorithms often reference "character boxes", which are simply groups + * with a single character in them. To decide if something is a character box, + * we find its innermost group, and see if it is a single character. + */ + + +var isCharacterBox = function isCharacterBox(group) { + var baseElem = getBaseElem(group); // These are all they types of groups which hold single characters + + return baseElem.type === "mathord" || baseElem.type === "textord" || baseElem.type === "atom"; +}; + +var assert = function assert(value) { + if (!value) { + throw new Error('Expected non-null, but got ' + String(value)); + } + + return value; +}; +/** + * Return the protocol of a URL, or "_relative" if the URL does not specify a + * protocol (and thus is relative). + */ + +var protocolFromUrl = function protocolFromUrl(url) { + var protocol = /^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(url); + return protocol != null ? protocol[1] : "_relative"; +}; +/* harmony default export */ var utils = ({ + contains: contains, + deflt: deflt, + escape: utils_escape, + hyphenate: hyphenate, + getBaseElem: getBaseElem, + isCharacterBox: isCharacterBox, + protocolFromUrl: protocolFromUrl +}); +/* eslint no-console:0 */ + +/** + * This is a module for storing settings passed into KaTeX. It correctly handles + * default settings. + */ + + + + +/** + * The main Settings object + * + * The current options stored are: + * - displayMode: Whether the expression should be typeset as inline math + * (false, the default), meaning that the math starts in + * \textstyle and is placed in an inline-block); or as display + * math (true), meaning that the math starts in \displaystyle + * and is placed in a block with vertical margin. + */ +var Settings = /*#__PURE__*/function () { + function Settings(options) { + this.displayMode = void 0; + this.output = void 0; + this.leqno = void 0; + this.fleqn = void 0; + this.throwOnError = void 0; + this.errorColor = void 0; + this.macros = void 0; + this.minRuleThickness = void 0; + this.colorIsTextColor = void 0; + this.strict = void 0; + this.trust = void 0; + this.maxSize = void 0; + this.maxExpand = void 0; + this.globalGroup = void 0; + // allow null options + options = options || {}; + this.displayMode = utils.deflt(options.displayMode, false); + this.output = utils.deflt(options.output, "htmlAndMathml"); + this.leqno = utils.deflt(options.leqno, false); + this.fleqn = utils.deflt(options.fleqn, false); + this.throwOnError = utils.deflt(options.throwOnError, true); + this.errorColor = utils.deflt(options.errorColor, "#cc0000"); + this.macros = options.macros || {}; + this.minRuleThickness = Math.max(0, utils.deflt(options.minRuleThickness, 0)); + this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false); + this.strict = utils.deflt(options.strict, "warn"); + this.trust = utils.deflt(options.trust, false); + this.maxSize = Math.max(0, utils.deflt(options.maxSize, Infinity)); + this.maxExpand = Math.max(0, utils.deflt(options.maxExpand, 1000)); + this.globalGroup = utils.deflt(options.globalGroup, false); + } + /** + * Report nonstrict (non-LaTeX-compatible) input. + * Can safely not be called if `this.strict` is false in JavaScript. + */ + + + var _proto = Settings.prototype; + + _proto.reportNonstrict = function reportNonstrict(errorCode, errorMsg, token) { + var strict = this.strict; + + if (typeof strict === "function") { + // Allow return value of strict function to be boolean or string + // (or null/undefined, meaning no further processing). + strict = strict(errorCode, errorMsg, token); + } + + if (!strict || strict === "ignore") { + return; + } else if (strict === true || strict === "error") { + throw new src_ParseError("LaTeX-incompatible input and strict mode is set to 'error': " + (errorMsg + " [" + errorCode + "]"), token); + } else if (strict === "warn") { + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]")); + } else { + // won't happen in type-safe code + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]")); + } + } + /** + * Check whether to apply strict (LaTeX-adhering) behavior for unusual + * input (like `\\`). Unlike `nonstrict`, will not throw an error; + * instead, "error" translates to a return value of `true`, while "ignore" + * translates to a return value of `false`. May still print a warning: + * "warn" prints a warning and returns `false`. + * This is for the second category of `errorCode`s listed in the README. + */ + ; + + _proto.useStrictBehavior = function useStrictBehavior(errorCode, errorMsg, token) { + var strict = this.strict; + + if (typeof strict === "function") { + // Allow return value of strict function to be boolean or string + // (or null/undefined, meaning no further processing). + // But catch any exceptions thrown by function, treating them + // like "error". + try { + strict = strict(errorCode, errorMsg, token); + } catch (error) { + strict = "error"; + } + } + + if (!strict || strict === "ignore") { + return false; + } else if (strict === true || strict === "error") { + return true; + } else if (strict === "warn") { + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]")); + return false; + } else { + // won't happen in type-safe code + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]")); + return false; + } + } + /** + * Check whether to test potentially dangerous input, and return + * `true` (trusted) or `false` (untrusted). The sole argument `context` + * should be an object with `command` field specifying the relevant LaTeX + * command (as a string starting with `\`), and any other arguments, etc. + * If `context` has a `url` field, a `protocol` field will automatically + * get added by this function (changing the specified object). + */ + ; + + _proto.isTrusted = function isTrusted(context) { + if (context.url && !context.protocol) { + context.protocol = utils.protocolFromUrl(context.url); + } + + var trust = typeof this.trust === "function" ? this.trust(context) : this.trust; + return Boolean(trust); + }; + + return Settings; +}(); +/** + * This file contains information and classes for the various kinds of styles + * used in TeX. It provides a generic `Style` class, which holds information + * about a specific style. It then provides instances of all the different kinds + * of styles possible, and provides functions to move between them and get + * information about them. + */ + +/** + * The main style class. Contains a unique id for the style, a size (which is + * the same for cramped and uncramped version of a style), and a cramped flag. + */ +var Style = /*#__PURE__*/function () { + function Style(id, size, cramped) { + this.id = void 0; + this.size = void 0; + this.cramped = void 0; + this.id = id; + this.size = size; + this.cramped = cramped; + } + /** + * Get the style of a superscript given a base in the current style. + */ + + + var _proto = Style.prototype; + + _proto.sup = function sup() { + return styles[_sup[this.id]]; + } + /** + * Get the style of a subscript given a base in the current style. + */ + ; + + _proto.sub = function sub() { + return styles[_sub[this.id]]; + } + /** + * Get the style of a fraction numerator given the fraction in the current + * style. + */ + ; + + _proto.fracNum = function fracNum() { + return styles[_fracNum[this.id]]; + } + /** + * Get the style of a fraction denominator given the fraction in the current + * style. + */ + ; + + _proto.fracDen = function fracDen() { + return styles[_fracDen[this.id]]; + } + /** + * Get the cramped version of a style (in particular, cramping a cramped style + * doesn't change the style). + */ + ; + + _proto.cramp = function cramp() { + return styles[_cramp[this.id]]; + } + /** + * Get a text or display version of this style. + */ + ; + + _proto.text = function text() { + return styles[_text[this.id]]; + } + /** + * Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle) + */ + ; + + _proto.isTight = function isTight() { + return this.size >= 2; + }; + + return Style; +}(); // Export an interface for type checking, but don't expose the implementation. +// This way, no more styles can be generated. + + +// IDs of the different styles +var D = 0; +var Dc = 1; +var T = 2; +var Tc = 3; +var S = 4; +var Sc = 5; +var SS = 6; +var SSc = 7; // Instances of the different styles + +var styles = [new Style(D, 0, false), new Style(Dc, 0, true), new Style(T, 1, false), new Style(Tc, 1, true), new Style(S, 2, false), new Style(Sc, 2, true), new Style(SS, 3, false), new Style(SSc, 3, true)]; // Lookup tables for switching from one style to another + +var _sup = [S, Sc, S, Sc, SS, SSc, SS, SSc]; +var _sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc]; +var _fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc]; +var _fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc]; +var _cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc]; +var _text = [D, Dc, T, Tc, T, Tc, T, Tc]; // We only export some of the styles. + +/* harmony default export */ var src_Style = ({ + DISPLAY: styles[D], + TEXT: styles[T], + SCRIPT: styles[S], + SCRIPTSCRIPT: styles[SS] +}); +/* + * This file defines the Unicode scripts and script families that we + * support. To add new scripts or families, just add a new entry to the + * scriptData array below. Adding scripts to the scriptData array allows + * characters from that script to appear in \text{} environments. + */ + +/** + * Each script or script family has a name and an array of blocks. + * Each block is an array of two numbers which specify the start and + * end points (inclusive) of a block of Unicode codepoints. + */ + +/** + * Unicode block data for the families of scripts we support in \text{}. + * Scripts only need to appear here if they do not have font metrics. + */ +var scriptData = [{ + // Latin characters beyond the Latin-1 characters we have metrics for. + // Needed for Czech, Hungarian and Turkish text, for example. + name: 'latin', + blocks: [[0x0100, 0x024f], // Latin Extended-A and Latin Extended-B + [0x0300, 0x036f] // Combining Diacritical marks + ] +}, { + // The Cyrillic script used by Russian and related languages. + // A Cyrillic subset used to be supported as explicitly defined + // symbols in symbols.js + name: 'cyrillic', + blocks: [[0x0400, 0x04ff]] +}, { + // Armenian + name: 'armenian', + blocks: [[0x0530, 0x058F]] +}, { + // The Brahmic scripts of South and Southeast Asia + // Devanagari (0900–097F) + // Bengali (0980–09FF) + // Gurmukhi (0A00–0A7F) + // Gujarati (0A80–0AFF) + // Oriya (0B00–0B7F) + // Tamil (0B80–0BFF) + // Telugu (0C00–0C7F) + // Kannada (0C80–0CFF) + // Malayalam (0D00–0D7F) + // Sinhala (0D80–0DFF) + // Thai (0E00–0E7F) + // Lao (0E80–0EFF) + // Tibetan (0F00–0FFF) + // Myanmar (1000–109F) + name: 'brahmic', + blocks: [[0x0900, 0x109F]] +}, { + name: 'georgian', + blocks: [[0x10A0, 0x10ff]] +}, { + // Chinese and Japanese. + // The "k" in cjk is for Korean, but we've separated Korean out + name: "cjk", + blocks: [[0x3000, 0x30FF], // CJK symbols and punctuation, Hiragana, Katakana + [0x4E00, 0x9FAF], // CJK ideograms + [0xFF00, 0xFF60] // Fullwidth punctuation + // TODO: add halfwidth Katakana and Romanji glyphs + ] +}, { + // Korean + name: 'hangul', + blocks: [[0xAC00, 0xD7AF]] +}]; +/** + * Given a codepoint, return the name of the script or script family + * it is from, or null if it is not part of a known block + */ + +function scriptFromCodepoint(codepoint) { + for (var i = 0; i < scriptData.length; i++) { + var script = scriptData[i]; + + for (var _i = 0; _i < script.blocks.length; _i++) { + var block = script.blocks[_i]; + + if (codepoint >= block[0] && codepoint <= block[1]) { + return script.name; + } + } + } + + return null; +} +/** + * A flattened version of all the supported blocks in a single array. + * This is an optimization to make supportedCodepoint() fast. + */ + +var allBlocks = []; +scriptData.forEach(function (s) { + return s.blocks.forEach(function (b) { + return allBlocks.push.apply(allBlocks, b); + }); +}); +/** + * Given a codepoint, return true if it falls within one of the + * scripts or script families defined above and false otherwise. + * + * Micro benchmarks shows that this is faster than + * /[\u3000-\u30FF\u4E00-\u9FAF\uFF00-\uFF60\uAC00-\uD7AF\u0900-\u109F]/.test() + * in Firefox, Chrome and Node. + */ + +function supportedCodepoint(codepoint) { + for (var i = 0; i < allBlocks.length; i += 2) { + if (codepoint >= allBlocks[i] && codepoint <= allBlocks[i + 1]) { + return true; + } + } + + return false; +} +/** + * This file provides support to domTree.js and delimiter.js. + * It's a storehouse of path geometry for SVG images. + */ +// In all paths below, the viewBox-to-em scale is 1000:1. +var hLinePad = 80; // padding above a sqrt viniculum. Prevents image cropping. +// The viniculum of a \sqrt can be made thicker by a KaTeX rendering option. +// Think of variable extraViniculum as two detours in the SVG path. +// The detour begins at the lower left of the area labeled extraViniculum below. +// The detour proceeds one extraViniculum distance up and slightly to the right, +// displacing the radiused corner between surd and viniculum. The radius is +// traversed as usual, then the detour resumes. It goes right, to the end of +// the very long viniculumn, then down one extraViniculum distance, +// after which it resumes regular path geometry for the radical. + +/* viniculum + / + /▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒←extraViniculum + / █████████████████████←0.04em (40 unit) std viniculum thickness + / / + / / + / /\ + / / surd +*/ + +var sqrtMain = function sqrtMain(extraViniculum, hLinePad) { + // sqrtMain path geometry is from glyph U221A in the font KaTeX Main + return "M95," + (622 + extraViniculum + hLinePad) + "\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl" + extraViniculum / 2.075 + " -" + extraViniculum + "\nc5.3,-9.3,12,-14,20,-14\nH400000v" + (40 + extraViniculum) + "H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM" + (834 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "h-400000z"; +}; + +var sqrtSize1 = function sqrtSize1(extraViniculum, hLinePad) { + // size1 is from glyph U221A in the font KaTeX_Size1-Regular + return "M263," + (601 + extraViniculum + hLinePad) + "c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl" + extraViniculum / 2.084 + " -" + extraViniculum + "\nc4.7,-7.3,11,-11,19,-11\nH40000v" + (40 + extraViniculum) + "H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM" + (1001 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "h-400000z"; +}; + +var sqrtSize2 = function sqrtSize2(extraViniculum, hLinePad) { + // size2 is from glyph U221A in the font KaTeX_Size2-Regular + return "M983 " + (10 + extraViniculum + hLinePad) + "\nl" + extraViniculum / 3.13 + " -" + extraViniculum + "\nc4,-6.7,10,-10,18,-10 H400000v" + (40 + extraViniculum) + "\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM" + (1001 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "h-400000z"; +}; + +var sqrtSize3 = function sqrtSize3(extraViniculum, hLinePad) { + // size3 is from glyph U221A in the font KaTeX_Size3-Regular + return "M424," + (2398 + extraViniculum + hLinePad) + "\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl" + extraViniculum / 4.223 + " -" + extraViniculum + "c4,-6.7,10,-10,18,-10 H400000\nv" + (40 + extraViniculum) + "H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M" + (1001 + extraViniculum) + " " + hLinePad + "\nh400000v" + (40 + extraViniculum) + "h-400000z"; +}; + +var sqrtSize4 = function sqrtSize4(extraViniculum, hLinePad) { + // size4 is from glyph U221A in the font KaTeX_Size4-Regular + return "M473," + (2713 + extraViniculum + hLinePad) + "\nc339.3,-1799.3,509.3,-2700,510,-2702 l" + extraViniculum / 5.298 + " -" + extraViniculum + "\nc3.3,-7.3,9.3,-11,18,-11 H400000v" + (40 + extraViniculum) + "H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM" + (1001 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "H1017.7z"; +}; + +var phasePath = function phasePath(y) { + var x = y / 2; // x coordinate at top of angle + + return "M400000 " + y + " H0 L" + x + " 0 l65 45 L145 " + (y - 80) + " H400000z"; +}; + +var sqrtTall = function sqrtTall(extraViniculum, hLinePad, viewBoxHeight) { + // sqrtTall is from glyph U23B7 in the font KaTeX_Size4-Regular + // One path edge has a variable length. It runs vertically from the viniculumn + // to a point near (14 units) the bottom of the surd. The viniculum + // is normally 40 units thick. So the length of the line in question is: + var vertSegment = viewBoxHeight - 54 - hLinePad - extraViniculum; + return "M702 " + (extraViniculum + hLinePad) + "H400000" + (40 + extraViniculum) + "\nH742v" + vertSegment + "l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 " + hLinePad + "H400000v" + (40 + extraViniculum) + "H742z"; +}; + +var sqrtPath = function sqrtPath(size, extraViniculum, viewBoxHeight) { + extraViniculum = 1000 * extraViniculum; // Convert from document ems to viewBox. + + var path = ""; + + switch (size) { + case "sqrtMain": + path = sqrtMain(extraViniculum, hLinePad); + break; + + case "sqrtSize1": + path = sqrtSize1(extraViniculum, hLinePad); + break; + + case "sqrtSize2": + path = sqrtSize2(extraViniculum, hLinePad); + break; + + case "sqrtSize3": + path = sqrtSize3(extraViniculum, hLinePad); + break; + + case "sqrtSize4": + path = sqrtSize4(extraViniculum, hLinePad); + break; + + case "sqrtTall": + path = sqrtTall(extraViniculum, hLinePad, viewBoxHeight); + } + + return path; +}; +var innerPath = function innerPath(name, height) { + // The inner part of stretchy tall delimiters + switch (name) { + case "\u239C": + return "M291 0 H417 V" + height + " H291z M291 0 H417 V" + height + " H291z"; + + case "\u2223": + return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z"; + + case "\u2225": + return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z" + ("M367 0 H410 V" + height + " H367z M367 0 H410 V" + height + " H367z"); + + case "\u239F": + return "M457 0 H583 V" + height + " H457z M457 0 H583 V" + height + " H457z"; + + case "\u23A2": + return "M319 0 H403 V" + height + " H319z M319 0 H403 V" + height + " H319z"; + + case "\u23A5": + return "M263 0 H347 V" + height + " H263z M263 0 H347 V" + height + " H263z"; + + case "\u23AA": + return "M384 0 H504 V" + height + " H384z M384 0 H504 V" + height + " H384z"; + + case "\u23D0": + return "M312 0 H355 V" + height + " H312z M312 0 H355 V" + height + " H312z"; + + case "\u2016": + return "M257 0 H300 V" + height + " H257z M257 0 H300 V" + height + " H257z" + ("M478 0 H521 V" + height + " H478z M478 0 H521 V" + height + " H478z"); + + default: + return ""; + } +}; +var path = { + // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main + doubleleftarrow: "M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z", + // doublerightarrow is from glyph U+21D2 in font KaTeX Main + doublerightarrow: "M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z", + // leftarrow is from glyph U+2190 in font KaTeX Main + leftarrow: "M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z", + // overbrace is from glyphs U+23A9/23A8/23A7 in font KaTeX_Size4-Regular + leftbrace: "M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z", + leftbraceunder: "M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z", + // overgroup is from the MnSymbol package (public domain) + leftgroup: "M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z", + leftgroupunder: "M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z", + // Harpoons are from glyph U+21BD in font KaTeX Main + leftharpoon: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z", + leftharpoonplus: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z", + leftharpoondown: "M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z", + leftharpoondownplus: "M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z", + // hook is from glyph U+21A9 in font KaTeX Main + lefthook: "M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z", + leftlinesegment: "M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z", + leftmapsto: "M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z", + // tofrom is from glyph U+21C4 in font KaTeX AMS Regular + leftToFrom: "M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z", + longequal: "M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z", + midbrace: "M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z", + midbraceunder: "M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z", + oiintSize1: "M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z", + oiintSize2: "M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z", + oiiintSize1: "M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z", + oiiintSize2: "M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z", + rightarrow: "M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z", + rightbrace: "M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z", + rightbraceunder: "M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z", + rightgroup: "M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z", + rightgroupunder: "M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z", + rightharpoon: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z", + rightharpoonplus: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z", + rightharpoondown: "M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z", + rightharpoondownplus: "M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z", + righthook: "M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z", + rightlinesegment: "M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z", + rightToFrom: "M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z", + // twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular + twoheadleftarrow: "M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z", + twoheadrightarrow: "M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z", + // tilde1 is a modified version of a glyph from the MnSymbol package + tilde1: "M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z", + // ditto tilde2, tilde3, & tilde4 + tilde2: "M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z", + tilde3: "M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z", + tilde4: "M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z", + // vec is from glyph U+20D7 in font KaTeX Main + vec: "M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z", + // widehat1 is a modified version of a glyph from the MnSymbol package + widehat1: "M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z", + // ditto widehat2, widehat3, & widehat4 + widehat2: "M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", + widehat3: "M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", + widehat4: "M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", + // widecheck paths are all inverted versions of widehat + widecheck1: "M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z", + widecheck2: "M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", + widecheck3: "M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", + widecheck4: "M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", + // The next ten paths support reaction arrows from the mhchem package. + // Arrows for \ce{<-->} are offset from xAxis by 0.22ex, per mhchem in LaTeX + // baraboveleftarrow is mostly from from glyph U+2190 in font KaTeX Main + baraboveleftarrow: "M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z", + // rightarrowabovebar is mostly from glyph U+2192, KaTeX Main + rightarrowabovebar: "M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z", + // The short left harpoon has 0.5em (i.e. 500 units) kern on the left end. + // Ref from mhchem.sty: \rlap{\raisebox{-.22ex}{$\kern0.5em + baraboveshortleftharpoon: "M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z", + rightharpoonaboveshortbar: "M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z", + shortbaraboveleftharpoon: "M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z", + shortrightharpoonabovebar: "M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z" +}; + + +/** + * This node represents a document fragment, which contains elements, but when + * placed into the DOM doesn't have any representation itself. It only contains + * children and doesn't have any DOM node properties. + */ +var DocumentFragment = /*#__PURE__*/function () { + // HtmlDomNode + // Never used; needed for satisfying interface. + function DocumentFragment(children) { + this.children = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.maxFontSize = void 0; + this.style = void 0; + this.children = children; + this.classes = []; + this.height = 0; + this.depth = 0; + this.maxFontSize = 0; + this.style = {}; + } + + var _proto = DocumentFragment.prototype; + + _proto.hasClass = function hasClass(className) { + return utils.contains(this.classes, className); + } + /** Convert the fragment into a node. */ + ; + + _proto.toNode = function toNode() { + var frag = document.createDocumentFragment(); + + for (var i = 0; i < this.children.length; i++) { + frag.appendChild(this.children[i].toNode()); + } + + return frag; + } + /** Convert the fragment into HTML markup. */ + ; + + _proto.toMarkup = function toMarkup() { + var markup = ""; // Simply concatenate the markup for the children together. + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + return markup; + } + /** + * Converts the math node into a string, similar to innerText. Applies to + * MathDomNode's only. + */ + ; + + _proto.toText = function toText() { + // To avoid this, we would subclass documentFragment separately for + // MathML, but polyfills for subclassing is expensive per PR 1469. + // $FlowFixMe: Only works for ChildType = MathDomNode. + var toText = function toText(child) { + return child.toText(); + }; + + return this.children.map(toText).join(""); + }; + + return DocumentFragment; +}(); +// This file is GENERATED by buildMetrics.sh. DO NOT MODIFY. +/* harmony default export */ var fontMetricsData = ({ + "AMS-Regular": { + "32": [0, 0, 0, 0, 0.25], + "65": [0, 0.68889, 0, 0, 0.72222], + "66": [0, 0.68889, 0, 0, 0.66667], + "67": [0, 0.68889, 0, 0, 0.72222], + "68": [0, 0.68889, 0, 0, 0.72222], + "69": [0, 0.68889, 0, 0, 0.66667], + "70": [0, 0.68889, 0, 0, 0.61111], + "71": [0, 0.68889, 0, 0, 0.77778], + "72": [0, 0.68889, 0, 0, 0.77778], + "73": [0, 0.68889, 0, 0, 0.38889], + "74": [0.16667, 0.68889, 0, 0, 0.5], + "75": [0, 0.68889, 0, 0, 0.77778], + "76": [0, 0.68889, 0, 0, 0.66667], + "77": [0, 0.68889, 0, 0, 0.94445], + "78": [0, 0.68889, 0, 0, 0.72222], + "79": [0.16667, 0.68889, 0, 0, 0.77778], + "80": [0, 0.68889, 0, 0, 0.61111], + "81": [0.16667, 0.68889, 0, 0, 0.77778], + "82": [0, 0.68889, 0, 0, 0.72222], + "83": [0, 0.68889, 0, 0, 0.55556], + "84": [0, 0.68889, 0, 0, 0.66667], + "85": [0, 0.68889, 0, 0, 0.72222], + "86": [0, 0.68889, 0, 0, 0.72222], + "87": [0, 0.68889, 0, 0, 1.0], + "88": [0, 0.68889, 0, 0, 0.72222], + "89": [0, 0.68889, 0, 0, 0.72222], + "90": [0, 0.68889, 0, 0, 0.66667], + "107": [0, 0.68889, 0, 0, 0.55556], + "160": [0, 0, 0, 0, 0.25], + "165": [0, 0.675, 0.025, 0, 0.75], + "174": [0.15559, 0.69224, 0, 0, 0.94666], + "240": [0, 0.68889, 0, 0, 0.55556], + "295": [0, 0.68889, 0, 0, 0.54028], + "710": [0, 0.825, 0, 0, 2.33334], + "732": [0, 0.9, 0, 0, 2.33334], + "770": [0, 0.825, 0, 0, 2.33334], + "771": [0, 0.9, 0, 0, 2.33334], + "989": [0.08167, 0.58167, 0, 0, 0.77778], + "1008": [0, 0.43056, 0.04028, 0, 0.66667], + "8245": [0, 0.54986, 0, 0, 0.275], + "8463": [0, 0.68889, 0, 0, 0.54028], + "8487": [0, 0.68889, 0, 0, 0.72222], + "8498": [0, 0.68889, 0, 0, 0.55556], + "8502": [0, 0.68889, 0, 0, 0.66667], + "8503": [0, 0.68889, 0, 0, 0.44445], + "8504": [0, 0.68889, 0, 0, 0.66667], + "8513": [0, 0.68889, 0, 0, 0.63889], + "8592": [-0.03598, 0.46402, 0, 0, 0.5], + "8594": [-0.03598, 0.46402, 0, 0, 0.5], + "8602": [-0.13313, 0.36687, 0, 0, 1.0], + "8603": [-0.13313, 0.36687, 0, 0, 1.0], + "8606": [0.01354, 0.52239, 0, 0, 1.0], + "8608": [0.01354, 0.52239, 0, 0, 1.0], + "8610": [0.01354, 0.52239, 0, 0, 1.11111], + "8611": [0.01354, 0.52239, 0, 0, 1.11111], + "8619": [0, 0.54986, 0, 0, 1.0], + "8620": [0, 0.54986, 0, 0, 1.0], + "8621": [-0.13313, 0.37788, 0, 0, 1.38889], + "8622": [-0.13313, 0.36687, 0, 0, 1.0], + "8624": [0, 0.69224, 0, 0, 0.5], + "8625": [0, 0.69224, 0, 0, 0.5], + "8630": [0, 0.43056, 0, 0, 1.0], + "8631": [0, 0.43056, 0, 0, 1.0], + "8634": [0.08198, 0.58198, 0, 0, 0.77778], + "8635": [0.08198, 0.58198, 0, 0, 0.77778], + "8638": [0.19444, 0.69224, 0, 0, 0.41667], + "8639": [0.19444, 0.69224, 0, 0, 0.41667], + "8642": [0.19444, 0.69224, 0, 0, 0.41667], + "8643": [0.19444, 0.69224, 0, 0, 0.41667], + "8644": [0.1808, 0.675, 0, 0, 1.0], + "8646": [0.1808, 0.675, 0, 0, 1.0], + "8647": [0.1808, 0.675, 0, 0, 1.0], + "8648": [0.19444, 0.69224, 0, 0, 0.83334], + "8649": [0.1808, 0.675, 0, 0, 1.0], + "8650": [0.19444, 0.69224, 0, 0, 0.83334], + "8651": [0.01354, 0.52239, 0, 0, 1.0], + "8652": [0.01354, 0.52239, 0, 0, 1.0], + "8653": [-0.13313, 0.36687, 0, 0, 1.0], + "8654": [-0.13313, 0.36687, 0, 0, 1.0], + "8655": [-0.13313, 0.36687, 0, 0, 1.0], + "8666": [0.13667, 0.63667, 0, 0, 1.0], + "8667": [0.13667, 0.63667, 0, 0, 1.0], + "8669": [-0.13313, 0.37788, 0, 0, 1.0], + "8672": [-0.064, 0.437, 0, 0, 1.334], + "8674": [-0.064, 0.437, 0, 0, 1.334], + "8705": [0, 0.825, 0, 0, 0.5], + "8708": [0, 0.68889, 0, 0, 0.55556], + "8709": [0.08167, 0.58167, 0, 0, 0.77778], + "8717": [0, 0.43056, 0, 0, 0.42917], + "8722": [-0.03598, 0.46402, 0, 0, 0.5], + "8724": [0.08198, 0.69224, 0, 0, 0.77778], + "8726": [0.08167, 0.58167, 0, 0, 0.77778], + "8733": [0, 0.69224, 0, 0, 0.77778], + "8736": [0, 0.69224, 0, 0, 0.72222], + "8737": [0, 0.69224, 0, 0, 0.72222], + "8738": [0.03517, 0.52239, 0, 0, 0.72222], + "8739": [0.08167, 0.58167, 0, 0, 0.22222], + "8740": [0.25142, 0.74111, 0, 0, 0.27778], + "8741": [0.08167, 0.58167, 0, 0, 0.38889], + "8742": [0.25142, 0.74111, 0, 0, 0.5], + "8756": [0, 0.69224, 0, 0, 0.66667], + "8757": [0, 0.69224, 0, 0, 0.66667], + "8764": [-0.13313, 0.36687, 0, 0, 0.77778], + "8765": [-0.13313, 0.37788, 0, 0, 0.77778], + "8769": [-0.13313, 0.36687, 0, 0, 0.77778], + "8770": [-0.03625, 0.46375, 0, 0, 0.77778], + "8774": [0.30274, 0.79383, 0, 0, 0.77778], + "8776": [-0.01688, 0.48312, 0, 0, 0.77778], + "8778": [0.08167, 0.58167, 0, 0, 0.77778], + "8782": [0.06062, 0.54986, 0, 0, 0.77778], + "8783": [0.06062, 0.54986, 0, 0, 0.77778], + "8785": [0.08198, 0.58198, 0, 0, 0.77778], + "8786": [0.08198, 0.58198, 0, 0, 0.77778], + "8787": [0.08198, 0.58198, 0, 0, 0.77778], + "8790": [0, 0.69224, 0, 0, 0.77778], + "8791": [0.22958, 0.72958, 0, 0, 0.77778], + "8796": [0.08198, 0.91667, 0, 0, 0.77778], + "8806": [0.25583, 0.75583, 0, 0, 0.77778], + "8807": [0.25583, 0.75583, 0, 0, 0.77778], + "8808": [0.25142, 0.75726, 0, 0, 0.77778], + "8809": [0.25142, 0.75726, 0, 0, 0.77778], + "8812": [0.25583, 0.75583, 0, 0, 0.5], + "8814": [0.20576, 0.70576, 0, 0, 0.77778], + "8815": [0.20576, 0.70576, 0, 0, 0.77778], + "8816": [0.30274, 0.79383, 0, 0, 0.77778], + "8817": [0.30274, 0.79383, 0, 0, 0.77778], + "8818": [0.22958, 0.72958, 0, 0, 0.77778], + "8819": [0.22958, 0.72958, 0, 0, 0.77778], + "8822": [0.1808, 0.675, 0, 0, 0.77778], + "8823": [0.1808, 0.675, 0, 0, 0.77778], + "8828": [0.13667, 0.63667, 0, 0, 0.77778], + "8829": [0.13667, 0.63667, 0, 0, 0.77778], + "8830": [0.22958, 0.72958, 0, 0, 0.77778], + "8831": [0.22958, 0.72958, 0, 0, 0.77778], + "8832": [0.20576, 0.70576, 0, 0, 0.77778], + "8833": [0.20576, 0.70576, 0, 0, 0.77778], + "8840": [0.30274, 0.79383, 0, 0, 0.77778], + "8841": [0.30274, 0.79383, 0, 0, 0.77778], + "8842": [0.13597, 0.63597, 0, 0, 0.77778], + "8843": [0.13597, 0.63597, 0, 0, 0.77778], + "8847": [0.03517, 0.54986, 0, 0, 0.77778], + "8848": [0.03517, 0.54986, 0, 0, 0.77778], + "8858": [0.08198, 0.58198, 0, 0, 0.77778], + "8859": [0.08198, 0.58198, 0, 0, 0.77778], + "8861": [0.08198, 0.58198, 0, 0, 0.77778], + "8862": [0, 0.675, 0, 0, 0.77778], + "8863": [0, 0.675, 0, 0, 0.77778], + "8864": [0, 0.675, 0, 0, 0.77778], + "8865": [0, 0.675, 0, 0, 0.77778], + "8872": [0, 0.69224, 0, 0, 0.61111], + "8873": [0, 0.69224, 0, 0, 0.72222], + "8874": [0, 0.69224, 0, 0, 0.88889], + "8876": [0, 0.68889, 0, 0, 0.61111], + "8877": [0, 0.68889, 0, 0, 0.61111], + "8878": [0, 0.68889, 0, 0, 0.72222], + "8879": [0, 0.68889, 0, 0, 0.72222], + "8882": [0.03517, 0.54986, 0, 0, 0.77778], + "8883": [0.03517, 0.54986, 0, 0, 0.77778], + "8884": [0.13667, 0.63667, 0, 0, 0.77778], + "8885": [0.13667, 0.63667, 0, 0, 0.77778], + "8888": [0, 0.54986, 0, 0, 1.11111], + "8890": [0.19444, 0.43056, 0, 0, 0.55556], + "8891": [0.19444, 0.69224, 0, 0, 0.61111], + "8892": [0.19444, 0.69224, 0, 0, 0.61111], + "8901": [0, 0.54986, 0, 0, 0.27778], + "8903": [0.08167, 0.58167, 0, 0, 0.77778], + "8905": [0.08167, 0.58167, 0, 0, 0.77778], + "8906": [0.08167, 0.58167, 0, 0, 0.77778], + "8907": [0, 0.69224, 0, 0, 0.77778], + "8908": [0, 0.69224, 0, 0, 0.77778], + "8909": [-0.03598, 0.46402, 0, 0, 0.77778], + "8910": [0, 0.54986, 0, 0, 0.76042], + "8911": [0, 0.54986, 0, 0, 0.76042], + "8912": [0.03517, 0.54986, 0, 0, 0.77778], + "8913": [0.03517, 0.54986, 0, 0, 0.77778], + "8914": [0, 0.54986, 0, 0, 0.66667], + "8915": [0, 0.54986, 0, 0, 0.66667], + "8916": [0, 0.69224, 0, 0, 0.66667], + "8918": [0.0391, 0.5391, 0, 0, 0.77778], + "8919": [0.0391, 0.5391, 0, 0, 0.77778], + "8920": [0.03517, 0.54986, 0, 0, 1.33334], + "8921": [0.03517, 0.54986, 0, 0, 1.33334], + "8922": [0.38569, 0.88569, 0, 0, 0.77778], + "8923": [0.38569, 0.88569, 0, 0, 0.77778], + "8926": [0.13667, 0.63667, 0, 0, 0.77778], + "8927": [0.13667, 0.63667, 0, 0, 0.77778], + "8928": [0.30274, 0.79383, 0, 0, 0.77778], + "8929": [0.30274, 0.79383, 0, 0, 0.77778], + "8934": [0.23222, 0.74111, 0, 0, 0.77778], + "8935": [0.23222, 0.74111, 0, 0, 0.77778], + "8936": [0.23222, 0.74111, 0, 0, 0.77778], + "8937": [0.23222, 0.74111, 0, 0, 0.77778], + "8938": [0.20576, 0.70576, 0, 0, 0.77778], + "8939": [0.20576, 0.70576, 0, 0, 0.77778], + "8940": [0.30274, 0.79383, 0, 0, 0.77778], + "8941": [0.30274, 0.79383, 0, 0, 0.77778], + "8994": [0.19444, 0.69224, 0, 0, 0.77778], + "8995": [0.19444, 0.69224, 0, 0, 0.77778], + "9416": [0.15559, 0.69224, 0, 0, 0.90222], + "9484": [0, 0.69224, 0, 0, 0.5], + "9488": [0, 0.69224, 0, 0, 0.5], + "9492": [0, 0.37788, 0, 0, 0.5], + "9496": [0, 0.37788, 0, 0, 0.5], + "9585": [0.19444, 0.68889, 0, 0, 0.88889], + "9586": [0.19444, 0.74111, 0, 0, 0.88889], + "9632": [0, 0.675, 0, 0, 0.77778], + "9633": [0, 0.675, 0, 0, 0.77778], + "9650": [0, 0.54986, 0, 0, 0.72222], + "9651": [0, 0.54986, 0, 0, 0.72222], + "9654": [0.03517, 0.54986, 0, 0, 0.77778], + "9660": [0, 0.54986, 0, 0, 0.72222], + "9661": [0, 0.54986, 0, 0, 0.72222], + "9664": [0.03517, 0.54986, 0, 0, 0.77778], + "9674": [0.11111, 0.69224, 0, 0, 0.66667], + "9733": [0.19444, 0.69224, 0, 0, 0.94445], + "10003": [0, 0.69224, 0, 0, 0.83334], + "10016": [0, 0.69224, 0, 0, 0.83334], + "10731": [0.11111, 0.69224, 0, 0, 0.66667], + "10846": [0.19444, 0.75583, 0, 0, 0.61111], + "10877": [0.13667, 0.63667, 0, 0, 0.77778], + "10878": [0.13667, 0.63667, 0, 0, 0.77778], + "10885": [0.25583, 0.75583, 0, 0, 0.77778], + "10886": [0.25583, 0.75583, 0, 0, 0.77778], + "10887": [0.13597, 0.63597, 0, 0, 0.77778], + "10888": [0.13597, 0.63597, 0, 0, 0.77778], + "10889": [0.26167, 0.75726, 0, 0, 0.77778], + "10890": [0.26167, 0.75726, 0, 0, 0.77778], + "10891": [0.48256, 0.98256, 0, 0, 0.77778], + "10892": [0.48256, 0.98256, 0, 0, 0.77778], + "10901": [0.13667, 0.63667, 0, 0, 0.77778], + "10902": [0.13667, 0.63667, 0, 0, 0.77778], + "10933": [0.25142, 0.75726, 0, 0, 0.77778], + "10934": [0.25142, 0.75726, 0, 0, 0.77778], + "10935": [0.26167, 0.75726, 0, 0, 0.77778], + "10936": [0.26167, 0.75726, 0, 0, 0.77778], + "10937": [0.26167, 0.75726, 0, 0, 0.77778], + "10938": [0.26167, 0.75726, 0, 0, 0.77778], + "10949": [0.25583, 0.75583, 0, 0, 0.77778], + "10950": [0.25583, 0.75583, 0, 0, 0.77778], + "10955": [0.28481, 0.79383, 0, 0, 0.77778], + "10956": [0.28481, 0.79383, 0, 0, 0.77778], + "57350": [0.08167, 0.58167, 0, 0, 0.22222], + "57351": [0.08167, 0.58167, 0, 0, 0.38889], + "57352": [0.08167, 0.58167, 0, 0, 0.77778], + "57353": [0, 0.43056, 0.04028, 0, 0.66667], + "57356": [0.25142, 0.75726, 0, 0, 0.77778], + "57357": [0.25142, 0.75726, 0, 0, 0.77778], + "57358": [0.41951, 0.91951, 0, 0, 0.77778], + "57359": [0.30274, 0.79383, 0, 0, 0.77778], + "57360": [0.30274, 0.79383, 0, 0, 0.77778], + "57361": [0.41951, 0.91951, 0, 0, 0.77778], + "57366": [0.25142, 0.75726, 0, 0, 0.77778], + "57367": [0.25142, 0.75726, 0, 0, 0.77778], + "57368": [0.25142, 0.75726, 0, 0, 0.77778], + "57369": [0.25142, 0.75726, 0, 0, 0.77778], + "57370": [0.13597, 0.63597, 0, 0, 0.77778], + "57371": [0.13597, 0.63597, 0, 0, 0.77778] + }, + "Caligraphic-Regular": { + "32": [0, 0, 0, 0, 0.25], + "65": [0, 0.68333, 0, 0.19445, 0.79847], + "66": [0, 0.68333, 0.03041, 0.13889, 0.65681], + "67": [0, 0.68333, 0.05834, 0.13889, 0.52653], + "68": [0, 0.68333, 0.02778, 0.08334, 0.77139], + "69": [0, 0.68333, 0.08944, 0.11111, 0.52778], + "70": [0, 0.68333, 0.09931, 0.11111, 0.71875], + "71": [0.09722, 0.68333, 0.0593, 0.11111, 0.59487], + "72": [0, 0.68333, 0.00965, 0.11111, 0.84452], + "73": [0, 0.68333, 0.07382, 0, 0.54452], + "74": [0.09722, 0.68333, 0.18472, 0.16667, 0.67778], + "75": [0, 0.68333, 0.01445, 0.05556, 0.76195], + "76": [0, 0.68333, 0, 0.13889, 0.68972], + "77": [0, 0.68333, 0, 0.13889, 1.2009], + "78": [0, 0.68333, 0.14736, 0.08334, 0.82049], + "79": [0, 0.68333, 0.02778, 0.11111, 0.79611], + "80": [0, 0.68333, 0.08222, 0.08334, 0.69556], + "81": [0.09722, 0.68333, 0, 0.11111, 0.81667], + "82": [0, 0.68333, 0, 0.08334, 0.8475], + "83": [0, 0.68333, 0.075, 0.13889, 0.60556], + "84": [0, 0.68333, 0.25417, 0, 0.54464], + "85": [0, 0.68333, 0.09931, 0.08334, 0.62583], + "86": [0, 0.68333, 0.08222, 0, 0.61278], + "87": [0, 0.68333, 0.08222, 0.08334, 0.98778], + "88": [0, 0.68333, 0.14643, 0.13889, 0.7133], + "89": [0.09722, 0.68333, 0.08222, 0.08334, 0.66834], + "90": [0, 0.68333, 0.07944, 0.13889, 0.72473], + "160": [0, 0, 0, 0, 0.25] + }, + "Fraktur-Regular": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69141, 0, 0, 0.29574], + "34": [0, 0.69141, 0, 0, 0.21471], + "38": [0, 0.69141, 0, 0, 0.73786], + "39": [0, 0.69141, 0, 0, 0.21201], + "40": [0.24982, 0.74947, 0, 0, 0.38865], + "41": [0.24982, 0.74947, 0, 0, 0.38865], + "42": [0, 0.62119, 0, 0, 0.27764], + "43": [0.08319, 0.58283, 0, 0, 0.75623], + "44": [0, 0.10803, 0, 0, 0.27764], + "45": [0.08319, 0.58283, 0, 0, 0.75623], + "46": [0, 0.10803, 0, 0, 0.27764], + "47": [0.24982, 0.74947, 0, 0, 0.50181], + "48": [0, 0.47534, 0, 0, 0.50181], + "49": [0, 0.47534, 0, 0, 0.50181], + "50": [0, 0.47534, 0, 0, 0.50181], + "51": [0.18906, 0.47534, 0, 0, 0.50181], + "52": [0.18906, 0.47534, 0, 0, 0.50181], + "53": [0.18906, 0.47534, 0, 0, 0.50181], + "54": [0, 0.69141, 0, 0, 0.50181], + "55": [0.18906, 0.47534, 0, 0, 0.50181], + "56": [0, 0.69141, 0, 0, 0.50181], + "57": [0.18906, 0.47534, 0, 0, 0.50181], + "58": [0, 0.47534, 0, 0, 0.21606], + "59": [0.12604, 0.47534, 0, 0, 0.21606], + "61": [-0.13099, 0.36866, 0, 0, 0.75623], + "63": [0, 0.69141, 0, 0, 0.36245], + "65": [0, 0.69141, 0, 0, 0.7176], + "66": [0, 0.69141, 0, 0, 0.88397], + "67": [0, 0.69141, 0, 0, 0.61254], + "68": [0, 0.69141, 0, 0, 0.83158], + "69": [0, 0.69141, 0, 0, 0.66278], + "70": [0.12604, 0.69141, 0, 0, 0.61119], + "71": [0, 0.69141, 0, 0, 0.78539], + "72": [0.06302, 0.69141, 0, 0, 0.7203], + "73": [0, 0.69141, 0, 0, 0.55448], + "74": [0.12604, 0.69141, 0, 0, 0.55231], + "75": [0, 0.69141, 0, 0, 0.66845], + "76": [0, 0.69141, 0, 0, 0.66602], + "77": [0, 0.69141, 0, 0, 1.04953], + "78": [0, 0.69141, 0, 0, 0.83212], + "79": [0, 0.69141, 0, 0, 0.82699], + "80": [0.18906, 0.69141, 0, 0, 0.82753], + "81": [0.03781, 0.69141, 0, 0, 0.82699], + "82": [0, 0.69141, 0, 0, 0.82807], + "83": [0, 0.69141, 0, 0, 0.82861], + "84": [0, 0.69141, 0, 0, 0.66899], + "85": [0, 0.69141, 0, 0, 0.64576], + "86": [0, 0.69141, 0, 0, 0.83131], + "87": [0, 0.69141, 0, 0, 1.04602], + "88": [0, 0.69141, 0, 0, 0.71922], + "89": [0.18906, 0.69141, 0, 0, 0.83293], + "90": [0.12604, 0.69141, 0, 0, 0.60201], + "91": [0.24982, 0.74947, 0, 0, 0.27764], + "93": [0.24982, 0.74947, 0, 0, 0.27764], + "94": [0, 0.69141, 0, 0, 0.49965], + "97": [0, 0.47534, 0, 0, 0.50046], + "98": [0, 0.69141, 0, 0, 0.51315], + "99": [0, 0.47534, 0, 0, 0.38946], + "100": [0, 0.62119, 0, 0, 0.49857], + "101": [0, 0.47534, 0, 0, 0.40053], + "102": [0.18906, 0.69141, 0, 0, 0.32626], + "103": [0.18906, 0.47534, 0, 0, 0.5037], + "104": [0.18906, 0.69141, 0, 0, 0.52126], + "105": [0, 0.69141, 0, 0, 0.27899], + "106": [0, 0.69141, 0, 0, 0.28088], + "107": [0, 0.69141, 0, 0, 0.38946], + "108": [0, 0.69141, 0, 0, 0.27953], + "109": [0, 0.47534, 0, 0, 0.76676], + "110": [0, 0.47534, 0, 0, 0.52666], + "111": [0, 0.47534, 0, 0, 0.48885], + "112": [0.18906, 0.52396, 0, 0, 0.50046], + "113": [0.18906, 0.47534, 0, 0, 0.48912], + "114": [0, 0.47534, 0, 0, 0.38919], + "115": [0, 0.47534, 0, 0, 0.44266], + "116": [0, 0.62119, 0, 0, 0.33301], + "117": [0, 0.47534, 0, 0, 0.5172], + "118": [0, 0.52396, 0, 0, 0.5118], + "119": [0, 0.52396, 0, 0, 0.77351], + "120": [0.18906, 0.47534, 0, 0, 0.38865], + "121": [0.18906, 0.47534, 0, 0, 0.49884], + "122": [0.18906, 0.47534, 0, 0, 0.39054], + "160": [0, 0, 0, 0, 0.25], + "8216": [0, 0.69141, 0, 0, 0.21471], + "8217": [0, 0.69141, 0, 0, 0.21471], + "58112": [0, 0.62119, 0, 0, 0.49749], + "58113": [0, 0.62119, 0, 0, 0.4983], + "58114": [0.18906, 0.69141, 0, 0, 0.33328], + "58115": [0.18906, 0.69141, 0, 0, 0.32923], + "58116": [0.18906, 0.47534, 0, 0, 0.50343], + "58117": [0, 0.69141, 0, 0, 0.33301], + "58118": [0, 0.62119, 0, 0, 0.33409], + "58119": [0, 0.47534, 0, 0, 0.50073] + }, + "Main-Bold": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.35], + "34": [0, 0.69444, 0, 0, 0.60278], + "35": [0.19444, 0.69444, 0, 0, 0.95833], + "36": [0.05556, 0.75, 0, 0, 0.575], + "37": [0.05556, 0.75, 0, 0, 0.95833], + "38": [0, 0.69444, 0, 0, 0.89444], + "39": [0, 0.69444, 0, 0, 0.31944], + "40": [0.25, 0.75, 0, 0, 0.44722], + "41": [0.25, 0.75, 0, 0, 0.44722], + "42": [0, 0.75, 0, 0, 0.575], + "43": [0.13333, 0.63333, 0, 0, 0.89444], + "44": [0.19444, 0.15556, 0, 0, 0.31944], + "45": [0, 0.44444, 0, 0, 0.38333], + "46": [0, 0.15556, 0, 0, 0.31944], + "47": [0.25, 0.75, 0, 0, 0.575], + "48": [0, 0.64444, 0, 0, 0.575], + "49": [0, 0.64444, 0, 0, 0.575], + "50": [0, 0.64444, 0, 0, 0.575], + "51": [0, 0.64444, 0, 0, 0.575], + "52": [0, 0.64444, 0, 0, 0.575], + "53": [0, 0.64444, 0, 0, 0.575], + "54": [0, 0.64444, 0, 0, 0.575], + "55": [0, 0.64444, 0, 0, 0.575], + "56": [0, 0.64444, 0, 0, 0.575], + "57": [0, 0.64444, 0, 0, 0.575], + "58": [0, 0.44444, 0, 0, 0.31944], + "59": [0.19444, 0.44444, 0, 0, 0.31944], + "60": [0.08556, 0.58556, 0, 0, 0.89444], + "61": [-0.10889, 0.39111, 0, 0, 0.89444], + "62": [0.08556, 0.58556, 0, 0, 0.89444], + "63": [0, 0.69444, 0, 0, 0.54305], + "64": [0, 0.69444, 0, 0, 0.89444], + "65": [0, 0.68611, 0, 0, 0.86944], + "66": [0, 0.68611, 0, 0, 0.81805], + "67": [0, 0.68611, 0, 0, 0.83055], + "68": [0, 0.68611, 0, 0, 0.88194], + "69": [0, 0.68611, 0, 0, 0.75555], + "70": [0, 0.68611, 0, 0, 0.72361], + "71": [0, 0.68611, 0, 0, 0.90416], + "72": [0, 0.68611, 0, 0, 0.9], + "73": [0, 0.68611, 0, 0, 0.43611], + "74": [0, 0.68611, 0, 0, 0.59444], + "75": [0, 0.68611, 0, 0, 0.90138], + "76": [0, 0.68611, 0, 0, 0.69166], + "77": [0, 0.68611, 0, 0, 1.09166], + "78": [0, 0.68611, 0, 0, 0.9], + "79": [0, 0.68611, 0, 0, 0.86388], + "80": [0, 0.68611, 0, 0, 0.78611], + "81": [0.19444, 0.68611, 0, 0, 0.86388], + "82": [0, 0.68611, 0, 0, 0.8625], + "83": [0, 0.68611, 0, 0, 0.63889], + "84": [0, 0.68611, 0, 0, 0.8], + "85": [0, 0.68611, 0, 0, 0.88472], + "86": [0, 0.68611, 0.01597, 0, 0.86944], + "87": [0, 0.68611, 0.01597, 0, 1.18888], + "88": [0, 0.68611, 0, 0, 0.86944], + "89": [0, 0.68611, 0.02875, 0, 0.86944], + "90": [0, 0.68611, 0, 0, 0.70277], + "91": [0.25, 0.75, 0, 0, 0.31944], + "92": [0.25, 0.75, 0, 0, 0.575], + "93": [0.25, 0.75, 0, 0, 0.31944], + "94": [0, 0.69444, 0, 0, 0.575], + "95": [0.31, 0.13444, 0.03194, 0, 0.575], + "97": [0, 0.44444, 0, 0, 0.55902], + "98": [0, 0.69444, 0, 0, 0.63889], + "99": [0, 0.44444, 0, 0, 0.51111], + "100": [0, 0.69444, 0, 0, 0.63889], + "101": [0, 0.44444, 0, 0, 0.52708], + "102": [0, 0.69444, 0.10903, 0, 0.35139], + "103": [0.19444, 0.44444, 0.01597, 0, 0.575], + "104": [0, 0.69444, 0, 0, 0.63889], + "105": [0, 0.69444, 0, 0, 0.31944], + "106": [0.19444, 0.69444, 0, 0, 0.35139], + "107": [0, 0.69444, 0, 0, 0.60694], + "108": [0, 0.69444, 0, 0, 0.31944], + "109": [0, 0.44444, 0, 0, 0.95833], + "110": [0, 0.44444, 0, 0, 0.63889], + "111": [0, 0.44444, 0, 0, 0.575], + "112": [0.19444, 0.44444, 0, 0, 0.63889], + "113": [0.19444, 0.44444, 0, 0, 0.60694], + "114": [0, 0.44444, 0, 0, 0.47361], + "115": [0, 0.44444, 0, 0, 0.45361], + "116": [0, 0.63492, 0, 0, 0.44722], + "117": [0, 0.44444, 0, 0, 0.63889], + "118": [0, 0.44444, 0.01597, 0, 0.60694], + "119": [0, 0.44444, 0.01597, 0, 0.83055], + "120": [0, 0.44444, 0, 0, 0.60694], + "121": [0.19444, 0.44444, 0.01597, 0, 0.60694], + "122": [0, 0.44444, 0, 0, 0.51111], + "123": [0.25, 0.75, 0, 0, 0.575], + "124": [0.25, 0.75, 0, 0, 0.31944], + "125": [0.25, 0.75, 0, 0, 0.575], + "126": [0.35, 0.34444, 0, 0, 0.575], + "160": [0, 0, 0, 0, 0.25], + "163": [0, 0.69444, 0, 0, 0.86853], + "168": [0, 0.69444, 0, 0, 0.575], + "172": [0, 0.44444, 0, 0, 0.76666], + "176": [0, 0.69444, 0, 0, 0.86944], + "177": [0.13333, 0.63333, 0, 0, 0.89444], + "184": [0.17014, 0, 0, 0, 0.51111], + "198": [0, 0.68611, 0, 0, 1.04166], + "215": [0.13333, 0.63333, 0, 0, 0.89444], + "216": [0.04861, 0.73472, 0, 0, 0.89444], + "223": [0, 0.69444, 0, 0, 0.59722], + "230": [0, 0.44444, 0, 0, 0.83055], + "247": [0.13333, 0.63333, 0, 0, 0.89444], + "248": [0.09722, 0.54167, 0, 0, 0.575], + "305": [0, 0.44444, 0, 0, 0.31944], + "338": [0, 0.68611, 0, 0, 1.16944], + "339": [0, 0.44444, 0, 0, 0.89444], + "567": [0.19444, 0.44444, 0, 0, 0.35139], + "710": [0, 0.69444, 0, 0, 0.575], + "711": [0, 0.63194, 0, 0, 0.575], + "713": [0, 0.59611, 0, 0, 0.575], + "714": [0, 0.69444, 0, 0, 0.575], + "715": [0, 0.69444, 0, 0, 0.575], + "728": [0, 0.69444, 0, 0, 0.575], + "729": [0, 0.69444, 0, 0, 0.31944], + "730": [0, 0.69444, 0, 0, 0.86944], + "732": [0, 0.69444, 0, 0, 0.575], + "733": [0, 0.69444, 0, 0, 0.575], + "915": [0, 0.68611, 0, 0, 0.69166], + "916": [0, 0.68611, 0, 0, 0.95833], + "920": [0, 0.68611, 0, 0, 0.89444], + "923": [0, 0.68611, 0, 0, 0.80555], + "926": [0, 0.68611, 0, 0, 0.76666], + "928": [0, 0.68611, 0, 0, 0.9], + "931": [0, 0.68611, 0, 0, 0.83055], + "933": [0, 0.68611, 0, 0, 0.89444], + "934": [0, 0.68611, 0, 0, 0.83055], + "936": [0, 0.68611, 0, 0, 0.89444], + "937": [0, 0.68611, 0, 0, 0.83055], + "8211": [0, 0.44444, 0.03194, 0, 0.575], + "8212": [0, 0.44444, 0.03194, 0, 1.14999], + "8216": [0, 0.69444, 0, 0, 0.31944], + "8217": [0, 0.69444, 0, 0, 0.31944], + "8220": [0, 0.69444, 0, 0, 0.60278], + "8221": [0, 0.69444, 0, 0, 0.60278], + "8224": [0.19444, 0.69444, 0, 0, 0.51111], + "8225": [0.19444, 0.69444, 0, 0, 0.51111], + "8242": [0, 0.55556, 0, 0, 0.34444], + "8407": [0, 0.72444, 0.15486, 0, 0.575], + "8463": [0, 0.69444, 0, 0, 0.66759], + "8465": [0, 0.69444, 0, 0, 0.83055], + "8467": [0, 0.69444, 0, 0, 0.47361], + "8472": [0.19444, 0.44444, 0, 0, 0.74027], + "8476": [0, 0.69444, 0, 0, 0.83055], + "8501": [0, 0.69444, 0, 0, 0.70277], + "8592": [-0.10889, 0.39111, 0, 0, 1.14999], + "8593": [0.19444, 0.69444, 0, 0, 0.575], + "8594": [-0.10889, 0.39111, 0, 0, 1.14999], + "8595": [0.19444, 0.69444, 0, 0, 0.575], + "8596": [-0.10889, 0.39111, 0, 0, 1.14999], + "8597": [0.25, 0.75, 0, 0, 0.575], + "8598": [0.19444, 0.69444, 0, 0, 1.14999], + "8599": [0.19444, 0.69444, 0, 0, 1.14999], + "8600": [0.19444, 0.69444, 0, 0, 1.14999], + "8601": [0.19444, 0.69444, 0, 0, 1.14999], + "8636": [-0.10889, 0.39111, 0, 0, 1.14999], + "8637": [-0.10889, 0.39111, 0, 0, 1.14999], + "8640": [-0.10889, 0.39111, 0, 0, 1.14999], + "8641": [-0.10889, 0.39111, 0, 0, 1.14999], + "8656": [-0.10889, 0.39111, 0, 0, 1.14999], + "8657": [0.19444, 0.69444, 0, 0, 0.70277], + "8658": [-0.10889, 0.39111, 0, 0, 1.14999], + "8659": [0.19444, 0.69444, 0, 0, 0.70277], + "8660": [-0.10889, 0.39111, 0, 0, 1.14999], + "8661": [0.25, 0.75, 0, 0, 0.70277], + "8704": [0, 0.69444, 0, 0, 0.63889], + "8706": [0, 0.69444, 0.06389, 0, 0.62847], + "8707": [0, 0.69444, 0, 0, 0.63889], + "8709": [0.05556, 0.75, 0, 0, 0.575], + "8711": [0, 0.68611, 0, 0, 0.95833], + "8712": [0.08556, 0.58556, 0, 0, 0.76666], + "8715": [0.08556, 0.58556, 0, 0, 0.76666], + "8722": [0.13333, 0.63333, 0, 0, 0.89444], + "8723": [0.13333, 0.63333, 0, 0, 0.89444], + "8725": [0.25, 0.75, 0, 0, 0.575], + "8726": [0.25, 0.75, 0, 0, 0.575], + "8727": [-0.02778, 0.47222, 0, 0, 0.575], + "8728": [-0.02639, 0.47361, 0, 0, 0.575], + "8729": [-0.02639, 0.47361, 0, 0, 0.575], + "8730": [0.18, 0.82, 0, 0, 0.95833], + "8733": [0, 0.44444, 0, 0, 0.89444], + "8734": [0, 0.44444, 0, 0, 1.14999], + "8736": [0, 0.69224, 0, 0, 0.72222], + "8739": [0.25, 0.75, 0, 0, 0.31944], + "8741": [0.25, 0.75, 0, 0, 0.575], + "8743": [0, 0.55556, 0, 0, 0.76666], + "8744": [0, 0.55556, 0, 0, 0.76666], + "8745": [0, 0.55556, 0, 0, 0.76666], + "8746": [0, 0.55556, 0, 0, 0.76666], + "8747": [0.19444, 0.69444, 0.12778, 0, 0.56875], + "8764": [-0.10889, 0.39111, 0, 0, 0.89444], + "8768": [0.19444, 0.69444, 0, 0, 0.31944], + "8771": [0.00222, 0.50222, 0, 0, 0.89444], + "8773": [0.027, 0.638, 0, 0, 0.894], + "8776": [0.02444, 0.52444, 0, 0, 0.89444], + "8781": [0.00222, 0.50222, 0, 0, 0.89444], + "8801": [0.00222, 0.50222, 0, 0, 0.89444], + "8804": [0.19667, 0.69667, 0, 0, 0.89444], + "8805": [0.19667, 0.69667, 0, 0, 0.89444], + "8810": [0.08556, 0.58556, 0, 0, 1.14999], + "8811": [0.08556, 0.58556, 0, 0, 1.14999], + "8826": [0.08556, 0.58556, 0, 0, 0.89444], + "8827": [0.08556, 0.58556, 0, 0, 0.89444], + "8834": [0.08556, 0.58556, 0, 0, 0.89444], + "8835": [0.08556, 0.58556, 0, 0, 0.89444], + "8838": [0.19667, 0.69667, 0, 0, 0.89444], + "8839": [0.19667, 0.69667, 0, 0, 0.89444], + "8846": [0, 0.55556, 0, 0, 0.76666], + "8849": [0.19667, 0.69667, 0, 0, 0.89444], + "8850": [0.19667, 0.69667, 0, 0, 0.89444], + "8851": [0, 0.55556, 0, 0, 0.76666], + "8852": [0, 0.55556, 0, 0, 0.76666], + "8853": [0.13333, 0.63333, 0, 0, 0.89444], + "8854": [0.13333, 0.63333, 0, 0, 0.89444], + "8855": [0.13333, 0.63333, 0, 0, 0.89444], + "8856": [0.13333, 0.63333, 0, 0, 0.89444], + "8857": [0.13333, 0.63333, 0, 0, 0.89444], + "8866": [0, 0.69444, 0, 0, 0.70277], + "8867": [0, 0.69444, 0, 0, 0.70277], + "8868": [0, 0.69444, 0, 0, 0.89444], + "8869": [0, 0.69444, 0, 0, 0.89444], + "8900": [-0.02639, 0.47361, 0, 0, 0.575], + "8901": [-0.02639, 0.47361, 0, 0, 0.31944], + "8902": [-0.02778, 0.47222, 0, 0, 0.575], + "8968": [0.25, 0.75, 0, 0, 0.51111], + "8969": [0.25, 0.75, 0, 0, 0.51111], + "8970": [0.25, 0.75, 0, 0, 0.51111], + "8971": [0.25, 0.75, 0, 0, 0.51111], + "8994": [-0.13889, 0.36111, 0, 0, 1.14999], + "8995": [-0.13889, 0.36111, 0, 0, 1.14999], + "9651": [0.19444, 0.69444, 0, 0, 1.02222], + "9657": [-0.02778, 0.47222, 0, 0, 0.575], + "9661": [0.19444, 0.69444, 0, 0, 1.02222], + "9667": [-0.02778, 0.47222, 0, 0, 0.575], + "9711": [0.19444, 0.69444, 0, 0, 1.14999], + "9824": [0.12963, 0.69444, 0, 0, 0.89444], + "9825": [0.12963, 0.69444, 0, 0, 0.89444], + "9826": [0.12963, 0.69444, 0, 0, 0.89444], + "9827": [0.12963, 0.69444, 0, 0, 0.89444], + "9837": [0, 0.75, 0, 0, 0.44722], + "9838": [0.19444, 0.69444, 0, 0, 0.44722], + "9839": [0.19444, 0.69444, 0, 0, 0.44722], + "10216": [0.25, 0.75, 0, 0, 0.44722], + "10217": [0.25, 0.75, 0, 0, 0.44722], + "10815": [0, 0.68611, 0, 0, 0.9], + "10927": [0.19667, 0.69667, 0, 0, 0.89444], + "10928": [0.19667, 0.69667, 0, 0, 0.89444], + "57376": [0.19444, 0.69444, 0, 0, 0] + }, + "Main-BoldItalic": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0.11417, 0, 0.38611], + "34": [0, 0.69444, 0.07939, 0, 0.62055], + "35": [0.19444, 0.69444, 0.06833, 0, 0.94444], + "37": [0.05556, 0.75, 0.12861, 0, 0.94444], + "38": [0, 0.69444, 0.08528, 0, 0.88555], + "39": [0, 0.69444, 0.12945, 0, 0.35555], + "40": [0.25, 0.75, 0.15806, 0, 0.47333], + "41": [0.25, 0.75, 0.03306, 0, 0.47333], + "42": [0, 0.75, 0.14333, 0, 0.59111], + "43": [0.10333, 0.60333, 0.03306, 0, 0.88555], + "44": [0.19444, 0.14722, 0, 0, 0.35555], + "45": [0, 0.44444, 0.02611, 0, 0.41444], + "46": [0, 0.14722, 0, 0, 0.35555], + "47": [0.25, 0.75, 0.15806, 0, 0.59111], + "48": [0, 0.64444, 0.13167, 0, 0.59111], + "49": [0, 0.64444, 0.13167, 0, 0.59111], + "50": [0, 0.64444, 0.13167, 0, 0.59111], + "51": [0, 0.64444, 0.13167, 0, 0.59111], + "52": [0.19444, 0.64444, 0.13167, 0, 0.59111], + "53": [0, 0.64444, 0.13167, 0, 0.59111], + "54": [0, 0.64444, 0.13167, 0, 0.59111], + "55": [0.19444, 0.64444, 0.13167, 0, 0.59111], + "56": [0, 0.64444, 0.13167, 0, 0.59111], + "57": [0, 0.64444, 0.13167, 0, 0.59111], + "58": [0, 0.44444, 0.06695, 0, 0.35555], + "59": [0.19444, 0.44444, 0.06695, 0, 0.35555], + "61": [-0.10889, 0.39111, 0.06833, 0, 0.88555], + "63": [0, 0.69444, 0.11472, 0, 0.59111], + "64": [0, 0.69444, 0.09208, 0, 0.88555], + "65": [0, 0.68611, 0, 0, 0.86555], + "66": [0, 0.68611, 0.0992, 0, 0.81666], + "67": [0, 0.68611, 0.14208, 0, 0.82666], + "68": [0, 0.68611, 0.09062, 0, 0.87555], + "69": [0, 0.68611, 0.11431, 0, 0.75666], + "70": [0, 0.68611, 0.12903, 0, 0.72722], + "71": [0, 0.68611, 0.07347, 0, 0.89527], + "72": [0, 0.68611, 0.17208, 0, 0.8961], + "73": [0, 0.68611, 0.15681, 0, 0.47166], + "74": [0, 0.68611, 0.145, 0, 0.61055], + "75": [0, 0.68611, 0.14208, 0, 0.89499], + "76": [0, 0.68611, 0, 0, 0.69777], + "77": [0, 0.68611, 0.17208, 0, 1.07277], + "78": [0, 0.68611, 0.17208, 0, 0.8961], + "79": [0, 0.68611, 0.09062, 0, 0.85499], + "80": [0, 0.68611, 0.0992, 0, 0.78721], + "81": [0.19444, 0.68611, 0.09062, 0, 0.85499], + "82": [0, 0.68611, 0.02559, 0, 0.85944], + "83": [0, 0.68611, 0.11264, 0, 0.64999], + "84": [0, 0.68611, 0.12903, 0, 0.7961], + "85": [0, 0.68611, 0.17208, 0, 0.88083], + "86": [0, 0.68611, 0.18625, 0, 0.86555], + "87": [0, 0.68611, 0.18625, 0, 1.15999], + "88": [0, 0.68611, 0.15681, 0, 0.86555], + "89": [0, 0.68611, 0.19803, 0, 0.86555], + "90": [0, 0.68611, 0.14208, 0, 0.70888], + "91": [0.25, 0.75, 0.1875, 0, 0.35611], + "93": [0.25, 0.75, 0.09972, 0, 0.35611], + "94": [0, 0.69444, 0.06709, 0, 0.59111], + "95": [0.31, 0.13444, 0.09811, 0, 0.59111], + "97": [0, 0.44444, 0.09426, 0, 0.59111], + "98": [0, 0.69444, 0.07861, 0, 0.53222], + "99": [0, 0.44444, 0.05222, 0, 0.53222], + "100": [0, 0.69444, 0.10861, 0, 0.59111], + "101": [0, 0.44444, 0.085, 0, 0.53222], + "102": [0.19444, 0.69444, 0.21778, 0, 0.4], + "103": [0.19444, 0.44444, 0.105, 0, 0.53222], + "104": [0, 0.69444, 0.09426, 0, 0.59111], + "105": [0, 0.69326, 0.11387, 0, 0.35555], + "106": [0.19444, 0.69326, 0.1672, 0, 0.35555], + "107": [0, 0.69444, 0.11111, 0, 0.53222], + "108": [0, 0.69444, 0.10861, 0, 0.29666], + "109": [0, 0.44444, 0.09426, 0, 0.94444], + "110": [0, 0.44444, 0.09426, 0, 0.64999], + "111": [0, 0.44444, 0.07861, 0, 0.59111], + "112": [0.19444, 0.44444, 0.07861, 0, 0.59111], + "113": [0.19444, 0.44444, 0.105, 0, 0.53222], + "114": [0, 0.44444, 0.11111, 0, 0.50167], + "115": [0, 0.44444, 0.08167, 0, 0.48694], + "116": [0, 0.63492, 0.09639, 0, 0.385], + "117": [0, 0.44444, 0.09426, 0, 0.62055], + "118": [0, 0.44444, 0.11111, 0, 0.53222], + "119": [0, 0.44444, 0.11111, 0, 0.76777], + "120": [0, 0.44444, 0.12583, 0, 0.56055], + "121": [0.19444, 0.44444, 0.105, 0, 0.56166], + "122": [0, 0.44444, 0.13889, 0, 0.49055], + "126": [0.35, 0.34444, 0.11472, 0, 0.59111], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.69444, 0.11473, 0, 0.59111], + "176": [0, 0.69444, 0, 0, 0.94888], + "184": [0.17014, 0, 0, 0, 0.53222], + "198": [0, 0.68611, 0.11431, 0, 1.02277], + "216": [0.04861, 0.73472, 0.09062, 0, 0.88555], + "223": [0.19444, 0.69444, 0.09736, 0, 0.665], + "230": [0, 0.44444, 0.085, 0, 0.82666], + "248": [0.09722, 0.54167, 0.09458, 0, 0.59111], + "305": [0, 0.44444, 0.09426, 0, 0.35555], + "338": [0, 0.68611, 0.11431, 0, 1.14054], + "339": [0, 0.44444, 0.085, 0, 0.82666], + "567": [0.19444, 0.44444, 0.04611, 0, 0.385], + "710": [0, 0.69444, 0.06709, 0, 0.59111], + "711": [0, 0.63194, 0.08271, 0, 0.59111], + "713": [0, 0.59444, 0.10444, 0, 0.59111], + "714": [0, 0.69444, 0.08528, 0, 0.59111], + "715": [0, 0.69444, 0, 0, 0.59111], + "728": [0, 0.69444, 0.10333, 0, 0.59111], + "729": [0, 0.69444, 0.12945, 0, 0.35555], + "730": [0, 0.69444, 0, 0, 0.94888], + "732": [0, 0.69444, 0.11472, 0, 0.59111], + "733": [0, 0.69444, 0.11472, 0, 0.59111], + "915": [0, 0.68611, 0.12903, 0, 0.69777], + "916": [0, 0.68611, 0, 0, 0.94444], + "920": [0, 0.68611, 0.09062, 0, 0.88555], + "923": [0, 0.68611, 0, 0, 0.80666], + "926": [0, 0.68611, 0.15092, 0, 0.76777], + "928": [0, 0.68611, 0.17208, 0, 0.8961], + "931": [0, 0.68611, 0.11431, 0, 0.82666], + "933": [0, 0.68611, 0.10778, 0, 0.88555], + "934": [0, 0.68611, 0.05632, 0, 0.82666], + "936": [0, 0.68611, 0.10778, 0, 0.88555], + "937": [0, 0.68611, 0.0992, 0, 0.82666], + "8211": [0, 0.44444, 0.09811, 0, 0.59111], + "8212": [0, 0.44444, 0.09811, 0, 1.18221], + "8216": [0, 0.69444, 0.12945, 0, 0.35555], + "8217": [0, 0.69444, 0.12945, 0, 0.35555], + "8220": [0, 0.69444, 0.16772, 0, 0.62055], + "8221": [0, 0.69444, 0.07939, 0, 0.62055] + }, + "Main-Italic": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0.12417, 0, 0.30667], + "34": [0, 0.69444, 0.06961, 0, 0.51444], + "35": [0.19444, 0.69444, 0.06616, 0, 0.81777], + "37": [0.05556, 0.75, 0.13639, 0, 0.81777], + "38": [0, 0.69444, 0.09694, 0, 0.76666], + "39": [0, 0.69444, 0.12417, 0, 0.30667], + "40": [0.25, 0.75, 0.16194, 0, 0.40889], + "41": [0.25, 0.75, 0.03694, 0, 0.40889], + "42": [0, 0.75, 0.14917, 0, 0.51111], + "43": [0.05667, 0.56167, 0.03694, 0, 0.76666], + "44": [0.19444, 0.10556, 0, 0, 0.30667], + "45": [0, 0.43056, 0.02826, 0, 0.35778], + "46": [0, 0.10556, 0, 0, 0.30667], + "47": [0.25, 0.75, 0.16194, 0, 0.51111], + "48": [0, 0.64444, 0.13556, 0, 0.51111], + "49": [0, 0.64444, 0.13556, 0, 0.51111], + "50": [0, 0.64444, 0.13556, 0, 0.51111], + "51": [0, 0.64444, 0.13556, 0, 0.51111], + "52": [0.19444, 0.64444, 0.13556, 0, 0.51111], + "53": [0, 0.64444, 0.13556, 0, 0.51111], + "54": [0, 0.64444, 0.13556, 0, 0.51111], + "55": [0.19444, 0.64444, 0.13556, 0, 0.51111], + "56": [0, 0.64444, 0.13556, 0, 0.51111], + "57": [0, 0.64444, 0.13556, 0, 0.51111], + "58": [0, 0.43056, 0.0582, 0, 0.30667], + "59": [0.19444, 0.43056, 0.0582, 0, 0.30667], + "61": [-0.13313, 0.36687, 0.06616, 0, 0.76666], + "63": [0, 0.69444, 0.1225, 0, 0.51111], + "64": [0, 0.69444, 0.09597, 0, 0.76666], + "65": [0, 0.68333, 0, 0, 0.74333], + "66": [0, 0.68333, 0.10257, 0, 0.70389], + "67": [0, 0.68333, 0.14528, 0, 0.71555], + "68": [0, 0.68333, 0.09403, 0, 0.755], + "69": [0, 0.68333, 0.12028, 0, 0.67833], + "70": [0, 0.68333, 0.13305, 0, 0.65277], + "71": [0, 0.68333, 0.08722, 0, 0.77361], + "72": [0, 0.68333, 0.16389, 0, 0.74333], + "73": [0, 0.68333, 0.15806, 0, 0.38555], + "74": [0, 0.68333, 0.14028, 0, 0.525], + "75": [0, 0.68333, 0.14528, 0, 0.76888], + "76": [0, 0.68333, 0, 0, 0.62722], + "77": [0, 0.68333, 0.16389, 0, 0.89666], + "78": [0, 0.68333, 0.16389, 0, 0.74333], + "79": [0, 0.68333, 0.09403, 0, 0.76666], + "80": [0, 0.68333, 0.10257, 0, 0.67833], + "81": [0.19444, 0.68333, 0.09403, 0, 0.76666], + "82": [0, 0.68333, 0.03868, 0, 0.72944], + "83": [0, 0.68333, 0.11972, 0, 0.56222], + "84": [0, 0.68333, 0.13305, 0, 0.71555], + "85": [0, 0.68333, 0.16389, 0, 0.74333], + "86": [0, 0.68333, 0.18361, 0, 0.74333], + "87": [0, 0.68333, 0.18361, 0, 0.99888], + "88": [0, 0.68333, 0.15806, 0, 0.74333], + "89": [0, 0.68333, 0.19383, 0, 0.74333], + "90": [0, 0.68333, 0.14528, 0, 0.61333], + "91": [0.25, 0.75, 0.1875, 0, 0.30667], + "93": [0.25, 0.75, 0.10528, 0, 0.30667], + "94": [0, 0.69444, 0.06646, 0, 0.51111], + "95": [0.31, 0.12056, 0.09208, 0, 0.51111], + "97": [0, 0.43056, 0.07671, 0, 0.51111], + "98": [0, 0.69444, 0.06312, 0, 0.46], + "99": [0, 0.43056, 0.05653, 0, 0.46], + "100": [0, 0.69444, 0.10333, 0, 0.51111], + "101": [0, 0.43056, 0.07514, 0, 0.46], + "102": [0.19444, 0.69444, 0.21194, 0, 0.30667], + "103": [0.19444, 0.43056, 0.08847, 0, 0.46], + "104": [0, 0.69444, 0.07671, 0, 0.51111], + "105": [0, 0.65536, 0.1019, 0, 0.30667], + "106": [0.19444, 0.65536, 0.14467, 0, 0.30667], + "107": [0, 0.69444, 0.10764, 0, 0.46], + "108": [0, 0.69444, 0.10333, 0, 0.25555], + "109": [0, 0.43056, 0.07671, 0, 0.81777], + "110": [0, 0.43056, 0.07671, 0, 0.56222], + "111": [0, 0.43056, 0.06312, 0, 0.51111], + "112": [0.19444, 0.43056, 0.06312, 0, 0.51111], + "113": [0.19444, 0.43056, 0.08847, 0, 0.46], + "114": [0, 0.43056, 0.10764, 0, 0.42166], + "115": [0, 0.43056, 0.08208, 0, 0.40889], + "116": [0, 0.61508, 0.09486, 0, 0.33222], + "117": [0, 0.43056, 0.07671, 0, 0.53666], + "118": [0, 0.43056, 0.10764, 0, 0.46], + "119": [0, 0.43056, 0.10764, 0, 0.66444], + "120": [0, 0.43056, 0.12042, 0, 0.46389], + "121": [0.19444, 0.43056, 0.08847, 0, 0.48555], + "122": [0, 0.43056, 0.12292, 0, 0.40889], + "126": [0.35, 0.31786, 0.11585, 0, 0.51111], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.66786, 0.10474, 0, 0.51111], + "176": [0, 0.69444, 0, 0, 0.83129], + "184": [0.17014, 0, 0, 0, 0.46], + "198": [0, 0.68333, 0.12028, 0, 0.88277], + "216": [0.04861, 0.73194, 0.09403, 0, 0.76666], + "223": [0.19444, 0.69444, 0.10514, 0, 0.53666], + "230": [0, 0.43056, 0.07514, 0, 0.71555], + "248": [0.09722, 0.52778, 0.09194, 0, 0.51111], + "338": [0, 0.68333, 0.12028, 0, 0.98499], + "339": [0, 0.43056, 0.07514, 0, 0.71555], + "710": [0, 0.69444, 0.06646, 0, 0.51111], + "711": [0, 0.62847, 0.08295, 0, 0.51111], + "713": [0, 0.56167, 0.10333, 0, 0.51111], + "714": [0, 0.69444, 0.09694, 0, 0.51111], + "715": [0, 0.69444, 0, 0, 0.51111], + "728": [0, 0.69444, 0.10806, 0, 0.51111], + "729": [0, 0.66786, 0.11752, 0, 0.30667], + "730": [0, 0.69444, 0, 0, 0.83129], + "732": [0, 0.66786, 0.11585, 0, 0.51111], + "733": [0, 0.69444, 0.1225, 0, 0.51111], + "915": [0, 0.68333, 0.13305, 0, 0.62722], + "916": [0, 0.68333, 0, 0, 0.81777], + "920": [0, 0.68333, 0.09403, 0, 0.76666], + "923": [0, 0.68333, 0, 0, 0.69222], + "926": [0, 0.68333, 0.15294, 0, 0.66444], + "928": [0, 0.68333, 0.16389, 0, 0.74333], + "931": [0, 0.68333, 0.12028, 0, 0.71555], + "933": [0, 0.68333, 0.11111, 0, 0.76666], + "934": [0, 0.68333, 0.05986, 0, 0.71555], + "936": [0, 0.68333, 0.11111, 0, 0.76666], + "937": [0, 0.68333, 0.10257, 0, 0.71555], + "8211": [0, 0.43056, 0.09208, 0, 0.51111], + "8212": [0, 0.43056, 0.09208, 0, 1.02222], + "8216": [0, 0.69444, 0.12417, 0, 0.30667], + "8217": [0, 0.69444, 0.12417, 0, 0.30667], + "8220": [0, 0.69444, 0.1685, 0, 0.51444], + "8221": [0, 0.69444, 0.06961, 0, 0.51444], + "8463": [0, 0.68889, 0, 0, 0.54028] + }, + "Main-Regular": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.27778], + "34": [0, 0.69444, 0, 0, 0.5], + "35": [0.19444, 0.69444, 0, 0, 0.83334], + "36": [0.05556, 0.75, 0, 0, 0.5], + "37": [0.05556, 0.75, 0, 0, 0.83334], + "38": [0, 0.69444, 0, 0, 0.77778], + "39": [0, 0.69444, 0, 0, 0.27778], + "40": [0.25, 0.75, 0, 0, 0.38889], + "41": [0.25, 0.75, 0, 0, 0.38889], + "42": [0, 0.75, 0, 0, 0.5], + "43": [0.08333, 0.58333, 0, 0, 0.77778], + "44": [0.19444, 0.10556, 0, 0, 0.27778], + "45": [0, 0.43056, 0, 0, 0.33333], + "46": [0, 0.10556, 0, 0, 0.27778], + "47": [0.25, 0.75, 0, 0, 0.5], + "48": [0, 0.64444, 0, 0, 0.5], + "49": [0, 0.64444, 0, 0, 0.5], + "50": [0, 0.64444, 0, 0, 0.5], + "51": [0, 0.64444, 0, 0, 0.5], + "52": [0, 0.64444, 0, 0, 0.5], + "53": [0, 0.64444, 0, 0, 0.5], + "54": [0, 0.64444, 0, 0, 0.5], + "55": [0, 0.64444, 0, 0, 0.5], + "56": [0, 0.64444, 0, 0, 0.5], + "57": [0, 0.64444, 0, 0, 0.5], + "58": [0, 0.43056, 0, 0, 0.27778], + "59": [0.19444, 0.43056, 0, 0, 0.27778], + "60": [0.0391, 0.5391, 0, 0, 0.77778], + "61": [-0.13313, 0.36687, 0, 0, 0.77778], + "62": [0.0391, 0.5391, 0, 0, 0.77778], + "63": [0, 0.69444, 0, 0, 0.47222], + "64": [0, 0.69444, 0, 0, 0.77778], + "65": [0, 0.68333, 0, 0, 0.75], + "66": [0, 0.68333, 0, 0, 0.70834], + "67": [0, 0.68333, 0, 0, 0.72222], + "68": [0, 0.68333, 0, 0, 0.76389], + "69": [0, 0.68333, 0, 0, 0.68056], + "70": [0, 0.68333, 0, 0, 0.65278], + "71": [0, 0.68333, 0, 0, 0.78472], + "72": [0, 0.68333, 0, 0, 0.75], + "73": [0, 0.68333, 0, 0, 0.36111], + "74": [0, 0.68333, 0, 0, 0.51389], + "75": [0, 0.68333, 0, 0, 0.77778], + "76": [0, 0.68333, 0, 0, 0.625], + "77": [0, 0.68333, 0, 0, 0.91667], + "78": [0, 0.68333, 0, 0, 0.75], + "79": [0, 0.68333, 0, 0, 0.77778], + "80": [0, 0.68333, 0, 0, 0.68056], + "81": [0.19444, 0.68333, 0, 0, 0.77778], + "82": [0, 0.68333, 0, 0, 0.73611], + "83": [0, 0.68333, 0, 0, 0.55556], + "84": [0, 0.68333, 0, 0, 0.72222], + "85": [0, 0.68333, 0, 0, 0.75], + "86": [0, 0.68333, 0.01389, 0, 0.75], + "87": [0, 0.68333, 0.01389, 0, 1.02778], + "88": [0, 0.68333, 0, 0, 0.75], + "89": [0, 0.68333, 0.025, 0, 0.75], + "90": [0, 0.68333, 0, 0, 0.61111], + "91": [0.25, 0.75, 0, 0, 0.27778], + "92": [0.25, 0.75, 0, 0, 0.5], + "93": [0.25, 0.75, 0, 0, 0.27778], + "94": [0, 0.69444, 0, 0, 0.5], + "95": [0.31, 0.12056, 0.02778, 0, 0.5], + "97": [0, 0.43056, 0, 0, 0.5], + "98": [0, 0.69444, 0, 0, 0.55556], + "99": [0, 0.43056, 0, 0, 0.44445], + "100": [0, 0.69444, 0, 0, 0.55556], + "101": [0, 0.43056, 0, 0, 0.44445], + "102": [0, 0.69444, 0.07778, 0, 0.30556], + "103": [0.19444, 0.43056, 0.01389, 0, 0.5], + "104": [0, 0.69444, 0, 0, 0.55556], + "105": [0, 0.66786, 0, 0, 0.27778], + "106": [0.19444, 0.66786, 0, 0, 0.30556], + "107": [0, 0.69444, 0, 0, 0.52778], + "108": [0, 0.69444, 0, 0, 0.27778], + "109": [0, 0.43056, 0, 0, 0.83334], + "110": [0, 0.43056, 0, 0, 0.55556], + "111": [0, 0.43056, 0, 0, 0.5], + "112": [0.19444, 0.43056, 0, 0, 0.55556], + "113": [0.19444, 0.43056, 0, 0, 0.52778], + "114": [0, 0.43056, 0, 0, 0.39167], + "115": [0, 0.43056, 0, 0, 0.39445], + "116": [0, 0.61508, 0, 0, 0.38889], + "117": [0, 0.43056, 0, 0, 0.55556], + "118": [0, 0.43056, 0.01389, 0, 0.52778], + "119": [0, 0.43056, 0.01389, 0, 0.72222], + "120": [0, 0.43056, 0, 0, 0.52778], + "121": [0.19444, 0.43056, 0.01389, 0, 0.52778], + "122": [0, 0.43056, 0, 0, 0.44445], + "123": [0.25, 0.75, 0, 0, 0.5], + "124": [0.25, 0.75, 0, 0, 0.27778], + "125": [0.25, 0.75, 0, 0, 0.5], + "126": [0.35, 0.31786, 0, 0, 0.5], + "160": [0, 0, 0, 0, 0.25], + "163": [0, 0.69444, 0, 0, 0.76909], + "167": [0.19444, 0.69444, 0, 0, 0.44445], + "168": [0, 0.66786, 0, 0, 0.5], + "172": [0, 0.43056, 0, 0, 0.66667], + "176": [0, 0.69444, 0, 0, 0.75], + "177": [0.08333, 0.58333, 0, 0, 0.77778], + "182": [0.19444, 0.69444, 0, 0, 0.61111], + "184": [0.17014, 0, 0, 0, 0.44445], + "198": [0, 0.68333, 0, 0, 0.90278], + "215": [0.08333, 0.58333, 0, 0, 0.77778], + "216": [0.04861, 0.73194, 0, 0, 0.77778], + "223": [0, 0.69444, 0, 0, 0.5], + "230": [0, 0.43056, 0, 0, 0.72222], + "247": [0.08333, 0.58333, 0, 0, 0.77778], + "248": [0.09722, 0.52778, 0, 0, 0.5], + "305": [0, 0.43056, 0, 0, 0.27778], + "338": [0, 0.68333, 0, 0, 1.01389], + "339": [0, 0.43056, 0, 0, 0.77778], + "567": [0.19444, 0.43056, 0, 0, 0.30556], + "710": [0, 0.69444, 0, 0, 0.5], + "711": [0, 0.62847, 0, 0, 0.5], + "713": [0, 0.56778, 0, 0, 0.5], + "714": [0, 0.69444, 0, 0, 0.5], + "715": [0, 0.69444, 0, 0, 0.5], + "728": [0, 0.69444, 0, 0, 0.5], + "729": [0, 0.66786, 0, 0, 0.27778], + "730": [0, 0.69444, 0, 0, 0.75], + "732": [0, 0.66786, 0, 0, 0.5], + "733": [0, 0.69444, 0, 0, 0.5], + "915": [0, 0.68333, 0, 0, 0.625], + "916": [0, 0.68333, 0, 0, 0.83334], + "920": [0, 0.68333, 0, 0, 0.77778], + "923": [0, 0.68333, 0, 0, 0.69445], + "926": [0, 0.68333, 0, 0, 0.66667], + "928": [0, 0.68333, 0, 0, 0.75], + "931": [0, 0.68333, 0, 0, 0.72222], + "933": [0, 0.68333, 0, 0, 0.77778], + "934": [0, 0.68333, 0, 0, 0.72222], + "936": [0, 0.68333, 0, 0, 0.77778], + "937": [0, 0.68333, 0, 0, 0.72222], + "8211": [0, 0.43056, 0.02778, 0, 0.5], + "8212": [0, 0.43056, 0.02778, 0, 1.0], + "8216": [0, 0.69444, 0, 0, 0.27778], + "8217": [0, 0.69444, 0, 0, 0.27778], + "8220": [0, 0.69444, 0, 0, 0.5], + "8221": [0, 0.69444, 0, 0, 0.5], + "8224": [0.19444, 0.69444, 0, 0, 0.44445], + "8225": [0.19444, 0.69444, 0, 0, 0.44445], + "8230": [0, 0.123, 0, 0, 1.172], + "8242": [0, 0.55556, 0, 0, 0.275], + "8407": [0, 0.71444, 0.15382, 0, 0.5], + "8463": [0, 0.68889, 0, 0, 0.54028], + "8465": [0, 0.69444, 0, 0, 0.72222], + "8467": [0, 0.69444, 0, 0.11111, 0.41667], + "8472": [0.19444, 0.43056, 0, 0.11111, 0.63646], + "8476": [0, 0.69444, 0, 0, 0.72222], + "8501": [0, 0.69444, 0, 0, 0.61111], + "8592": [-0.13313, 0.36687, 0, 0, 1.0], + "8593": [0.19444, 0.69444, 0, 0, 0.5], + "8594": [-0.13313, 0.36687, 0, 0, 1.0], + "8595": [0.19444, 0.69444, 0, 0, 0.5], + "8596": [-0.13313, 0.36687, 0, 0, 1.0], + "8597": [0.25, 0.75, 0, 0, 0.5], + "8598": [0.19444, 0.69444, 0, 0, 1.0], + "8599": [0.19444, 0.69444, 0, 0, 1.0], + "8600": [0.19444, 0.69444, 0, 0, 1.0], + "8601": [0.19444, 0.69444, 0, 0, 1.0], + "8614": [0.011, 0.511, 0, 0, 1.0], + "8617": [0.011, 0.511, 0, 0, 1.126], + "8618": [0.011, 0.511, 0, 0, 1.126], + "8636": [-0.13313, 0.36687, 0, 0, 1.0], + "8637": [-0.13313, 0.36687, 0, 0, 1.0], + "8640": [-0.13313, 0.36687, 0, 0, 1.0], + "8641": [-0.13313, 0.36687, 0, 0, 1.0], + "8652": [0.011, 0.671, 0, 0, 1.0], + "8656": [-0.13313, 0.36687, 0, 0, 1.0], + "8657": [0.19444, 0.69444, 0, 0, 0.61111], + "8658": [-0.13313, 0.36687, 0, 0, 1.0], + "8659": [0.19444, 0.69444, 0, 0, 0.61111], + "8660": [-0.13313, 0.36687, 0, 0, 1.0], + "8661": [0.25, 0.75, 0, 0, 0.61111], + "8704": [0, 0.69444, 0, 0, 0.55556], + "8706": [0, 0.69444, 0.05556, 0.08334, 0.5309], + "8707": [0, 0.69444, 0, 0, 0.55556], + "8709": [0.05556, 0.75, 0, 0, 0.5], + "8711": [0, 0.68333, 0, 0, 0.83334], + "8712": [0.0391, 0.5391, 0, 0, 0.66667], + "8715": [0.0391, 0.5391, 0, 0, 0.66667], + "8722": [0.08333, 0.58333, 0, 0, 0.77778], + "8723": [0.08333, 0.58333, 0, 0, 0.77778], + "8725": [0.25, 0.75, 0, 0, 0.5], + "8726": [0.25, 0.75, 0, 0, 0.5], + "8727": [-0.03472, 0.46528, 0, 0, 0.5], + "8728": [-0.05555, 0.44445, 0, 0, 0.5], + "8729": [-0.05555, 0.44445, 0, 0, 0.5], + "8730": [0.2, 0.8, 0, 0, 0.83334], + "8733": [0, 0.43056, 0, 0, 0.77778], + "8734": [0, 0.43056, 0, 0, 1.0], + "8736": [0, 0.69224, 0, 0, 0.72222], + "8739": [0.25, 0.75, 0, 0, 0.27778], + "8741": [0.25, 0.75, 0, 0, 0.5], + "8743": [0, 0.55556, 0, 0, 0.66667], + "8744": [0, 0.55556, 0, 0, 0.66667], + "8745": [0, 0.55556, 0, 0, 0.66667], + "8746": [0, 0.55556, 0, 0, 0.66667], + "8747": [0.19444, 0.69444, 0.11111, 0, 0.41667], + "8764": [-0.13313, 0.36687, 0, 0, 0.77778], + "8768": [0.19444, 0.69444, 0, 0, 0.27778], + "8771": [-0.03625, 0.46375, 0, 0, 0.77778], + "8773": [-0.022, 0.589, 0, 0, 0.778], + "8776": [-0.01688, 0.48312, 0, 0, 0.77778], + "8781": [-0.03625, 0.46375, 0, 0, 0.77778], + "8784": [-0.133, 0.673, 0, 0, 0.778], + "8801": [-0.03625, 0.46375, 0, 0, 0.77778], + "8804": [0.13597, 0.63597, 0, 0, 0.77778], + "8805": [0.13597, 0.63597, 0, 0, 0.77778], + "8810": [0.0391, 0.5391, 0, 0, 1.0], + "8811": [0.0391, 0.5391, 0, 0, 1.0], + "8826": [0.0391, 0.5391, 0, 0, 0.77778], + "8827": [0.0391, 0.5391, 0, 0, 0.77778], + "8834": [0.0391, 0.5391, 0, 0, 0.77778], + "8835": [0.0391, 0.5391, 0, 0, 0.77778], + "8838": [0.13597, 0.63597, 0, 0, 0.77778], + "8839": [0.13597, 0.63597, 0, 0, 0.77778], + "8846": [0, 0.55556, 0, 0, 0.66667], + "8849": [0.13597, 0.63597, 0, 0, 0.77778], + "8850": [0.13597, 0.63597, 0, 0, 0.77778], + "8851": [0, 0.55556, 0, 0, 0.66667], + "8852": [0, 0.55556, 0, 0, 0.66667], + "8853": [0.08333, 0.58333, 0, 0, 0.77778], + "8854": [0.08333, 0.58333, 0, 0, 0.77778], + "8855": [0.08333, 0.58333, 0, 0, 0.77778], + "8856": [0.08333, 0.58333, 0, 0, 0.77778], + "8857": [0.08333, 0.58333, 0, 0, 0.77778], + "8866": [0, 0.69444, 0, 0, 0.61111], + "8867": [0, 0.69444, 0, 0, 0.61111], + "8868": [0, 0.69444, 0, 0, 0.77778], + "8869": [0, 0.69444, 0, 0, 0.77778], + "8872": [0.249, 0.75, 0, 0, 0.867], + "8900": [-0.05555, 0.44445, 0, 0, 0.5], + "8901": [-0.05555, 0.44445, 0, 0, 0.27778], + "8902": [-0.03472, 0.46528, 0, 0, 0.5], + "8904": [0.005, 0.505, 0, 0, 0.9], + "8942": [0.03, 0.903, 0, 0, 0.278], + "8943": [-0.19, 0.313, 0, 0, 1.172], + "8945": [-0.1, 0.823, 0, 0, 1.282], + "8968": [0.25, 0.75, 0, 0, 0.44445], + "8969": [0.25, 0.75, 0, 0, 0.44445], + "8970": [0.25, 0.75, 0, 0, 0.44445], + "8971": [0.25, 0.75, 0, 0, 0.44445], + "8994": [-0.14236, 0.35764, 0, 0, 1.0], + "8995": [-0.14236, 0.35764, 0, 0, 1.0], + "9136": [0.244, 0.744, 0, 0, 0.412], + "9137": [0.244, 0.745, 0, 0, 0.412], + "9651": [0.19444, 0.69444, 0, 0, 0.88889], + "9657": [-0.03472, 0.46528, 0, 0, 0.5], + "9661": [0.19444, 0.69444, 0, 0, 0.88889], + "9667": [-0.03472, 0.46528, 0, 0, 0.5], + "9711": [0.19444, 0.69444, 0, 0, 1.0], + "9824": [0.12963, 0.69444, 0, 0, 0.77778], + "9825": [0.12963, 0.69444, 0, 0, 0.77778], + "9826": [0.12963, 0.69444, 0, 0, 0.77778], + "9827": [0.12963, 0.69444, 0, 0, 0.77778], + "9837": [0, 0.75, 0, 0, 0.38889], + "9838": [0.19444, 0.69444, 0, 0, 0.38889], + "9839": [0.19444, 0.69444, 0, 0, 0.38889], + "10216": [0.25, 0.75, 0, 0, 0.38889], + "10217": [0.25, 0.75, 0, 0, 0.38889], + "10222": [0.244, 0.744, 0, 0, 0.412], + "10223": [0.244, 0.745, 0, 0, 0.412], + "10229": [0.011, 0.511, 0, 0, 1.609], + "10230": [0.011, 0.511, 0, 0, 1.638], + "10231": [0.011, 0.511, 0, 0, 1.859], + "10232": [0.024, 0.525, 0, 0, 1.609], + "10233": [0.024, 0.525, 0, 0, 1.638], + "10234": [0.024, 0.525, 0, 0, 1.858], + "10236": [0.011, 0.511, 0, 0, 1.638], + "10815": [0, 0.68333, 0, 0, 0.75], + "10927": [0.13597, 0.63597, 0, 0, 0.77778], + "10928": [0.13597, 0.63597, 0, 0, 0.77778], + "57376": [0.19444, 0.69444, 0, 0, 0] + }, + "Math-BoldItalic": { + "32": [0, 0, 0, 0, 0.25], + "48": [0, 0.44444, 0, 0, 0.575], + "49": [0, 0.44444, 0, 0, 0.575], + "50": [0, 0.44444, 0, 0, 0.575], + "51": [0.19444, 0.44444, 0, 0, 0.575], + "52": [0.19444, 0.44444, 0, 0, 0.575], + "53": [0.19444, 0.44444, 0, 0, 0.575], + "54": [0, 0.64444, 0, 0, 0.575], + "55": [0.19444, 0.44444, 0, 0, 0.575], + "56": [0, 0.64444, 0, 0, 0.575], + "57": [0.19444, 0.44444, 0, 0, 0.575], + "65": [0, 0.68611, 0, 0, 0.86944], + "66": [0, 0.68611, 0.04835, 0, 0.8664], + "67": [0, 0.68611, 0.06979, 0, 0.81694], + "68": [0, 0.68611, 0.03194, 0, 0.93812], + "69": [0, 0.68611, 0.05451, 0, 0.81007], + "70": [0, 0.68611, 0.15972, 0, 0.68889], + "71": [0, 0.68611, 0, 0, 0.88673], + "72": [0, 0.68611, 0.08229, 0, 0.98229], + "73": [0, 0.68611, 0.07778, 0, 0.51111], + "74": [0, 0.68611, 0.10069, 0, 0.63125], + "75": [0, 0.68611, 0.06979, 0, 0.97118], + "76": [0, 0.68611, 0, 0, 0.75555], + "77": [0, 0.68611, 0.11424, 0, 1.14201], + "78": [0, 0.68611, 0.11424, 0, 0.95034], + "79": [0, 0.68611, 0.03194, 0, 0.83666], + "80": [0, 0.68611, 0.15972, 0, 0.72309], + "81": [0.19444, 0.68611, 0, 0, 0.86861], + "82": [0, 0.68611, 0.00421, 0, 0.87235], + "83": [0, 0.68611, 0.05382, 0, 0.69271], + "84": [0, 0.68611, 0.15972, 0, 0.63663], + "85": [0, 0.68611, 0.11424, 0, 0.80027], + "86": [0, 0.68611, 0.25555, 0, 0.67778], + "87": [0, 0.68611, 0.15972, 0, 1.09305], + "88": [0, 0.68611, 0.07778, 0, 0.94722], + "89": [0, 0.68611, 0.25555, 0, 0.67458], + "90": [0, 0.68611, 0.06979, 0, 0.77257], + "97": [0, 0.44444, 0, 0, 0.63287], + "98": [0, 0.69444, 0, 0, 0.52083], + "99": [0, 0.44444, 0, 0, 0.51342], + "100": [0, 0.69444, 0, 0, 0.60972], + "101": [0, 0.44444, 0, 0, 0.55361], + "102": [0.19444, 0.69444, 0.11042, 0, 0.56806], + "103": [0.19444, 0.44444, 0.03704, 0, 0.5449], + "104": [0, 0.69444, 0, 0, 0.66759], + "105": [0, 0.69326, 0, 0, 0.4048], + "106": [0.19444, 0.69326, 0.0622, 0, 0.47083], + "107": [0, 0.69444, 0.01852, 0, 0.6037], + "108": [0, 0.69444, 0.0088, 0, 0.34815], + "109": [0, 0.44444, 0, 0, 1.0324], + "110": [0, 0.44444, 0, 0, 0.71296], + "111": [0, 0.44444, 0, 0, 0.58472], + "112": [0.19444, 0.44444, 0, 0, 0.60092], + "113": [0.19444, 0.44444, 0.03704, 0, 0.54213], + "114": [0, 0.44444, 0.03194, 0, 0.5287], + "115": [0, 0.44444, 0, 0, 0.53125], + "116": [0, 0.63492, 0, 0, 0.41528], + "117": [0, 0.44444, 0, 0, 0.68102], + "118": [0, 0.44444, 0.03704, 0, 0.56666], + "119": [0, 0.44444, 0.02778, 0, 0.83148], + "120": [0, 0.44444, 0, 0, 0.65903], + "121": [0.19444, 0.44444, 0.03704, 0, 0.59028], + "122": [0, 0.44444, 0.04213, 0, 0.55509], + "160": [0, 0, 0, 0, 0.25], + "915": [0, 0.68611, 0.15972, 0, 0.65694], + "916": [0, 0.68611, 0, 0, 0.95833], + "920": [0, 0.68611, 0.03194, 0, 0.86722], + "923": [0, 0.68611, 0, 0, 0.80555], + "926": [0, 0.68611, 0.07458, 0, 0.84125], + "928": [0, 0.68611, 0.08229, 0, 0.98229], + "931": [0, 0.68611, 0.05451, 0, 0.88507], + "933": [0, 0.68611, 0.15972, 0, 0.67083], + "934": [0, 0.68611, 0, 0, 0.76666], + "936": [0, 0.68611, 0.11653, 0, 0.71402], + "937": [0, 0.68611, 0.04835, 0, 0.8789], + "945": [0, 0.44444, 0, 0, 0.76064], + "946": [0.19444, 0.69444, 0.03403, 0, 0.65972], + "947": [0.19444, 0.44444, 0.06389, 0, 0.59003], + "948": [0, 0.69444, 0.03819, 0, 0.52222], + "949": [0, 0.44444, 0, 0, 0.52882], + "950": [0.19444, 0.69444, 0.06215, 0, 0.50833], + "951": [0.19444, 0.44444, 0.03704, 0, 0.6], + "952": [0, 0.69444, 0.03194, 0, 0.5618], + "953": [0, 0.44444, 0, 0, 0.41204], + "954": [0, 0.44444, 0, 0, 0.66759], + "955": [0, 0.69444, 0, 0, 0.67083], + "956": [0.19444, 0.44444, 0, 0, 0.70787], + "957": [0, 0.44444, 0.06898, 0, 0.57685], + "958": [0.19444, 0.69444, 0.03021, 0, 0.50833], + "959": [0, 0.44444, 0, 0, 0.58472], + "960": [0, 0.44444, 0.03704, 0, 0.68241], + "961": [0.19444, 0.44444, 0, 0, 0.6118], + "962": [0.09722, 0.44444, 0.07917, 0, 0.42361], + "963": [0, 0.44444, 0.03704, 0, 0.68588], + "964": [0, 0.44444, 0.13472, 0, 0.52083], + "965": [0, 0.44444, 0.03704, 0, 0.63055], + "966": [0.19444, 0.44444, 0, 0, 0.74722], + "967": [0.19444, 0.44444, 0, 0, 0.71805], + "968": [0.19444, 0.69444, 0.03704, 0, 0.75833], + "969": [0, 0.44444, 0.03704, 0, 0.71782], + "977": [0, 0.69444, 0, 0, 0.69155], + "981": [0.19444, 0.69444, 0, 0, 0.7125], + "982": [0, 0.44444, 0.03194, 0, 0.975], + "1009": [0.19444, 0.44444, 0, 0, 0.6118], + "1013": [0, 0.44444, 0, 0, 0.48333], + "57649": [0, 0.44444, 0, 0, 0.39352], + "57911": [0.19444, 0.44444, 0, 0, 0.43889] + }, + "Math-Italic": { + "32": [0, 0, 0, 0, 0.25], + "48": [0, 0.43056, 0, 0, 0.5], + "49": [0, 0.43056, 0, 0, 0.5], + "50": [0, 0.43056, 0, 0, 0.5], + "51": [0.19444, 0.43056, 0, 0, 0.5], + "52": [0.19444, 0.43056, 0, 0, 0.5], + "53": [0.19444, 0.43056, 0, 0, 0.5], + "54": [0, 0.64444, 0, 0, 0.5], + "55": [0.19444, 0.43056, 0, 0, 0.5], + "56": [0, 0.64444, 0, 0, 0.5], + "57": [0.19444, 0.43056, 0, 0, 0.5], + "65": [0, 0.68333, 0, 0.13889, 0.75], + "66": [0, 0.68333, 0.05017, 0.08334, 0.75851], + "67": [0, 0.68333, 0.07153, 0.08334, 0.71472], + "68": [0, 0.68333, 0.02778, 0.05556, 0.82792], + "69": [0, 0.68333, 0.05764, 0.08334, 0.7382], + "70": [0, 0.68333, 0.13889, 0.08334, 0.64306], + "71": [0, 0.68333, 0, 0.08334, 0.78625], + "72": [0, 0.68333, 0.08125, 0.05556, 0.83125], + "73": [0, 0.68333, 0.07847, 0.11111, 0.43958], + "74": [0, 0.68333, 0.09618, 0.16667, 0.55451], + "75": [0, 0.68333, 0.07153, 0.05556, 0.84931], + "76": [0, 0.68333, 0, 0.02778, 0.68056], + "77": [0, 0.68333, 0.10903, 0.08334, 0.97014], + "78": [0, 0.68333, 0.10903, 0.08334, 0.80347], + "79": [0, 0.68333, 0.02778, 0.08334, 0.76278], + "80": [0, 0.68333, 0.13889, 0.08334, 0.64201], + "81": [0.19444, 0.68333, 0, 0.08334, 0.79056], + "82": [0, 0.68333, 0.00773, 0.08334, 0.75929], + "83": [0, 0.68333, 0.05764, 0.08334, 0.6132], + "84": [0, 0.68333, 0.13889, 0.08334, 0.58438], + "85": [0, 0.68333, 0.10903, 0.02778, 0.68278], + "86": [0, 0.68333, 0.22222, 0, 0.58333], + "87": [0, 0.68333, 0.13889, 0, 0.94445], + "88": [0, 0.68333, 0.07847, 0.08334, 0.82847], + "89": [0, 0.68333, 0.22222, 0, 0.58056], + "90": [0, 0.68333, 0.07153, 0.08334, 0.68264], + "97": [0, 0.43056, 0, 0, 0.52859], + "98": [0, 0.69444, 0, 0, 0.42917], + "99": [0, 0.43056, 0, 0.05556, 0.43276], + "100": [0, 0.69444, 0, 0.16667, 0.52049], + "101": [0, 0.43056, 0, 0.05556, 0.46563], + "102": [0.19444, 0.69444, 0.10764, 0.16667, 0.48959], + "103": [0.19444, 0.43056, 0.03588, 0.02778, 0.47697], + "104": [0, 0.69444, 0, 0, 0.57616], + "105": [0, 0.65952, 0, 0, 0.34451], + "106": [0.19444, 0.65952, 0.05724, 0, 0.41181], + "107": [0, 0.69444, 0.03148, 0, 0.5206], + "108": [0, 0.69444, 0.01968, 0.08334, 0.29838], + "109": [0, 0.43056, 0, 0, 0.87801], + "110": [0, 0.43056, 0, 0, 0.60023], + "111": [0, 0.43056, 0, 0.05556, 0.48472], + "112": [0.19444, 0.43056, 0, 0.08334, 0.50313], + "113": [0.19444, 0.43056, 0.03588, 0.08334, 0.44641], + "114": [0, 0.43056, 0.02778, 0.05556, 0.45116], + "115": [0, 0.43056, 0, 0.05556, 0.46875], + "116": [0, 0.61508, 0, 0.08334, 0.36111], + "117": [0, 0.43056, 0, 0.02778, 0.57246], + "118": [0, 0.43056, 0.03588, 0.02778, 0.48472], + "119": [0, 0.43056, 0.02691, 0.08334, 0.71592], + "120": [0, 0.43056, 0, 0.02778, 0.57153], + "121": [0.19444, 0.43056, 0.03588, 0.05556, 0.49028], + "122": [0, 0.43056, 0.04398, 0.05556, 0.46505], + "160": [0, 0, 0, 0, 0.25], + "915": [0, 0.68333, 0.13889, 0.08334, 0.61528], + "916": [0, 0.68333, 0, 0.16667, 0.83334], + "920": [0, 0.68333, 0.02778, 0.08334, 0.76278], + "923": [0, 0.68333, 0, 0.16667, 0.69445], + "926": [0, 0.68333, 0.07569, 0.08334, 0.74236], + "928": [0, 0.68333, 0.08125, 0.05556, 0.83125], + "931": [0, 0.68333, 0.05764, 0.08334, 0.77986], + "933": [0, 0.68333, 0.13889, 0.05556, 0.58333], + "934": [0, 0.68333, 0, 0.08334, 0.66667], + "936": [0, 0.68333, 0.11, 0.05556, 0.61222], + "937": [0, 0.68333, 0.05017, 0.08334, 0.7724], + "945": [0, 0.43056, 0.0037, 0.02778, 0.6397], + "946": [0.19444, 0.69444, 0.05278, 0.08334, 0.56563], + "947": [0.19444, 0.43056, 0.05556, 0, 0.51773], + "948": [0, 0.69444, 0.03785, 0.05556, 0.44444], + "949": [0, 0.43056, 0, 0.08334, 0.46632], + "950": [0.19444, 0.69444, 0.07378, 0.08334, 0.4375], + "951": [0.19444, 0.43056, 0.03588, 0.05556, 0.49653], + "952": [0, 0.69444, 0.02778, 0.08334, 0.46944], + "953": [0, 0.43056, 0, 0.05556, 0.35394], + "954": [0, 0.43056, 0, 0, 0.57616], + "955": [0, 0.69444, 0, 0, 0.58334], + "956": [0.19444, 0.43056, 0, 0.02778, 0.60255], + "957": [0, 0.43056, 0.06366, 0.02778, 0.49398], + "958": [0.19444, 0.69444, 0.04601, 0.11111, 0.4375], + "959": [0, 0.43056, 0, 0.05556, 0.48472], + "960": [0, 0.43056, 0.03588, 0, 0.57003], + "961": [0.19444, 0.43056, 0, 0.08334, 0.51702], + "962": [0.09722, 0.43056, 0.07986, 0.08334, 0.36285], + "963": [0, 0.43056, 0.03588, 0, 0.57141], + "964": [0, 0.43056, 0.1132, 0.02778, 0.43715], + "965": [0, 0.43056, 0.03588, 0.02778, 0.54028], + "966": [0.19444, 0.43056, 0, 0.08334, 0.65417], + "967": [0.19444, 0.43056, 0, 0.05556, 0.62569], + "968": [0.19444, 0.69444, 0.03588, 0.11111, 0.65139], + "969": [0, 0.43056, 0.03588, 0, 0.62245], + "977": [0, 0.69444, 0, 0.08334, 0.59144], + "981": [0.19444, 0.69444, 0, 0.08334, 0.59583], + "982": [0, 0.43056, 0.02778, 0, 0.82813], + "1009": [0.19444, 0.43056, 0, 0.08334, 0.51702], + "1013": [0, 0.43056, 0, 0.05556, 0.4059], + "57649": [0, 0.43056, 0, 0.02778, 0.32246], + "57911": [0.19444, 0.43056, 0, 0.08334, 0.38403] + }, + "SansSerif-Bold": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.36667], + "34": [0, 0.69444, 0, 0, 0.55834], + "35": [0.19444, 0.69444, 0, 0, 0.91667], + "36": [0.05556, 0.75, 0, 0, 0.55], + "37": [0.05556, 0.75, 0, 0, 1.02912], + "38": [0, 0.69444, 0, 0, 0.83056], + "39": [0, 0.69444, 0, 0, 0.30556], + "40": [0.25, 0.75, 0, 0, 0.42778], + "41": [0.25, 0.75, 0, 0, 0.42778], + "42": [0, 0.75, 0, 0, 0.55], + "43": [0.11667, 0.61667, 0, 0, 0.85556], + "44": [0.10556, 0.13056, 0, 0, 0.30556], + "45": [0, 0.45833, 0, 0, 0.36667], + "46": [0, 0.13056, 0, 0, 0.30556], + "47": [0.25, 0.75, 0, 0, 0.55], + "48": [0, 0.69444, 0, 0, 0.55], + "49": [0, 0.69444, 0, 0, 0.55], + "50": [0, 0.69444, 0, 0, 0.55], + "51": [0, 0.69444, 0, 0, 0.55], + "52": [0, 0.69444, 0, 0, 0.55], + "53": [0, 0.69444, 0, 0, 0.55], + "54": [0, 0.69444, 0, 0, 0.55], + "55": [0, 0.69444, 0, 0, 0.55], + "56": [0, 0.69444, 0, 0, 0.55], + "57": [0, 0.69444, 0, 0, 0.55], + "58": [0, 0.45833, 0, 0, 0.30556], + "59": [0.10556, 0.45833, 0, 0, 0.30556], + "61": [-0.09375, 0.40625, 0, 0, 0.85556], + "63": [0, 0.69444, 0, 0, 0.51945], + "64": [0, 0.69444, 0, 0, 0.73334], + "65": [0, 0.69444, 0, 0, 0.73334], + "66": [0, 0.69444, 0, 0, 0.73334], + "67": [0, 0.69444, 0, 0, 0.70278], + "68": [0, 0.69444, 0, 0, 0.79445], + "69": [0, 0.69444, 0, 0, 0.64167], + "70": [0, 0.69444, 0, 0, 0.61111], + "71": [0, 0.69444, 0, 0, 0.73334], + "72": [0, 0.69444, 0, 0, 0.79445], + "73": [0, 0.69444, 0, 0, 0.33056], + "74": [0, 0.69444, 0, 0, 0.51945], + "75": [0, 0.69444, 0, 0, 0.76389], + "76": [0, 0.69444, 0, 0, 0.58056], + "77": [0, 0.69444, 0, 0, 0.97778], + "78": [0, 0.69444, 0, 0, 0.79445], + "79": [0, 0.69444, 0, 0, 0.79445], + "80": [0, 0.69444, 0, 0, 0.70278], + "81": [0.10556, 0.69444, 0, 0, 0.79445], + "82": [0, 0.69444, 0, 0, 0.70278], + "83": [0, 0.69444, 0, 0, 0.61111], + "84": [0, 0.69444, 0, 0, 0.73334], + "85": [0, 0.69444, 0, 0, 0.76389], + "86": [0, 0.69444, 0.01528, 0, 0.73334], + "87": [0, 0.69444, 0.01528, 0, 1.03889], + "88": [0, 0.69444, 0, 0, 0.73334], + "89": [0, 0.69444, 0.0275, 0, 0.73334], + "90": [0, 0.69444, 0, 0, 0.67223], + "91": [0.25, 0.75, 0, 0, 0.34306], + "93": [0.25, 0.75, 0, 0, 0.34306], + "94": [0, 0.69444, 0, 0, 0.55], + "95": [0.35, 0.10833, 0.03056, 0, 0.55], + "97": [0, 0.45833, 0, 0, 0.525], + "98": [0, 0.69444, 0, 0, 0.56111], + "99": [0, 0.45833, 0, 0, 0.48889], + "100": [0, 0.69444, 0, 0, 0.56111], + "101": [0, 0.45833, 0, 0, 0.51111], + "102": [0, 0.69444, 0.07639, 0, 0.33611], + "103": [0.19444, 0.45833, 0.01528, 0, 0.55], + "104": [0, 0.69444, 0, 0, 0.56111], + "105": [0, 0.69444, 0, 0, 0.25556], + "106": [0.19444, 0.69444, 0, 0, 0.28611], + "107": [0, 0.69444, 0, 0, 0.53056], + "108": [0, 0.69444, 0, 0, 0.25556], + "109": [0, 0.45833, 0, 0, 0.86667], + "110": [0, 0.45833, 0, 0, 0.56111], + "111": [0, 0.45833, 0, 0, 0.55], + "112": [0.19444, 0.45833, 0, 0, 0.56111], + "113": [0.19444, 0.45833, 0, 0, 0.56111], + "114": [0, 0.45833, 0.01528, 0, 0.37222], + "115": [0, 0.45833, 0, 0, 0.42167], + "116": [0, 0.58929, 0, 0, 0.40417], + "117": [0, 0.45833, 0, 0, 0.56111], + "118": [0, 0.45833, 0.01528, 0, 0.5], + "119": [0, 0.45833, 0.01528, 0, 0.74445], + "120": [0, 0.45833, 0, 0, 0.5], + "121": [0.19444, 0.45833, 0.01528, 0, 0.5], + "122": [0, 0.45833, 0, 0, 0.47639], + "126": [0.35, 0.34444, 0, 0, 0.55], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.69444, 0, 0, 0.55], + "176": [0, 0.69444, 0, 0, 0.73334], + "180": [0, 0.69444, 0, 0, 0.55], + "184": [0.17014, 0, 0, 0, 0.48889], + "305": [0, 0.45833, 0, 0, 0.25556], + "567": [0.19444, 0.45833, 0, 0, 0.28611], + "710": [0, 0.69444, 0, 0, 0.55], + "711": [0, 0.63542, 0, 0, 0.55], + "713": [0, 0.63778, 0, 0, 0.55], + "728": [0, 0.69444, 0, 0, 0.55], + "729": [0, 0.69444, 0, 0, 0.30556], + "730": [0, 0.69444, 0, 0, 0.73334], + "732": [0, 0.69444, 0, 0, 0.55], + "733": [0, 0.69444, 0, 0, 0.55], + "915": [0, 0.69444, 0, 0, 0.58056], + "916": [0, 0.69444, 0, 0, 0.91667], + "920": [0, 0.69444, 0, 0, 0.85556], + "923": [0, 0.69444, 0, 0, 0.67223], + "926": [0, 0.69444, 0, 0, 0.73334], + "928": [0, 0.69444, 0, 0, 0.79445], + "931": [0, 0.69444, 0, 0, 0.79445], + "933": [0, 0.69444, 0, 0, 0.85556], + "934": [0, 0.69444, 0, 0, 0.79445], + "936": [0, 0.69444, 0, 0, 0.85556], + "937": [0, 0.69444, 0, 0, 0.79445], + "8211": [0, 0.45833, 0.03056, 0, 0.55], + "8212": [0, 0.45833, 0.03056, 0, 1.10001], + "8216": [0, 0.69444, 0, 0, 0.30556], + "8217": [0, 0.69444, 0, 0, 0.30556], + "8220": [0, 0.69444, 0, 0, 0.55834], + "8221": [0, 0.69444, 0, 0, 0.55834] + }, + "SansSerif-Italic": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0.05733, 0, 0.31945], + "34": [0, 0.69444, 0.00316, 0, 0.5], + "35": [0.19444, 0.69444, 0.05087, 0, 0.83334], + "36": [0.05556, 0.75, 0.11156, 0, 0.5], + "37": [0.05556, 0.75, 0.03126, 0, 0.83334], + "38": [0, 0.69444, 0.03058, 0, 0.75834], + "39": [0, 0.69444, 0.07816, 0, 0.27778], + "40": [0.25, 0.75, 0.13164, 0, 0.38889], + "41": [0.25, 0.75, 0.02536, 0, 0.38889], + "42": [0, 0.75, 0.11775, 0, 0.5], + "43": [0.08333, 0.58333, 0.02536, 0, 0.77778], + "44": [0.125, 0.08333, 0, 0, 0.27778], + "45": [0, 0.44444, 0.01946, 0, 0.33333], + "46": [0, 0.08333, 0, 0, 0.27778], + "47": [0.25, 0.75, 0.13164, 0, 0.5], + "48": [0, 0.65556, 0.11156, 0, 0.5], + "49": [0, 0.65556, 0.11156, 0, 0.5], + "50": [0, 0.65556, 0.11156, 0, 0.5], + "51": [0, 0.65556, 0.11156, 0, 0.5], + "52": [0, 0.65556, 0.11156, 0, 0.5], + "53": [0, 0.65556, 0.11156, 0, 0.5], + "54": [0, 0.65556, 0.11156, 0, 0.5], + "55": [0, 0.65556, 0.11156, 0, 0.5], + "56": [0, 0.65556, 0.11156, 0, 0.5], + "57": [0, 0.65556, 0.11156, 0, 0.5], + "58": [0, 0.44444, 0.02502, 0, 0.27778], + "59": [0.125, 0.44444, 0.02502, 0, 0.27778], + "61": [-0.13, 0.37, 0.05087, 0, 0.77778], + "63": [0, 0.69444, 0.11809, 0, 0.47222], + "64": [0, 0.69444, 0.07555, 0, 0.66667], + "65": [0, 0.69444, 0, 0, 0.66667], + "66": [0, 0.69444, 0.08293, 0, 0.66667], + "67": [0, 0.69444, 0.11983, 0, 0.63889], + "68": [0, 0.69444, 0.07555, 0, 0.72223], + "69": [0, 0.69444, 0.11983, 0, 0.59722], + "70": [0, 0.69444, 0.13372, 0, 0.56945], + "71": [0, 0.69444, 0.11983, 0, 0.66667], + "72": [0, 0.69444, 0.08094, 0, 0.70834], + "73": [0, 0.69444, 0.13372, 0, 0.27778], + "74": [0, 0.69444, 0.08094, 0, 0.47222], + "75": [0, 0.69444, 0.11983, 0, 0.69445], + "76": [0, 0.69444, 0, 0, 0.54167], + "77": [0, 0.69444, 0.08094, 0, 0.875], + "78": [0, 0.69444, 0.08094, 0, 0.70834], + "79": [0, 0.69444, 0.07555, 0, 0.73611], + "80": [0, 0.69444, 0.08293, 0, 0.63889], + "81": [0.125, 0.69444, 0.07555, 0, 0.73611], + "82": [0, 0.69444, 0.08293, 0, 0.64584], + "83": [0, 0.69444, 0.09205, 0, 0.55556], + "84": [0, 0.69444, 0.13372, 0, 0.68056], + "85": [0, 0.69444, 0.08094, 0, 0.6875], + "86": [0, 0.69444, 0.1615, 0, 0.66667], + "87": [0, 0.69444, 0.1615, 0, 0.94445], + "88": [0, 0.69444, 0.13372, 0, 0.66667], + "89": [0, 0.69444, 0.17261, 0, 0.66667], + "90": [0, 0.69444, 0.11983, 0, 0.61111], + "91": [0.25, 0.75, 0.15942, 0, 0.28889], + "93": [0.25, 0.75, 0.08719, 0, 0.28889], + "94": [0, 0.69444, 0.0799, 0, 0.5], + "95": [0.35, 0.09444, 0.08616, 0, 0.5], + "97": [0, 0.44444, 0.00981, 0, 0.48056], + "98": [0, 0.69444, 0.03057, 0, 0.51667], + "99": [0, 0.44444, 0.08336, 0, 0.44445], + "100": [0, 0.69444, 0.09483, 0, 0.51667], + "101": [0, 0.44444, 0.06778, 0, 0.44445], + "102": [0, 0.69444, 0.21705, 0, 0.30556], + "103": [0.19444, 0.44444, 0.10836, 0, 0.5], + "104": [0, 0.69444, 0.01778, 0, 0.51667], + "105": [0, 0.67937, 0.09718, 0, 0.23889], + "106": [0.19444, 0.67937, 0.09162, 0, 0.26667], + "107": [0, 0.69444, 0.08336, 0, 0.48889], + "108": [0, 0.69444, 0.09483, 0, 0.23889], + "109": [0, 0.44444, 0.01778, 0, 0.79445], + "110": [0, 0.44444, 0.01778, 0, 0.51667], + "111": [0, 0.44444, 0.06613, 0, 0.5], + "112": [0.19444, 0.44444, 0.0389, 0, 0.51667], + "113": [0.19444, 0.44444, 0.04169, 0, 0.51667], + "114": [0, 0.44444, 0.10836, 0, 0.34167], + "115": [0, 0.44444, 0.0778, 0, 0.38333], + "116": [0, 0.57143, 0.07225, 0, 0.36111], + "117": [0, 0.44444, 0.04169, 0, 0.51667], + "118": [0, 0.44444, 0.10836, 0, 0.46111], + "119": [0, 0.44444, 0.10836, 0, 0.68334], + "120": [0, 0.44444, 0.09169, 0, 0.46111], + "121": [0.19444, 0.44444, 0.10836, 0, 0.46111], + "122": [0, 0.44444, 0.08752, 0, 0.43472], + "126": [0.35, 0.32659, 0.08826, 0, 0.5], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.67937, 0.06385, 0, 0.5], + "176": [0, 0.69444, 0, 0, 0.73752], + "184": [0.17014, 0, 0, 0, 0.44445], + "305": [0, 0.44444, 0.04169, 0, 0.23889], + "567": [0.19444, 0.44444, 0.04169, 0, 0.26667], + "710": [0, 0.69444, 0.0799, 0, 0.5], + "711": [0, 0.63194, 0.08432, 0, 0.5], + "713": [0, 0.60889, 0.08776, 0, 0.5], + "714": [0, 0.69444, 0.09205, 0, 0.5], + "715": [0, 0.69444, 0, 0, 0.5], + "728": [0, 0.69444, 0.09483, 0, 0.5], + "729": [0, 0.67937, 0.07774, 0, 0.27778], + "730": [0, 0.69444, 0, 0, 0.73752], + "732": [0, 0.67659, 0.08826, 0, 0.5], + "733": [0, 0.69444, 0.09205, 0, 0.5], + "915": [0, 0.69444, 0.13372, 0, 0.54167], + "916": [0, 0.69444, 0, 0, 0.83334], + "920": [0, 0.69444, 0.07555, 0, 0.77778], + "923": [0, 0.69444, 0, 0, 0.61111], + "926": [0, 0.69444, 0.12816, 0, 0.66667], + "928": [0, 0.69444, 0.08094, 0, 0.70834], + "931": [0, 0.69444, 0.11983, 0, 0.72222], + "933": [0, 0.69444, 0.09031, 0, 0.77778], + "934": [0, 0.69444, 0.04603, 0, 0.72222], + "936": [0, 0.69444, 0.09031, 0, 0.77778], + "937": [0, 0.69444, 0.08293, 0, 0.72222], + "8211": [0, 0.44444, 0.08616, 0, 0.5], + "8212": [0, 0.44444, 0.08616, 0, 1.0], + "8216": [0, 0.69444, 0.07816, 0, 0.27778], + "8217": [0, 0.69444, 0.07816, 0, 0.27778], + "8220": [0, 0.69444, 0.14205, 0, 0.5], + "8221": [0, 0.69444, 0.00316, 0, 0.5] + }, + "SansSerif-Regular": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.31945], + "34": [0, 0.69444, 0, 0, 0.5], + "35": [0.19444, 0.69444, 0, 0, 0.83334], + "36": [0.05556, 0.75, 0, 0, 0.5], + "37": [0.05556, 0.75, 0, 0, 0.83334], + "38": [0, 0.69444, 0, 0, 0.75834], + "39": [0, 0.69444, 0, 0, 0.27778], + "40": [0.25, 0.75, 0, 0, 0.38889], + "41": [0.25, 0.75, 0, 0, 0.38889], + "42": [0, 0.75, 0, 0, 0.5], + "43": [0.08333, 0.58333, 0, 0, 0.77778], + "44": [0.125, 0.08333, 0, 0, 0.27778], + "45": [0, 0.44444, 0, 0, 0.33333], + "46": [0, 0.08333, 0, 0, 0.27778], + "47": [0.25, 0.75, 0, 0, 0.5], + "48": [0, 0.65556, 0, 0, 0.5], + "49": [0, 0.65556, 0, 0, 0.5], + "50": [0, 0.65556, 0, 0, 0.5], + "51": [0, 0.65556, 0, 0, 0.5], + "52": [0, 0.65556, 0, 0, 0.5], + "53": [0, 0.65556, 0, 0, 0.5], + "54": [0, 0.65556, 0, 0, 0.5], + "55": [0, 0.65556, 0, 0, 0.5], + "56": [0, 0.65556, 0, 0, 0.5], + "57": [0, 0.65556, 0, 0, 0.5], + "58": [0, 0.44444, 0, 0, 0.27778], + "59": [0.125, 0.44444, 0, 0, 0.27778], + "61": [-0.13, 0.37, 0, 0, 0.77778], + "63": [0, 0.69444, 0, 0, 0.47222], + "64": [0, 0.69444, 0, 0, 0.66667], + "65": [0, 0.69444, 0, 0, 0.66667], + "66": [0, 0.69444, 0, 0, 0.66667], + "67": [0, 0.69444, 0, 0, 0.63889], + "68": [0, 0.69444, 0, 0, 0.72223], + "69": [0, 0.69444, 0, 0, 0.59722], + "70": [0, 0.69444, 0, 0, 0.56945], + "71": [0, 0.69444, 0, 0, 0.66667], + "72": [0, 0.69444, 0, 0, 0.70834], + "73": [0, 0.69444, 0, 0, 0.27778], + "74": [0, 0.69444, 0, 0, 0.47222], + "75": [0, 0.69444, 0, 0, 0.69445], + "76": [0, 0.69444, 0, 0, 0.54167], + "77": [0, 0.69444, 0, 0, 0.875], + "78": [0, 0.69444, 0, 0, 0.70834], + "79": [0, 0.69444, 0, 0, 0.73611], + "80": [0, 0.69444, 0, 0, 0.63889], + "81": [0.125, 0.69444, 0, 0, 0.73611], + "82": [0, 0.69444, 0, 0, 0.64584], + "83": [0, 0.69444, 0, 0, 0.55556], + "84": [0, 0.69444, 0, 0, 0.68056], + "85": [0, 0.69444, 0, 0, 0.6875], + "86": [0, 0.69444, 0.01389, 0, 0.66667], + "87": [0, 0.69444, 0.01389, 0, 0.94445], + "88": [0, 0.69444, 0, 0, 0.66667], + "89": [0, 0.69444, 0.025, 0, 0.66667], + "90": [0, 0.69444, 0, 0, 0.61111], + "91": [0.25, 0.75, 0, 0, 0.28889], + "93": [0.25, 0.75, 0, 0, 0.28889], + "94": [0, 0.69444, 0, 0, 0.5], + "95": [0.35, 0.09444, 0.02778, 0, 0.5], + "97": [0, 0.44444, 0, 0, 0.48056], + "98": [0, 0.69444, 0, 0, 0.51667], + "99": [0, 0.44444, 0, 0, 0.44445], + "100": [0, 0.69444, 0, 0, 0.51667], + "101": [0, 0.44444, 0, 0, 0.44445], + "102": [0, 0.69444, 0.06944, 0, 0.30556], + "103": [0.19444, 0.44444, 0.01389, 0, 0.5], + "104": [0, 0.69444, 0, 0, 0.51667], + "105": [0, 0.67937, 0, 0, 0.23889], + "106": [0.19444, 0.67937, 0, 0, 0.26667], + "107": [0, 0.69444, 0, 0, 0.48889], + "108": [0, 0.69444, 0, 0, 0.23889], + "109": [0, 0.44444, 0, 0, 0.79445], + "110": [0, 0.44444, 0, 0, 0.51667], + "111": [0, 0.44444, 0, 0, 0.5], + "112": [0.19444, 0.44444, 0, 0, 0.51667], + "113": [0.19444, 0.44444, 0, 0, 0.51667], + "114": [0, 0.44444, 0.01389, 0, 0.34167], + "115": [0, 0.44444, 0, 0, 0.38333], + "116": [0, 0.57143, 0, 0, 0.36111], + "117": [0, 0.44444, 0, 0, 0.51667], + "118": [0, 0.44444, 0.01389, 0, 0.46111], + "119": [0, 0.44444, 0.01389, 0, 0.68334], + "120": [0, 0.44444, 0, 0, 0.46111], + "121": [0.19444, 0.44444, 0.01389, 0, 0.46111], + "122": [0, 0.44444, 0, 0, 0.43472], + "126": [0.35, 0.32659, 0, 0, 0.5], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.67937, 0, 0, 0.5], + "176": [0, 0.69444, 0, 0, 0.66667], + "184": [0.17014, 0, 0, 0, 0.44445], + "305": [0, 0.44444, 0, 0, 0.23889], + "567": [0.19444, 0.44444, 0, 0, 0.26667], + "710": [0, 0.69444, 0, 0, 0.5], + "711": [0, 0.63194, 0, 0, 0.5], + "713": [0, 0.60889, 0, 0, 0.5], + "714": [0, 0.69444, 0, 0, 0.5], + "715": [0, 0.69444, 0, 0, 0.5], + "728": [0, 0.69444, 0, 0, 0.5], + "729": [0, 0.67937, 0, 0, 0.27778], + "730": [0, 0.69444, 0, 0, 0.66667], + "732": [0, 0.67659, 0, 0, 0.5], + "733": [0, 0.69444, 0, 0, 0.5], + "915": [0, 0.69444, 0, 0, 0.54167], + "916": [0, 0.69444, 0, 0, 0.83334], + "920": [0, 0.69444, 0, 0, 0.77778], + "923": [0, 0.69444, 0, 0, 0.61111], + "926": [0, 0.69444, 0, 0, 0.66667], + "928": [0, 0.69444, 0, 0, 0.70834], + "931": [0, 0.69444, 0, 0, 0.72222], + "933": [0, 0.69444, 0, 0, 0.77778], + "934": [0, 0.69444, 0, 0, 0.72222], + "936": [0, 0.69444, 0, 0, 0.77778], + "937": [0, 0.69444, 0, 0, 0.72222], + "8211": [0, 0.44444, 0.02778, 0, 0.5], + "8212": [0, 0.44444, 0.02778, 0, 1.0], + "8216": [0, 0.69444, 0, 0, 0.27778], + "8217": [0, 0.69444, 0, 0, 0.27778], + "8220": [0, 0.69444, 0, 0, 0.5], + "8221": [0, 0.69444, 0, 0, 0.5] + }, + "Script-Regular": { + "32": [0, 0, 0, 0, 0.25], + "65": [0, 0.7, 0.22925, 0, 0.80253], + "66": [0, 0.7, 0.04087, 0, 0.90757], + "67": [0, 0.7, 0.1689, 0, 0.66619], + "68": [0, 0.7, 0.09371, 0, 0.77443], + "69": [0, 0.7, 0.18583, 0, 0.56162], + "70": [0, 0.7, 0.13634, 0, 0.89544], + "71": [0, 0.7, 0.17322, 0, 0.60961], + "72": [0, 0.7, 0.29694, 0, 0.96919], + "73": [0, 0.7, 0.19189, 0, 0.80907], + "74": [0.27778, 0.7, 0.19189, 0, 1.05159], + "75": [0, 0.7, 0.31259, 0, 0.91364], + "76": [0, 0.7, 0.19189, 0, 0.87373], + "77": [0, 0.7, 0.15981, 0, 1.08031], + "78": [0, 0.7, 0.3525, 0, 0.9015], + "79": [0, 0.7, 0.08078, 0, 0.73787], + "80": [0, 0.7, 0.08078, 0, 1.01262], + "81": [0, 0.7, 0.03305, 0, 0.88282], + "82": [0, 0.7, 0.06259, 0, 0.85], + "83": [0, 0.7, 0.19189, 0, 0.86767], + "84": [0, 0.7, 0.29087, 0, 0.74697], + "85": [0, 0.7, 0.25815, 0, 0.79996], + "86": [0, 0.7, 0.27523, 0, 0.62204], + "87": [0, 0.7, 0.27523, 0, 0.80532], + "88": [0, 0.7, 0.26006, 0, 0.94445], + "89": [0, 0.7, 0.2939, 0, 0.70961], + "90": [0, 0.7, 0.24037, 0, 0.8212], + "160": [0, 0, 0, 0, 0.25] + }, + "Size1-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [0.35001, 0.85, 0, 0, 0.45834], + "41": [0.35001, 0.85, 0, 0, 0.45834], + "47": [0.35001, 0.85, 0, 0, 0.57778], + "91": [0.35001, 0.85, 0, 0, 0.41667], + "92": [0.35001, 0.85, 0, 0, 0.57778], + "93": [0.35001, 0.85, 0, 0, 0.41667], + "123": [0.35001, 0.85, 0, 0, 0.58334], + "125": [0.35001, 0.85, 0, 0, 0.58334], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.72222, 0, 0, 0.55556], + "732": [0, 0.72222, 0, 0, 0.55556], + "770": [0, 0.72222, 0, 0, 0.55556], + "771": [0, 0.72222, 0, 0, 0.55556], + "8214": [-0.00099, 0.601, 0, 0, 0.77778], + "8593": [1e-05, 0.6, 0, 0, 0.66667], + "8595": [1e-05, 0.6, 0, 0, 0.66667], + "8657": [1e-05, 0.6, 0, 0, 0.77778], + "8659": [1e-05, 0.6, 0, 0, 0.77778], + "8719": [0.25001, 0.75, 0, 0, 0.94445], + "8720": [0.25001, 0.75, 0, 0, 0.94445], + "8721": [0.25001, 0.75, 0, 0, 1.05556], + "8730": [0.35001, 0.85, 0, 0, 1.0], + "8739": [-0.00599, 0.606, 0, 0, 0.33333], + "8741": [-0.00599, 0.606, 0, 0, 0.55556], + "8747": [0.30612, 0.805, 0.19445, 0, 0.47222], + "8748": [0.306, 0.805, 0.19445, 0, 0.47222], + "8749": [0.306, 0.805, 0.19445, 0, 0.47222], + "8750": [0.30612, 0.805, 0.19445, 0, 0.47222], + "8896": [0.25001, 0.75, 0, 0, 0.83334], + "8897": [0.25001, 0.75, 0, 0, 0.83334], + "8898": [0.25001, 0.75, 0, 0, 0.83334], + "8899": [0.25001, 0.75, 0, 0, 0.83334], + "8968": [0.35001, 0.85, 0, 0, 0.47222], + "8969": [0.35001, 0.85, 0, 0, 0.47222], + "8970": [0.35001, 0.85, 0, 0, 0.47222], + "8971": [0.35001, 0.85, 0, 0, 0.47222], + "9168": [-0.00099, 0.601, 0, 0, 0.66667], + "10216": [0.35001, 0.85, 0, 0, 0.47222], + "10217": [0.35001, 0.85, 0, 0, 0.47222], + "10752": [0.25001, 0.75, 0, 0, 1.11111], + "10753": [0.25001, 0.75, 0, 0, 1.11111], + "10754": [0.25001, 0.75, 0, 0, 1.11111], + "10756": [0.25001, 0.75, 0, 0, 0.83334], + "10758": [0.25001, 0.75, 0, 0, 0.83334] + }, + "Size2-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [0.65002, 1.15, 0, 0, 0.59722], + "41": [0.65002, 1.15, 0, 0, 0.59722], + "47": [0.65002, 1.15, 0, 0, 0.81111], + "91": [0.65002, 1.15, 0, 0, 0.47222], + "92": [0.65002, 1.15, 0, 0, 0.81111], + "93": [0.65002, 1.15, 0, 0, 0.47222], + "123": [0.65002, 1.15, 0, 0, 0.66667], + "125": [0.65002, 1.15, 0, 0, 0.66667], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.75, 0, 0, 1.0], + "732": [0, 0.75, 0, 0, 1.0], + "770": [0, 0.75, 0, 0, 1.0], + "771": [0, 0.75, 0, 0, 1.0], + "8719": [0.55001, 1.05, 0, 0, 1.27778], + "8720": [0.55001, 1.05, 0, 0, 1.27778], + "8721": [0.55001, 1.05, 0, 0, 1.44445], + "8730": [0.65002, 1.15, 0, 0, 1.0], + "8747": [0.86225, 1.36, 0.44445, 0, 0.55556], + "8748": [0.862, 1.36, 0.44445, 0, 0.55556], + "8749": [0.862, 1.36, 0.44445, 0, 0.55556], + "8750": [0.86225, 1.36, 0.44445, 0, 0.55556], + "8896": [0.55001, 1.05, 0, 0, 1.11111], + "8897": [0.55001, 1.05, 0, 0, 1.11111], + "8898": [0.55001, 1.05, 0, 0, 1.11111], + "8899": [0.55001, 1.05, 0, 0, 1.11111], + "8968": [0.65002, 1.15, 0, 0, 0.52778], + "8969": [0.65002, 1.15, 0, 0, 0.52778], + "8970": [0.65002, 1.15, 0, 0, 0.52778], + "8971": [0.65002, 1.15, 0, 0, 0.52778], + "10216": [0.65002, 1.15, 0, 0, 0.61111], + "10217": [0.65002, 1.15, 0, 0, 0.61111], + "10752": [0.55001, 1.05, 0, 0, 1.51112], + "10753": [0.55001, 1.05, 0, 0, 1.51112], + "10754": [0.55001, 1.05, 0, 0, 1.51112], + "10756": [0.55001, 1.05, 0, 0, 1.11111], + "10758": [0.55001, 1.05, 0, 0, 1.11111] + }, + "Size3-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [0.95003, 1.45, 0, 0, 0.73611], + "41": [0.95003, 1.45, 0, 0, 0.73611], + "47": [0.95003, 1.45, 0, 0, 1.04445], + "91": [0.95003, 1.45, 0, 0, 0.52778], + "92": [0.95003, 1.45, 0, 0, 1.04445], + "93": [0.95003, 1.45, 0, 0, 0.52778], + "123": [0.95003, 1.45, 0, 0, 0.75], + "125": [0.95003, 1.45, 0, 0, 0.75], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.75, 0, 0, 1.44445], + "732": [0, 0.75, 0, 0, 1.44445], + "770": [0, 0.75, 0, 0, 1.44445], + "771": [0, 0.75, 0, 0, 1.44445], + "8730": [0.95003, 1.45, 0, 0, 1.0], + "8968": [0.95003, 1.45, 0, 0, 0.58334], + "8969": [0.95003, 1.45, 0, 0, 0.58334], + "8970": [0.95003, 1.45, 0, 0, 0.58334], + "8971": [0.95003, 1.45, 0, 0, 0.58334], + "10216": [0.95003, 1.45, 0, 0, 0.75], + "10217": [0.95003, 1.45, 0, 0, 0.75] + }, + "Size4-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [1.25003, 1.75, 0, 0, 0.79167], + "41": [1.25003, 1.75, 0, 0, 0.79167], + "47": [1.25003, 1.75, 0, 0, 1.27778], + "91": [1.25003, 1.75, 0, 0, 0.58334], + "92": [1.25003, 1.75, 0, 0, 1.27778], + "93": [1.25003, 1.75, 0, 0, 0.58334], + "123": [1.25003, 1.75, 0, 0, 0.80556], + "125": [1.25003, 1.75, 0, 0, 0.80556], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.825, 0, 0, 1.8889], + "732": [0, 0.825, 0, 0, 1.8889], + "770": [0, 0.825, 0, 0, 1.8889], + "771": [0, 0.825, 0, 0, 1.8889], + "8730": [1.25003, 1.75, 0, 0, 1.0], + "8968": [1.25003, 1.75, 0, 0, 0.63889], + "8969": [1.25003, 1.75, 0, 0, 0.63889], + "8970": [1.25003, 1.75, 0, 0, 0.63889], + "8971": [1.25003, 1.75, 0, 0, 0.63889], + "9115": [0.64502, 1.155, 0, 0, 0.875], + "9116": [1e-05, 0.6, 0, 0, 0.875], + "9117": [0.64502, 1.155, 0, 0, 0.875], + "9118": [0.64502, 1.155, 0, 0, 0.875], + "9119": [1e-05, 0.6, 0, 0, 0.875], + "9120": [0.64502, 1.155, 0, 0, 0.875], + "9121": [0.64502, 1.155, 0, 0, 0.66667], + "9122": [-0.00099, 0.601, 0, 0, 0.66667], + "9123": [0.64502, 1.155, 0, 0, 0.66667], + "9124": [0.64502, 1.155, 0, 0, 0.66667], + "9125": [-0.00099, 0.601, 0, 0, 0.66667], + "9126": [0.64502, 1.155, 0, 0, 0.66667], + "9127": [1e-05, 0.9, 0, 0, 0.88889], + "9128": [0.65002, 1.15, 0, 0, 0.88889], + "9129": [0.90001, 0, 0, 0, 0.88889], + "9130": [0, 0.3, 0, 0, 0.88889], + "9131": [1e-05, 0.9, 0, 0, 0.88889], + "9132": [0.65002, 1.15, 0, 0, 0.88889], + "9133": [0.90001, 0, 0, 0, 0.88889], + "9143": [0.88502, 0.915, 0, 0, 1.05556], + "10216": [1.25003, 1.75, 0, 0, 0.80556], + "10217": [1.25003, 1.75, 0, 0, 0.80556], + "57344": [-0.00499, 0.605, 0, 0, 1.05556], + "57345": [-0.00499, 0.605, 0, 0, 1.05556], + "57680": [0, 0.12, 0, 0, 0.45], + "57681": [0, 0.12, 0, 0, 0.45], + "57682": [0, 0.12, 0, 0, 0.45], + "57683": [0, 0.12, 0, 0, 0.45] + }, + "Typewriter-Regular": { + "32": [0, 0, 0, 0, 0.525], + "33": [0, 0.61111, 0, 0, 0.525], + "34": [0, 0.61111, 0, 0, 0.525], + "35": [0, 0.61111, 0, 0, 0.525], + "36": [0.08333, 0.69444, 0, 0, 0.525], + "37": [0.08333, 0.69444, 0, 0, 0.525], + "38": [0, 0.61111, 0, 0, 0.525], + "39": [0, 0.61111, 0, 0, 0.525], + "40": [0.08333, 0.69444, 0, 0, 0.525], + "41": [0.08333, 0.69444, 0, 0, 0.525], + "42": [0, 0.52083, 0, 0, 0.525], + "43": [-0.08056, 0.53055, 0, 0, 0.525], + "44": [0.13889, 0.125, 0, 0, 0.525], + "45": [-0.08056, 0.53055, 0, 0, 0.525], + "46": [0, 0.125, 0, 0, 0.525], + "47": [0.08333, 0.69444, 0, 0, 0.525], + "48": [0, 0.61111, 0, 0, 0.525], + "49": [0, 0.61111, 0, 0, 0.525], + "50": [0, 0.61111, 0, 0, 0.525], + "51": [0, 0.61111, 0, 0, 0.525], + "52": [0, 0.61111, 0, 0, 0.525], + "53": [0, 0.61111, 0, 0, 0.525], + "54": [0, 0.61111, 0, 0, 0.525], + "55": [0, 0.61111, 0, 0, 0.525], + "56": [0, 0.61111, 0, 0, 0.525], + "57": [0, 0.61111, 0, 0, 0.525], + "58": [0, 0.43056, 0, 0, 0.525], + "59": [0.13889, 0.43056, 0, 0, 0.525], + "60": [-0.05556, 0.55556, 0, 0, 0.525], + "61": [-0.19549, 0.41562, 0, 0, 0.525], + "62": [-0.05556, 0.55556, 0, 0, 0.525], + "63": [0, 0.61111, 0, 0, 0.525], + "64": [0, 0.61111, 0, 0, 0.525], + "65": [0, 0.61111, 0, 0, 0.525], + "66": [0, 0.61111, 0, 0, 0.525], + "67": [0, 0.61111, 0, 0, 0.525], + "68": [0, 0.61111, 0, 0, 0.525], + "69": [0, 0.61111, 0, 0, 0.525], + "70": [0, 0.61111, 0, 0, 0.525], + "71": [0, 0.61111, 0, 0, 0.525], + "72": [0, 0.61111, 0, 0, 0.525], + "73": [0, 0.61111, 0, 0, 0.525], + "74": [0, 0.61111, 0, 0, 0.525], + "75": [0, 0.61111, 0, 0, 0.525], + "76": [0, 0.61111, 0, 0, 0.525], + "77": [0, 0.61111, 0, 0, 0.525], + "78": [0, 0.61111, 0, 0, 0.525], + "79": [0, 0.61111, 0, 0, 0.525], + "80": [0, 0.61111, 0, 0, 0.525], + "81": [0.13889, 0.61111, 0, 0, 0.525], + "82": [0, 0.61111, 0, 0, 0.525], + "83": [0, 0.61111, 0, 0, 0.525], + "84": [0, 0.61111, 0, 0, 0.525], + "85": [0, 0.61111, 0, 0, 0.525], + "86": [0, 0.61111, 0, 0, 0.525], + "87": [0, 0.61111, 0, 0, 0.525], + "88": [0, 0.61111, 0, 0, 0.525], + "89": [0, 0.61111, 0, 0, 0.525], + "90": [0, 0.61111, 0, 0, 0.525], + "91": [0.08333, 0.69444, 0, 0, 0.525], + "92": [0.08333, 0.69444, 0, 0, 0.525], + "93": [0.08333, 0.69444, 0, 0, 0.525], + "94": [0, 0.61111, 0, 0, 0.525], + "95": [0.09514, 0, 0, 0, 0.525], + "96": [0, 0.61111, 0, 0, 0.525], + "97": [0, 0.43056, 0, 0, 0.525], + "98": [0, 0.61111, 0, 0, 0.525], + "99": [0, 0.43056, 0, 0, 0.525], + "100": [0, 0.61111, 0, 0, 0.525], + "101": [0, 0.43056, 0, 0, 0.525], + "102": [0, 0.61111, 0, 0, 0.525], + "103": [0.22222, 0.43056, 0, 0, 0.525], + "104": [0, 0.61111, 0, 0, 0.525], + "105": [0, 0.61111, 0, 0, 0.525], + "106": [0.22222, 0.61111, 0, 0, 0.525], + "107": [0, 0.61111, 0, 0, 0.525], + "108": [0, 0.61111, 0, 0, 0.525], + "109": [0, 0.43056, 0, 0, 0.525], + "110": [0, 0.43056, 0, 0, 0.525], + "111": [0, 0.43056, 0, 0, 0.525], + "112": [0.22222, 0.43056, 0, 0, 0.525], + "113": [0.22222, 0.43056, 0, 0, 0.525], + "114": [0, 0.43056, 0, 0, 0.525], + "115": [0, 0.43056, 0, 0, 0.525], + "116": [0, 0.55358, 0, 0, 0.525], + "117": [0, 0.43056, 0, 0, 0.525], + "118": [0, 0.43056, 0, 0, 0.525], + "119": [0, 0.43056, 0, 0, 0.525], + "120": [0, 0.43056, 0, 0, 0.525], + "121": [0.22222, 0.43056, 0, 0, 0.525], + "122": [0, 0.43056, 0, 0, 0.525], + "123": [0.08333, 0.69444, 0, 0, 0.525], + "124": [0.08333, 0.69444, 0, 0, 0.525], + "125": [0.08333, 0.69444, 0, 0, 0.525], + "126": [0, 0.61111, 0, 0, 0.525], + "127": [0, 0.61111, 0, 0, 0.525], + "160": [0, 0, 0, 0, 0.525], + "176": [0, 0.61111, 0, 0, 0.525], + "184": [0.19445, 0, 0, 0, 0.525], + "305": [0, 0.43056, 0, 0, 0.525], + "567": [0.22222, 0.43056, 0, 0, 0.525], + "711": [0, 0.56597, 0, 0, 0.525], + "713": [0, 0.56555, 0, 0, 0.525], + "714": [0, 0.61111, 0, 0, 0.525], + "715": [0, 0.61111, 0, 0, 0.525], + "728": [0, 0.61111, 0, 0, 0.525], + "730": [0, 0.61111, 0, 0, 0.525], + "770": [0, 0.61111, 0, 0, 0.525], + "771": [0, 0.61111, 0, 0, 0.525], + "776": [0, 0.61111, 0, 0, 0.525], + "915": [0, 0.61111, 0, 0, 0.525], + "916": [0, 0.61111, 0, 0, 0.525], + "920": [0, 0.61111, 0, 0, 0.525], + "923": [0, 0.61111, 0, 0, 0.525], + "926": [0, 0.61111, 0, 0, 0.525], + "928": [0, 0.61111, 0, 0, 0.525], + "931": [0, 0.61111, 0, 0, 0.525], + "933": [0, 0.61111, 0, 0, 0.525], + "934": [0, 0.61111, 0, 0, 0.525], + "936": [0, 0.61111, 0, 0, 0.525], + "937": [0, 0.61111, 0, 0, 0.525], + "8216": [0, 0.61111, 0, 0, 0.525], + "8217": [0, 0.61111, 0, 0, 0.525], + "8242": [0, 0.61111, 0, 0, 0.525], + "9251": [0.11111, 0.21944, 0, 0, 0.525] + } +}); + + +/** + * This file contains metrics regarding fonts and individual symbols. The sigma + * and xi variables, as well as the metricMap map contain data extracted from + * TeX, TeX font metrics, and the TTF files. These data are then exposed via the + * `metrics` variable and the getCharacterMetrics function. + */ +// In TeX, there are actually three sets of dimensions, one for each of +// textstyle (size index 5 and higher: >=9pt), scriptstyle (size index 3 and 4: +// 7-8pt), and scriptscriptstyle (size index 1 and 2: 5-6pt). These are +// provided in the the arrays below, in that order. +// +// The font metrics are stored in fonts cmsy10, cmsy7, and cmsy5 respsectively. +// This was determined by running the following script: +// +// latex -interaction=nonstopmode \ +// '\documentclass{article}\usepackage{amsmath}\begin{document}' \ +// '$a$ \expandafter\show\the\textfont2' \ +// '\expandafter\show\the\scriptfont2' \ +// '\expandafter\show\the\scriptscriptfont2' \ +// '\stop' +// +// The metrics themselves were retreived using the following commands: +// +// tftopl cmsy10 +// tftopl cmsy7 +// tftopl cmsy5 +// +// The output of each of these commands is quite lengthy. The only part we +// care about is the FONTDIMEN section. Each value is measured in EMs. +var sigmasAndXis = { + slant: [0.250, 0.250, 0.250], + // sigma1 + space: [0.000, 0.000, 0.000], + // sigma2 + stretch: [0.000, 0.000, 0.000], + // sigma3 + shrink: [0.000, 0.000, 0.000], + // sigma4 + xHeight: [0.431, 0.431, 0.431], + // sigma5 + quad: [1.000, 1.171, 1.472], + // sigma6 + extraSpace: [0.000, 0.000, 0.000], + // sigma7 + num1: [0.677, 0.732, 0.925], + // sigma8 + num2: [0.394, 0.384, 0.387], + // sigma9 + num3: [0.444, 0.471, 0.504], + // sigma10 + denom1: [0.686, 0.752, 1.025], + // sigma11 + denom2: [0.345, 0.344, 0.532], + // sigma12 + sup1: [0.413, 0.503, 0.504], + // sigma13 + sup2: [0.363, 0.431, 0.404], + // sigma14 + sup3: [0.289, 0.286, 0.294], + // sigma15 + sub1: [0.150, 0.143, 0.200], + // sigma16 + sub2: [0.247, 0.286, 0.400], + // sigma17 + supDrop: [0.386, 0.353, 0.494], + // sigma18 + subDrop: [0.050, 0.071, 0.100], + // sigma19 + delim1: [2.390, 1.700, 1.980], + // sigma20 + delim2: [1.010, 1.157, 1.420], + // sigma21 + axisHeight: [0.250, 0.250, 0.250], + // sigma22 + // These font metrics are extracted from TeX by using tftopl on cmex10.tfm; + // they correspond to the font parameters of the extension fonts (family 3). + // See the TeXbook, page 441. In AMSTeX, the extension fonts scale; to + // match cmex7, we'd use cmex7.tfm values for script and scriptscript + // values. + defaultRuleThickness: [0.04, 0.049, 0.049], + // xi8; cmex7: 0.049 + bigOpSpacing1: [0.111, 0.111, 0.111], + // xi9 + bigOpSpacing2: [0.166, 0.166, 0.166], + // xi10 + bigOpSpacing3: [0.2, 0.2, 0.2], + // xi11 + bigOpSpacing4: [0.6, 0.611, 0.611], + // xi12; cmex7: 0.611 + bigOpSpacing5: [0.1, 0.143, 0.143], + // xi13; cmex7: 0.143 + // The \sqrt rule width is taken from the height of the surd character. + // Since we use the same font at all sizes, this thickness doesn't scale. + sqrtRuleThickness: [0.04, 0.04, 0.04], + // This value determines how large a pt is, for metrics which are defined + // in terms of pts. + // This value is also used in katex.less; if you change it make sure the + // values match. + ptPerEm: [10.0, 10.0, 10.0], + // The space between adjacent `|` columns in an array definition. From + // `\showthe\doublerulesep` in LaTeX. Equals 2.0 / ptPerEm. + doubleRuleSep: [0.2, 0.2, 0.2], + // The width of separator lines in {array} environments. From + // `\showthe\arrayrulewidth` in LaTeX. Equals 0.4 / ptPerEm. + arrayRuleWidth: [0.04, 0.04, 0.04], + // Two values from LaTeX source2e: + fboxsep: [0.3, 0.3, 0.3], + // 3 pt / ptPerEm + fboxrule: [0.04, 0.04, 0.04] // 0.4 pt / ptPerEm + +}; // This map contains a mapping from font name and character code to character +// metrics, including height, depth, italic correction, and skew (kern from the +// character to the corresponding \skewchar) +// This map is generated via `make metrics`. It should not be changed manually. + + // These are very rough approximations. We default to Times New Roman which +// should have Latin-1 and Cyrillic characters, but may not depending on the +// operating system. The metrics do not account for extra height from the +// accents. In the case of Cyrillic characters which have both ascenders and +// descenders we prefer approximations with ascenders, primarily to prevent +// the fraction bar or root line from intersecting the glyph. +// TODO(kevinb) allow union of multiple glyph metrics for better accuracy. + +var extraCharacterMap = { + // Latin-1 + 'Å': 'A', + 'Ð': 'D', + 'Þ': 'o', + 'å': 'a', + 'ð': 'd', + 'þ': 'o', + // Cyrillic + 'А': 'A', + 'Б': 'B', + 'В': 'B', + 'Г': 'F', + 'Д': 'A', + 'Е': 'E', + 'Ж': 'K', + 'З': '3', + 'И': 'N', + 'Й': 'N', + 'К': 'K', + 'Л': 'N', + 'М': 'M', + 'Н': 'H', + 'О': 'O', + 'П': 'N', + 'Р': 'P', + 'С': 'C', + 'Т': 'T', + 'У': 'y', + 'Ф': 'O', + 'Х': 'X', + 'Ц': 'U', + 'Ч': 'h', + 'Ш': 'W', + 'Щ': 'W', + 'Ъ': 'B', + 'Ы': 'X', + 'Ь': 'B', + 'Э': '3', + 'Ю': 'X', + 'Я': 'R', + 'а': 'a', + 'б': 'b', + 'в': 'a', + 'г': 'r', + 'д': 'y', + 'е': 'e', + 'ж': 'm', + 'з': 'e', + 'и': 'n', + 'й': 'n', + 'к': 'n', + 'л': 'n', + 'м': 'm', + 'н': 'n', + 'о': 'o', + 'п': 'n', + 'р': 'p', + 'с': 'c', + 'т': 'o', + 'у': 'y', + 'ф': 'b', + 'х': 'x', + 'ц': 'n', + 'ч': 'n', + 'ш': 'w', + 'щ': 'w', + 'ъ': 'a', + 'ы': 'm', + 'ь': 'a', + 'э': 'e', + 'ю': 'm', + 'я': 'r' +}; + +/** + * This function adds new font metrics to default metricMap + * It can also override existing metrics + */ +function setFontMetrics(fontName, metrics) { + fontMetricsData[fontName] = metrics; +} +/** + * This function is a convenience function for looking up information in the + * metricMap table. It takes a character as a string, and a font. + * + * Note: the `width` property may be undefined if fontMetricsData.js wasn't + * built using `Make extended_metrics`. + */ + +function getCharacterMetrics(character, font, mode) { + if (!fontMetricsData[font]) { + throw new Error("Font metrics not found for font: " + font + "."); + } + + var ch = character.charCodeAt(0); + var metrics = fontMetricsData[font][ch]; + + if (!metrics && character[0] in extraCharacterMap) { + ch = extraCharacterMap[character[0]].charCodeAt(0); + metrics = fontMetricsData[font][ch]; + } + + if (!metrics && mode === 'text') { + // We don't typically have font metrics for Asian scripts. + // But since we support them in text mode, we need to return + // some sort of metrics. + // So if the character is in a script we support but we + // don't have metrics for it, just use the metrics for + // the Latin capital letter M. This is close enough because + // we (currently) only care about the height of the glpyh + // not its width. + if (supportedCodepoint(ch)) { + metrics = fontMetricsData[font][77]; // 77 is the charcode for 'M' + } + } + + if (metrics) { + return { + depth: metrics[0], + height: metrics[1], + italic: metrics[2], + skew: metrics[3], + width: metrics[4] + }; + } +} +var fontMetricsBySizeIndex = {}; +/** + * Get the font metrics for a given size. + */ + +function getGlobalMetrics(size) { + var sizeIndex; + + if (size >= 5) { + sizeIndex = 0; + } else if (size >= 3) { + sizeIndex = 1; + } else { + sizeIndex = 2; + } + + if (!fontMetricsBySizeIndex[sizeIndex]) { + var metrics = fontMetricsBySizeIndex[sizeIndex] = { + cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18 + }; + + for (var key in sigmasAndXis) { + if (sigmasAndXis.hasOwnProperty(key)) { + metrics[key] = sigmasAndXis[key][sizeIndex]; + } + } + } + + return fontMetricsBySizeIndex[sizeIndex]; +} +/** + * This file contains information about the options that the Parser carries + * around with it while parsing. Data is held in an `Options` object, and when + * recursing, a new `Options` object can be created with the `.with*` and + * `.reset` functions. + */ + +var sizeStyleMap = [// Each element contains [textsize, scriptsize, scriptscriptsize]. +// The size mappings are taken from TeX with \normalsize=10pt. +[1, 1, 1], // size1: [5, 5, 5] \tiny +[2, 1, 1], // size2: [6, 5, 5] +[3, 1, 1], // size3: [7, 5, 5] \scriptsize +[4, 2, 1], // size4: [8, 6, 5] \footnotesize +[5, 2, 1], // size5: [9, 6, 5] \small +[6, 3, 1], // size6: [10, 7, 5] \normalsize +[7, 4, 2], // size7: [12, 8, 6] \large +[8, 6, 3], // size8: [14.4, 10, 7] \Large +[9, 7, 6], // size9: [17.28, 12, 10] \LARGE +[10, 8, 7], // size10: [20.74, 14.4, 12] \huge +[11, 10, 9] // size11: [24.88, 20.74, 17.28] \HUGE +]; +var sizeMultipliers = [// fontMetrics.js:getGlobalMetrics also uses size indexes, so if +// you change size indexes, change that function. +0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488]; + +var sizeAtStyle = function sizeAtStyle(size, style) { + return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1]; +}; // In these types, "" (empty string) means "no change". + + +/** + * This is the main options class. It contains the current style, size, color, + * and font. + * + * Options objects should not be modified. To create a new Options with + * different properties, call a `.having*` method. + */ +var Options = /*#__PURE__*/function () { + // A font family applies to a group of fonts (i.e. SansSerif), while a font + // represents a specific font (i.e. SansSerif Bold). + // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm + + /** + * The base size index. + */ + function Options(data) { + this.style = void 0; + this.color = void 0; + this.size = void 0; + this.textSize = void 0; + this.phantom = void 0; + this.font = void 0; + this.fontFamily = void 0; + this.fontWeight = void 0; + this.fontShape = void 0; + this.sizeMultiplier = void 0; + this.maxSize = void 0; + this.minRuleThickness = void 0; + this._fontMetrics = void 0; + this.style = data.style; + this.color = data.color; + this.size = data.size || Options.BASESIZE; + this.textSize = data.textSize || this.size; + this.phantom = !!data.phantom; + this.font = data.font || ""; + this.fontFamily = data.fontFamily || ""; + this.fontWeight = data.fontWeight || ''; + this.fontShape = data.fontShape || ''; + this.sizeMultiplier = sizeMultipliers[this.size - 1]; + this.maxSize = data.maxSize; + this.minRuleThickness = data.minRuleThickness; + this._fontMetrics = undefined; + } + /** + * Returns a new options object with the same properties as "this". Properties + * from "extension" will be copied to the new options object. + */ + + + var _proto = Options.prototype; + + _proto.extend = function extend(extension) { + var data = { + style: this.style, + size: this.size, + textSize: this.textSize, + color: this.color, + phantom: this.phantom, + font: this.font, + fontFamily: this.fontFamily, + fontWeight: this.fontWeight, + fontShape: this.fontShape, + maxSize: this.maxSize, + minRuleThickness: this.minRuleThickness + }; + + for (var key in extension) { + if (extension.hasOwnProperty(key)) { + data[key] = extension[key]; + } + } + + return new Options(data); + } + /** + * Return an options object with the given style. If `this.style === style`, + * returns `this`. + */ + ; + + _proto.havingStyle = function havingStyle(style) { + if (this.style === style) { + return this; + } else { + return this.extend({ + style: style, + size: sizeAtStyle(this.textSize, style) + }); + } + } + /** + * Return an options object with a cramped version of the current style. If + * the current style is cramped, returns `this`. + */ + ; + + _proto.havingCrampedStyle = function havingCrampedStyle() { + return this.havingStyle(this.style.cramp()); + } + /** + * Return an options object with the given size and in at least `\textstyle`. + * Returns `this` if appropriate. + */ + ; + + _proto.havingSize = function havingSize(size) { + if (this.size === size && this.textSize === size) { + return this; + } else { + return this.extend({ + style: this.style.text(), + size: size, + textSize: size, + sizeMultiplier: sizeMultipliers[size - 1] + }); + } + } + /** + * Like `this.havingSize(BASESIZE).havingStyle(style)`. If `style` is omitted, + * changes to at least `\textstyle`. + */ + ; + + _proto.havingBaseStyle = function havingBaseStyle(style) { + style = style || this.style.text(); + var wantSize = sizeAtStyle(Options.BASESIZE, style); + + if (this.size === wantSize && this.textSize === Options.BASESIZE && this.style === style) { + return this; + } else { + return this.extend({ + style: style, + size: wantSize + }); + } + } + /** + * Remove the effect of sizing changes such as \Huge. + * Keep the effect of the current style, such as \scriptstyle. + */ + ; + + _proto.havingBaseSizing = function havingBaseSizing() { + var size; + + switch (this.style.id) { + case 4: + case 5: + size = 3; // normalsize in scriptstyle + + break; + + case 6: + case 7: + size = 1; // normalsize in scriptscriptstyle + + break; + + default: + size = 6; + // normalsize in textstyle or displaystyle + } + + return this.extend({ + style: this.style.text(), + size: size + }); + } + /** + * Create a new options object with the given color. + */ + ; + + _proto.withColor = function withColor(color) { + return this.extend({ + color: color + }); + } + /** + * Create a new options object with "phantom" set to true. + */ + ; + + _proto.withPhantom = function withPhantom() { + return this.extend({ + phantom: true + }); + } + /** + * Creates a new options object with the given math font or old text font. + * @type {[type]} + */ + ; + + _proto.withFont = function withFont(font) { + return this.extend({ + font: font + }); + } + /** + * Create a new options objects with the given fontFamily. + */ + ; + + _proto.withTextFontFamily = function withTextFontFamily(fontFamily) { + return this.extend({ + fontFamily: fontFamily, + font: "" + }); + } + /** + * Creates a new options object with the given font weight + */ + ; + + _proto.withTextFontWeight = function withTextFontWeight(fontWeight) { + return this.extend({ + fontWeight: fontWeight, + font: "" + }); + } + /** + * Creates a new options object with the given font weight + */ + ; + + _proto.withTextFontShape = function withTextFontShape(fontShape) { + return this.extend({ + fontShape: fontShape, + font: "" + }); + } + /** + * Return the CSS sizing classes required to switch from enclosing options + * `oldOptions` to `this`. Returns an array of classes. + */ + ; + + _proto.sizingClasses = function sizingClasses(oldOptions) { + if (oldOptions.size !== this.size) { + return ["sizing", "reset-size" + oldOptions.size, "size" + this.size]; + } else { + return []; + } + } + /** + * Return the CSS sizing classes required to switch to the base size. Like + * `this.havingSize(BASESIZE).sizingClasses(this)`. + */ + ; + + _proto.baseSizingClasses = function baseSizingClasses() { + if (this.size !== Options.BASESIZE) { + return ["sizing", "reset-size" + this.size, "size" + Options.BASESIZE]; + } else { + return []; + } + } + /** + * Return the font metrics for this size. + */ + ; + + _proto.fontMetrics = function fontMetrics() { + if (!this._fontMetrics) { + this._fontMetrics = getGlobalMetrics(this.size); + } + + return this._fontMetrics; + } + /** + * Gets the CSS color of the current options object + */ + ; + + _proto.getColor = function getColor() { + if (this.phantom) { + return "transparent"; + } else { + return this.color; + } + }; + + return Options; +}(); + +Options.BASESIZE = 6; +/* harmony default export */ var src_Options = (Options); +/** + * This file does conversion between units. In particular, it provides + * calculateSize to convert other units into ems. + */ + + // This table gives the number of TeX pts in one of each *absolute* TeX unit. +// Thus, multiplying a length by this number converts the length from units +// into pts. Dividing the result by ptPerEm gives the number of ems +// *assuming* a font size of ptPerEm (normal size, normal style). + +var ptPerUnit = { + // https://en.wikibooks.org/wiki/LaTeX/Lengths and + // https://tex.stackexchange.com/a/8263 + "pt": 1, + // TeX point + "mm": 7227 / 2540, + // millimeter + "cm": 7227 / 254, + // centimeter + "in": 72.27, + // inch + "bp": 803 / 800, + // big (PostScript) points + "pc": 12, + // pica + "dd": 1238 / 1157, + // didot + "cc": 14856 / 1157, + // cicero (12 didot) + "nd": 685 / 642, + // new didot + "nc": 1370 / 107, + // new cicero (12 new didot) + "sp": 1 / 65536, + // scaled point (TeX's internal smallest unit) + // https://tex.stackexchange.com/a/41371 + "px": 803 / 800 // \pdfpxdimen defaults to 1 bp in pdfTeX and LuaTeX + +}; // Dictionary of relative units, for fast validity testing. + +var relativeUnit = { + "ex": true, + "em": true, + "mu": true +}; + +/** + * Determine whether the specified unit (either a string defining the unit + * or a "size" parse node containing a unit field) is valid. + */ +var validUnit = function validUnit(unit) { + if (typeof unit !== "string") { + unit = unit.unit; + } + + return unit in ptPerUnit || unit in relativeUnit || unit === "ex"; +}; +/* + * Convert a "size" parse node (with numeric "number" and string "unit" fields, + * as parsed by functions.js argType "size") into a CSS em value for the + * current style/scale. `options` gives the current options. + */ + +var calculateSize = function calculateSize(sizeValue, options) { + var scale; + + if (sizeValue.unit in ptPerUnit) { + // Absolute units + scale = ptPerUnit[sizeValue.unit] // Convert unit to pt + / options.fontMetrics().ptPerEm // Convert pt to CSS em + / options.sizeMultiplier; // Unscale to make absolute units + } else if (sizeValue.unit === "mu") { + // `mu` units scale with scriptstyle/scriptscriptstyle. + scale = options.fontMetrics().cssEmPerMu; + } else { + // Other relative units always refer to the *textstyle* font + // in the current size. + var unitOptions; + + if (options.style.isTight()) { + // isTight() means current style is script/scriptscript. + unitOptions = options.havingStyle(options.style.text()); + } else { + unitOptions = options; + } // TODO: In TeX these units are relative to the quad of the current + // *text* font, e.g. cmr10. KaTeX instead uses values from the + // comparably-sized *Computer Modern symbol* font. At 10pt, these + // match. At 7pt and 5pt, they differ: cmr7=1.138894, cmsy7=1.170641; + // cmr5=1.361133, cmsy5=1.472241. Consider $\scriptsize a\kern1emb$. + // TeX \showlists shows a kern of 1.13889 * fontsize; + // KaTeX shows a kern of 1.171 * fontsize. + + + if (sizeValue.unit === "ex") { + scale = unitOptions.fontMetrics().xHeight; + } else if (sizeValue.unit === "em") { + scale = unitOptions.fontMetrics().quad; + } else { + throw new src_ParseError("Invalid unit: '" + sizeValue.unit + "'"); + } + + if (unitOptions !== options) { + scale *= unitOptions.sizeMultiplier / options.sizeMultiplier; + } + } + + return Math.min(sizeValue.number * scale, options.maxSize); +}; +/** + * Round `n` to 4 decimal places, or to the nearest 1/10,000th em. See + * https://github.com/KaTeX/KaTeX/pull/2460. + */ + +var makeEm = function makeEm(n) { + return +n.toFixed(4) + "em"; +}; +/** + * These objects store the data about the DOM nodes we create, as well as some + * extra data. They can then be transformed into real DOM nodes with the + * `toNode` function or HTML markup using `toMarkup`. They are useful for both + * storing extra properties on the nodes, as well as providing a way to easily + * work with the DOM. + * + * Similar functions for working with MathML nodes exist in mathMLTree.js. + * + * TODO: refactor `span` and `anchor` into common superclass when + * target environments support class inheritance + */ + + + + + + +/** + * Create an HTML className based on a list of classes. In addition to joining + * with spaces, we also remove empty classes. + */ +var createClass = function createClass(classes) { + return classes.filter(function (cls) { + return cls; + }).join(" "); +}; + +var initNode = function initNode(classes, options, style) { + this.classes = classes || []; + this.attributes = {}; + this.height = 0; + this.depth = 0; + this.maxFontSize = 0; + this.style = style || {}; + + if (options) { + if (options.style.isTight()) { + this.classes.push("mtight"); + } + + var color = options.getColor(); + + if (color) { + this.style.color = color; + } + } +}; +/** + * Convert into an HTML node + */ + + +var _toNode = function toNode(tagName) { + var node = document.createElement(tagName); // Apply the class + + node.className = createClass(this.classes); // Apply inline styles + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + // $FlowFixMe Flow doesn't seem to understand span.style's type. + node.style[style] = this.style[style]; + } + } // Apply attributes + + + for (var attr in this.attributes) { + if (this.attributes.hasOwnProperty(attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } // Append the children, also as HTML nodes + + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; +}; +/** + * Convert into an HTML markup string + */ + + +var _toMarkup = function toMarkup(tagName) { + var markup = "<" + tagName; // Add the class + + if (this.classes.length) { + markup += " class=\"" + utils.escape(createClass(this.classes)) + "\""; + } + + var styles = ""; // Add the styles, after hyphenation + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; + } + } + + if (styles) { + markup += " style=\"" + utils.escape(styles) + "\""; + } // Add the attributes + + + for (var attr in this.attributes) { + if (this.attributes.hasOwnProperty(attr)) { + markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\""; + } + } + + markup += ">"; // Add the markup of the children, also as markup + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + markup += ""; + return markup; +}; // Making the type below exact with all optional fields doesn't work due to +// - https://github.com/facebook/flow/issues/4582 +// - https://github.com/facebook/flow/issues/5688 +// However, since *all* fields are optional, $Shape<> works as suggested in 5688 +// above. +// This type does not include all CSS properties. Additional properties should +// be added as needed. + + +/** + * This node represents a span node, with a className, a list of children, and + * an inline style. It also contains information about its height, depth, and + * maxFontSize. + * + * Represents two types with different uses: SvgSpan to wrap an SVG and DomSpan + * otherwise. This typesafety is important when HTML builders access a span's + * children. + */ +var Span = /*#__PURE__*/function () { + function Span(classes, children, options, style) { + this.children = void 0; + this.attributes = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.width = void 0; + this.maxFontSize = void 0; + this.style = void 0; + initNode.call(this, classes, options, style); + this.children = children || []; + } + /** + * Sets an arbitrary attribute on the span. Warning: use this wisely. Not + * all browsers support attributes the same, and having too many custom + * attributes is probably bad. + */ + + + var _proto = Span.prototype; + + _proto.setAttribute = function setAttribute(attribute, value) { + this.attributes[attribute] = value; + }; + + _proto.hasClass = function hasClass(className) { + return utils.contains(this.classes, className); + }; + + _proto.toNode = function toNode() { + return _toNode.call(this, "span"); + }; + + _proto.toMarkup = function toMarkup() { + return _toMarkup.call(this, "span"); + }; + + return Span; +}(); +/** + * This node represents an anchor () element with a hyperlink. See `span` + * for further details. + */ + +var Anchor = /*#__PURE__*/function () { + function Anchor(href, classes, children, options) { + this.children = void 0; + this.attributes = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.maxFontSize = void 0; + this.style = void 0; + initNode.call(this, classes, options); + this.children = children || []; + this.setAttribute('href', href); + } + + var _proto2 = Anchor.prototype; + + _proto2.setAttribute = function setAttribute(attribute, value) { + this.attributes[attribute] = value; + }; + + _proto2.hasClass = function hasClass(className) { + return utils.contains(this.classes, className); + }; + + _proto2.toNode = function toNode() { + return _toNode.call(this, "a"); + }; + + _proto2.toMarkup = function toMarkup() { + return _toMarkup.call(this, "a"); + }; + + return Anchor; +}(); +/** + * This node represents an image embed () element. + */ + +var Img = /*#__PURE__*/function () { + function Img(src, alt, style) { + this.src = void 0; + this.alt = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.maxFontSize = void 0; + this.style = void 0; + this.alt = alt; + this.src = src; + this.classes = ["mord"]; + this.style = style; + } + + var _proto3 = Img.prototype; + + _proto3.hasClass = function hasClass(className) { + return utils.contains(this.classes, className); + }; + + _proto3.toNode = function toNode() { + var node = document.createElement("img"); + node.src = this.src; + node.alt = this.alt; + node.className = "mord"; // Apply inline styles + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + // $FlowFixMe + node.style[style] = this.style[style]; + } + } + + return node; + }; + + _proto3.toMarkup = function toMarkup() { + var markup = "" + this.alt + " 0) { + span = document.createElement("span"); + span.style.marginRight = makeEm(this.italic); + } + + if (this.classes.length > 0) { + span = span || document.createElement("span"); + span.className = createClass(this.classes); + } + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + span = span || document.createElement("span"); // $FlowFixMe Flow doesn't seem to understand span.style's type. + + span.style[style] = this.style[style]; + } + } + + if (span) { + span.appendChild(node); + return span; + } else { + return node; + } + } + /** + * Creates markup for a symbol node. + */ + ; + + _proto4.toMarkup = function toMarkup() { + // TODO(alpert): More duplication than I'd like from + // span.prototype.toMarkup and symbolNode.prototype.toNode... + var needsSpan = false; + var markup = " 0) { + styles += "margin-right:" + this.italic + "em;"; + } + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; + } + } + + if (styles) { + needsSpan = true; + markup += " style=\"" + utils.escape(styles) + "\""; + } + + var escaped = utils.escape(this.text); + + if (needsSpan) { + markup += ">"; + markup += escaped; + markup += ""; + return markup; + } else { + return escaped; + } + }; + + return SymbolNode; +}(); +/** + * SVG nodes are used to render stretchy wide elements. + */ + +var SvgNode = /*#__PURE__*/function () { + function SvgNode(children, attributes) { + this.children = void 0; + this.attributes = void 0; + this.children = children || []; + this.attributes = attributes || {}; + } + + var _proto5 = SvgNode.prototype; + + _proto5.toNode = function toNode() { + var svgNS = "http://www.w3.org/2000/svg"; + var node = document.createElementNS(svgNS, "svg"); // Apply attributes + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; + }; + + _proto5.toMarkup = function toMarkup() { + var markup = ""; + } else { + return ""; + } + }; + + return PathNode; +}(); +var LineNode = /*#__PURE__*/function () { + function LineNode(attributes) { + this.attributes = void 0; + this.attributes = attributes || {}; + } + + var _proto7 = LineNode.prototype; + + _proto7.toNode = function toNode() { + var svgNS = "http://www.w3.org/2000/svg"; + var node = document.createElementNS(svgNS, "line"); // Apply attributes + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + return node; + }; + + _proto7.toMarkup = function toMarkup() { + var markup = " but got " + String(group) + "."); + } +} +/** + * This file holds a list of all no-argument functions and single-character + * symbols (like 'a' or ';'). + * + * For each of the symbols, there are three properties they can have: + * - font (required): the font to be used for this symbol. Either "main" (the + normal font), or "ams" (the ams fonts). + * - group (required): the ParseNode group type the symbol should have (i.e. + "textord", "mathord", etc). + See https://github.com/KaTeX/KaTeX/wiki/Examining-TeX#group-types + * - replace: the character that this symbol or function should be + * replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi + * character in the main font). + * + * The outermost map in the table indicates what mode the symbols should be + * accepted in (e.g. "math" or "text"). + */ +// Some of these have a "-token" suffix since these are also used as `ParseNode` +// types for raw text tokens, and we want to avoid conflicts with higher-level +// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by +// looking up the `symbols` map. +var ATOMS = { + "bin": 1, + "close": 1, + "inner": 1, + "open": 1, + "punct": 1, + "rel": 1 +}; +var NON_ATOMS = { + "accent-token": 1, + "mathord": 1, + "op-token": 1, + "spacing": 1, + "textord": 1 +}; +var symbols = { + "math": {}, + "text": {} +}; +/* harmony default export */ var src_symbols = (symbols); +/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */ + +function defineSymbol(mode, font, group, replace, name, acceptUnicodeChar) { + symbols[mode][name] = { + font: font, + group: group, + replace: replace + }; + + if (acceptUnicodeChar && replace) { + symbols[mode][replace] = symbols[mode][name]; + } +} // Some abbreviations for commonly used strings. +// This helps minify the code, and also spotting typos using jshint. +// modes: + +var math = "math"; +var symbols_text = "text"; // fonts: + +var main = "main"; +var ams = "ams"; // groups: + +var accent = "accent-token"; +var bin = "bin"; +var symbols_close = "close"; +var inner = "inner"; +var mathord = "mathord"; +var op = "op-token"; +var symbols_open = "open"; +var punct = "punct"; +var rel = "rel"; +var spacing = "spacing"; +var textord = "textord"; // Now comes the symbol table +// Relation Symbols + +defineSymbol(math, main, rel, "\u2261", "\\equiv", true); +defineSymbol(math, main, rel, "\u227A", "\\prec", true); +defineSymbol(math, main, rel, "\u227B", "\\succ", true); +defineSymbol(math, main, rel, "\u223C", "\\sim", true); +defineSymbol(math, main, rel, "\u22A5", "\\perp"); +defineSymbol(math, main, rel, "\u2AAF", "\\preceq", true); +defineSymbol(math, main, rel, "\u2AB0", "\\succeq", true); +defineSymbol(math, main, rel, "\u2243", "\\simeq", true); +defineSymbol(math, main, rel, "\u2223", "\\mid", true); +defineSymbol(math, main, rel, "\u226A", "\\ll", true); +defineSymbol(math, main, rel, "\u226B", "\\gg", true); +defineSymbol(math, main, rel, "\u224D", "\\asymp", true); +defineSymbol(math, main, rel, "\u2225", "\\parallel"); +defineSymbol(math, main, rel, "\u22C8", "\\bowtie", true); +defineSymbol(math, main, rel, "\u2323", "\\smile", true); +defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq", true); +defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq", true); +defineSymbol(math, main, rel, "\u2250", "\\doteq", true); +defineSymbol(math, main, rel, "\u2322", "\\frown", true); +defineSymbol(math, main, rel, "\u220B", "\\ni", true); +defineSymbol(math, main, rel, "\u221D", "\\propto", true); +defineSymbol(math, main, rel, "\u22A2", "\\vdash", true); +defineSymbol(math, main, rel, "\u22A3", "\\dashv", true); +defineSymbol(math, main, rel, "\u220B", "\\owns"); // Punctuation + +defineSymbol(math, main, punct, ".", "\\ldotp"); +defineSymbol(math, main, punct, "\u22C5", "\\cdotp"); // Misc Symbols + +defineSymbol(math, main, textord, "#", "\\#"); +defineSymbol(symbols_text, main, textord, "#", "\\#"); +defineSymbol(math, main, textord, "&", "\\&"); +defineSymbol(symbols_text, main, textord, "&", "\\&"); +defineSymbol(math, main, textord, "\u2135", "\\aleph", true); +defineSymbol(math, main, textord, "\u2200", "\\forall", true); +defineSymbol(math, main, textord, "\u210F", "\\hbar", true); +defineSymbol(math, main, textord, "\u2203", "\\exists", true); +defineSymbol(math, main, textord, "\u2207", "\\nabla", true); +defineSymbol(math, main, textord, "\u266D", "\\flat", true); +defineSymbol(math, main, textord, "\u2113", "\\ell", true); +defineSymbol(math, main, textord, "\u266E", "\\natural", true); +defineSymbol(math, main, textord, "\u2663", "\\clubsuit", true); +defineSymbol(math, main, textord, "\u2118", "\\wp", true); +defineSymbol(math, main, textord, "\u266F", "\\sharp", true); +defineSymbol(math, main, textord, "\u2662", "\\diamondsuit", true); +defineSymbol(math, main, textord, "\u211C", "\\Re", true); +defineSymbol(math, main, textord, "\u2661", "\\heartsuit", true); +defineSymbol(math, main, textord, "\u2111", "\\Im", true); +defineSymbol(math, main, textord, "\u2660", "\\spadesuit", true); +defineSymbol(math, main, textord, "\xA7", "\\S", true); +defineSymbol(symbols_text, main, textord, "\xA7", "\\S"); +defineSymbol(math, main, textord, "\xB6", "\\P", true); +defineSymbol(symbols_text, main, textord, "\xB6", "\\P"); // Math and Text + +defineSymbol(math, main, textord, "\u2020", "\\dag"); +defineSymbol(symbols_text, main, textord, "\u2020", "\\dag"); +defineSymbol(symbols_text, main, textord, "\u2020", "\\textdagger"); +defineSymbol(math, main, textord, "\u2021", "\\ddag"); +defineSymbol(symbols_text, main, textord, "\u2021", "\\ddag"); +defineSymbol(symbols_text, main, textord, "\u2021", "\\textdaggerdbl"); // Large Delimiters + +defineSymbol(math, main, symbols_close, "\u23B1", "\\rmoustache", true); +defineSymbol(math, main, symbols_open, "\u23B0", "\\lmoustache", true); +defineSymbol(math, main, symbols_close, "\u27EF", "\\rgroup", true); +defineSymbol(math, main, symbols_open, "\u27EE", "\\lgroup", true); // Binary Operators + +defineSymbol(math, main, bin, "\u2213", "\\mp", true); +defineSymbol(math, main, bin, "\u2296", "\\ominus", true); +defineSymbol(math, main, bin, "\u228E", "\\uplus", true); +defineSymbol(math, main, bin, "\u2293", "\\sqcap", true); +defineSymbol(math, main, bin, "\u2217", "\\ast"); +defineSymbol(math, main, bin, "\u2294", "\\sqcup", true); +defineSymbol(math, main, bin, "\u25EF", "\\bigcirc", true); +defineSymbol(math, main, bin, "\u2219", "\\bullet"); +defineSymbol(math, main, bin, "\u2021", "\\ddagger"); +defineSymbol(math, main, bin, "\u2240", "\\wr", true); +defineSymbol(math, main, bin, "\u2A3F", "\\amalg"); +defineSymbol(math, main, bin, "&", "\\And"); // from amsmath +// Arrow Symbols + +defineSymbol(math, main, rel, "\u27F5", "\\longleftarrow", true); +defineSymbol(math, main, rel, "\u21D0", "\\Leftarrow", true); +defineSymbol(math, main, rel, "\u27F8", "\\Longleftarrow", true); +defineSymbol(math, main, rel, "\u27F6", "\\longrightarrow", true); +defineSymbol(math, main, rel, "\u21D2", "\\Rightarrow", true); +defineSymbol(math, main, rel, "\u27F9", "\\Longrightarrow", true); +defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow", true); +defineSymbol(math, main, rel, "\u27F7", "\\longleftrightarrow", true); +defineSymbol(math, main, rel, "\u21D4", "\\Leftrightarrow", true); +defineSymbol(math, main, rel, "\u27FA", "\\Longleftrightarrow", true); +defineSymbol(math, main, rel, "\u21A6", "\\mapsto", true); +defineSymbol(math, main, rel, "\u27FC", "\\longmapsto", true); +defineSymbol(math, main, rel, "\u2197", "\\nearrow", true); +defineSymbol(math, main, rel, "\u21A9", "\\hookleftarrow", true); +defineSymbol(math, main, rel, "\u21AA", "\\hookrightarrow", true); +defineSymbol(math, main, rel, "\u2198", "\\searrow", true); +defineSymbol(math, main, rel, "\u21BC", "\\leftharpoonup", true); +defineSymbol(math, main, rel, "\u21C0", "\\rightharpoonup", true); +defineSymbol(math, main, rel, "\u2199", "\\swarrow", true); +defineSymbol(math, main, rel, "\u21BD", "\\leftharpoondown", true); +defineSymbol(math, main, rel, "\u21C1", "\\rightharpoondown", true); +defineSymbol(math, main, rel, "\u2196", "\\nwarrow", true); +defineSymbol(math, main, rel, "\u21CC", "\\rightleftharpoons", true); // AMS Negated Binary Relations + +defineSymbol(math, ams, rel, "\u226E", "\\nless", true); // Symbol names preceeded by "@" each have a corresponding macro. + +defineSymbol(math, ams, rel, "\uE010", "\\@nleqslant"); +defineSymbol(math, ams, rel, "\uE011", "\\@nleqq"); +defineSymbol(math, ams, rel, "\u2A87", "\\lneq", true); +defineSymbol(math, ams, rel, "\u2268", "\\lneqq", true); +defineSymbol(math, ams, rel, "\uE00C", "\\@lvertneqq"); +defineSymbol(math, ams, rel, "\u22E6", "\\lnsim", true); +defineSymbol(math, ams, rel, "\u2A89", "\\lnapprox", true); +defineSymbol(math, ams, rel, "\u2280", "\\nprec", true); // unicode-math maps \u22e0 to \npreccurlyeq. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u22E0", "\\npreceq", true); +defineSymbol(math, ams, rel, "\u22E8", "\\precnsim", true); +defineSymbol(math, ams, rel, "\u2AB9", "\\precnapprox", true); +defineSymbol(math, ams, rel, "\u2241", "\\nsim", true); +defineSymbol(math, ams, rel, "\uE006", "\\@nshortmid"); +defineSymbol(math, ams, rel, "\u2224", "\\nmid", true); +defineSymbol(math, ams, rel, "\u22AC", "\\nvdash", true); +defineSymbol(math, ams, rel, "\u22AD", "\\nvDash", true); +defineSymbol(math, ams, rel, "\u22EA", "\\ntriangleleft"); +defineSymbol(math, ams, rel, "\u22EC", "\\ntrianglelefteq", true); +defineSymbol(math, ams, rel, "\u228A", "\\subsetneq", true); +defineSymbol(math, ams, rel, "\uE01A", "\\@varsubsetneq"); +defineSymbol(math, ams, rel, "\u2ACB", "\\subsetneqq", true); +defineSymbol(math, ams, rel, "\uE017", "\\@varsubsetneqq"); +defineSymbol(math, ams, rel, "\u226F", "\\ngtr", true); +defineSymbol(math, ams, rel, "\uE00F", "\\@ngeqslant"); +defineSymbol(math, ams, rel, "\uE00E", "\\@ngeqq"); +defineSymbol(math, ams, rel, "\u2A88", "\\gneq", true); +defineSymbol(math, ams, rel, "\u2269", "\\gneqq", true); +defineSymbol(math, ams, rel, "\uE00D", "\\@gvertneqq"); +defineSymbol(math, ams, rel, "\u22E7", "\\gnsim", true); +defineSymbol(math, ams, rel, "\u2A8A", "\\gnapprox", true); +defineSymbol(math, ams, rel, "\u2281", "\\nsucc", true); // unicode-math maps \u22e1 to \nsucccurlyeq. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u22E1", "\\nsucceq", true); +defineSymbol(math, ams, rel, "\u22E9", "\\succnsim", true); +defineSymbol(math, ams, rel, "\u2ABA", "\\succnapprox", true); // unicode-math maps \u2246 to \simneqq. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u2246", "\\ncong", true); +defineSymbol(math, ams, rel, "\uE007", "\\@nshortparallel"); +defineSymbol(math, ams, rel, "\u2226", "\\nparallel", true); +defineSymbol(math, ams, rel, "\u22AF", "\\nVDash", true); +defineSymbol(math, ams, rel, "\u22EB", "\\ntriangleright"); +defineSymbol(math, ams, rel, "\u22ED", "\\ntrianglerighteq", true); +defineSymbol(math, ams, rel, "\uE018", "\\@nsupseteqq"); +defineSymbol(math, ams, rel, "\u228B", "\\supsetneq", true); +defineSymbol(math, ams, rel, "\uE01B", "\\@varsupsetneq"); +defineSymbol(math, ams, rel, "\u2ACC", "\\supsetneqq", true); +defineSymbol(math, ams, rel, "\uE019", "\\@varsupsetneqq"); +defineSymbol(math, ams, rel, "\u22AE", "\\nVdash", true); +defineSymbol(math, ams, rel, "\u2AB5", "\\precneqq", true); +defineSymbol(math, ams, rel, "\u2AB6", "\\succneqq", true); +defineSymbol(math, ams, rel, "\uE016", "\\@nsubseteqq"); +defineSymbol(math, ams, bin, "\u22B4", "\\unlhd"); +defineSymbol(math, ams, bin, "\u22B5", "\\unrhd"); // AMS Negated Arrows + +defineSymbol(math, ams, rel, "\u219A", "\\nleftarrow", true); +defineSymbol(math, ams, rel, "\u219B", "\\nrightarrow", true); +defineSymbol(math, ams, rel, "\u21CD", "\\nLeftarrow", true); +defineSymbol(math, ams, rel, "\u21CF", "\\nRightarrow", true); +defineSymbol(math, ams, rel, "\u21AE", "\\nleftrightarrow", true); +defineSymbol(math, ams, rel, "\u21CE", "\\nLeftrightarrow", true); // AMS Misc + +defineSymbol(math, ams, rel, "\u25B3", "\\vartriangle"); +defineSymbol(math, ams, textord, "\u210F", "\\hslash"); +defineSymbol(math, ams, textord, "\u25BD", "\\triangledown"); +defineSymbol(math, ams, textord, "\u25CA", "\\lozenge"); +defineSymbol(math, ams, textord, "\u24C8", "\\circledS"); +defineSymbol(math, ams, textord, "\xAE", "\\circledR"); +defineSymbol(symbols_text, ams, textord, "\xAE", "\\circledR"); +defineSymbol(math, ams, textord, "\u2221", "\\measuredangle", true); +defineSymbol(math, ams, textord, "\u2204", "\\nexists"); +defineSymbol(math, ams, textord, "\u2127", "\\mho"); +defineSymbol(math, ams, textord, "\u2132", "\\Finv", true); +defineSymbol(math, ams, textord, "\u2141", "\\Game", true); +defineSymbol(math, ams, textord, "\u2035", "\\backprime"); +defineSymbol(math, ams, textord, "\u25B2", "\\blacktriangle"); +defineSymbol(math, ams, textord, "\u25BC", "\\blacktriangledown"); +defineSymbol(math, ams, textord, "\u25A0", "\\blacksquare"); +defineSymbol(math, ams, textord, "\u29EB", "\\blacklozenge"); +defineSymbol(math, ams, textord, "\u2605", "\\bigstar"); +defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle", true); +defineSymbol(math, ams, textord, "\u2201", "\\complement", true); // unicode-math maps U+F0 to \matheth. We map to AMS function \eth + +defineSymbol(math, ams, textord, "\xF0", "\\eth", true); +defineSymbol(symbols_text, main, textord, "\xF0", "\xF0"); +defineSymbol(math, ams, textord, "\u2571", "\\diagup"); +defineSymbol(math, ams, textord, "\u2572", "\\diagdown"); +defineSymbol(math, ams, textord, "\u25A1", "\\square"); +defineSymbol(math, ams, textord, "\u25A1", "\\Box"); +defineSymbol(math, ams, textord, "\u25CA", "\\Diamond"); // unicode-math maps U+A5 to \mathyen. We map to AMS function \yen + +defineSymbol(math, ams, textord, "\xA5", "\\yen", true); +defineSymbol(symbols_text, ams, textord, "\xA5", "\\yen", true); +defineSymbol(math, ams, textord, "\u2713", "\\checkmark", true); +defineSymbol(symbols_text, ams, textord, "\u2713", "\\checkmark"); // AMS Hebrew + +defineSymbol(math, ams, textord, "\u2136", "\\beth", true); +defineSymbol(math, ams, textord, "\u2138", "\\daleth", true); +defineSymbol(math, ams, textord, "\u2137", "\\gimel", true); // AMS Greek + +defineSymbol(math, ams, textord, "\u03DD", "\\digamma", true); +defineSymbol(math, ams, textord, "\u03F0", "\\varkappa"); // AMS Delimiters + +defineSymbol(math, ams, symbols_open, "\u250C", "\\@ulcorner", true); +defineSymbol(math, ams, symbols_close, "\u2510", "\\@urcorner", true); +defineSymbol(math, ams, symbols_open, "\u2514", "\\@llcorner", true); +defineSymbol(math, ams, symbols_close, "\u2518", "\\@lrcorner", true); // AMS Binary Relations + +defineSymbol(math, ams, rel, "\u2266", "\\leqq", true); +defineSymbol(math, ams, rel, "\u2A7D", "\\leqslant", true); +defineSymbol(math, ams, rel, "\u2A95", "\\eqslantless", true); +defineSymbol(math, ams, rel, "\u2272", "\\lesssim", true); +defineSymbol(math, ams, rel, "\u2A85", "\\lessapprox", true); +defineSymbol(math, ams, rel, "\u224A", "\\approxeq", true); +defineSymbol(math, ams, bin, "\u22D6", "\\lessdot"); +defineSymbol(math, ams, rel, "\u22D8", "\\lll", true); +defineSymbol(math, ams, rel, "\u2276", "\\lessgtr", true); +defineSymbol(math, ams, rel, "\u22DA", "\\lesseqgtr", true); +defineSymbol(math, ams, rel, "\u2A8B", "\\lesseqqgtr", true); +defineSymbol(math, ams, rel, "\u2251", "\\doteqdot"); +defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq", true); +defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq", true); +defineSymbol(math, ams, rel, "\u223D", "\\backsim", true); +defineSymbol(math, ams, rel, "\u22CD", "\\backsimeq", true); +defineSymbol(math, ams, rel, "\u2AC5", "\\subseteqq", true); +defineSymbol(math, ams, rel, "\u22D0", "\\Subset", true); +defineSymbol(math, ams, rel, "\u228F", "\\sqsubset", true); +defineSymbol(math, ams, rel, "\u227C", "\\preccurlyeq", true); +defineSymbol(math, ams, rel, "\u22DE", "\\curlyeqprec", true); +defineSymbol(math, ams, rel, "\u227E", "\\precsim", true); +defineSymbol(math, ams, rel, "\u2AB7", "\\precapprox", true); +defineSymbol(math, ams, rel, "\u22B2", "\\vartriangleleft"); +defineSymbol(math, ams, rel, "\u22B4", "\\trianglelefteq"); +defineSymbol(math, ams, rel, "\u22A8", "\\vDash", true); +defineSymbol(math, ams, rel, "\u22AA", "\\Vvdash", true); +defineSymbol(math, ams, rel, "\u2323", "\\smallsmile"); +defineSymbol(math, ams, rel, "\u2322", "\\smallfrown"); +defineSymbol(math, ams, rel, "\u224F", "\\bumpeq", true); +defineSymbol(math, ams, rel, "\u224E", "\\Bumpeq", true); +defineSymbol(math, ams, rel, "\u2267", "\\geqq", true); +defineSymbol(math, ams, rel, "\u2A7E", "\\geqslant", true); +defineSymbol(math, ams, rel, "\u2A96", "\\eqslantgtr", true); +defineSymbol(math, ams, rel, "\u2273", "\\gtrsim", true); +defineSymbol(math, ams, rel, "\u2A86", "\\gtrapprox", true); +defineSymbol(math, ams, bin, "\u22D7", "\\gtrdot"); +defineSymbol(math, ams, rel, "\u22D9", "\\ggg", true); +defineSymbol(math, ams, rel, "\u2277", "\\gtrless", true); +defineSymbol(math, ams, rel, "\u22DB", "\\gtreqless", true); +defineSymbol(math, ams, rel, "\u2A8C", "\\gtreqqless", true); +defineSymbol(math, ams, rel, "\u2256", "\\eqcirc", true); +defineSymbol(math, ams, rel, "\u2257", "\\circeq", true); +defineSymbol(math, ams, rel, "\u225C", "\\triangleq", true); +defineSymbol(math, ams, rel, "\u223C", "\\thicksim"); +defineSymbol(math, ams, rel, "\u2248", "\\thickapprox"); +defineSymbol(math, ams, rel, "\u2AC6", "\\supseteqq", true); +defineSymbol(math, ams, rel, "\u22D1", "\\Supset", true); +defineSymbol(math, ams, rel, "\u2290", "\\sqsupset", true); +defineSymbol(math, ams, rel, "\u227D", "\\succcurlyeq", true); +defineSymbol(math, ams, rel, "\u22DF", "\\curlyeqsucc", true); +defineSymbol(math, ams, rel, "\u227F", "\\succsim", true); +defineSymbol(math, ams, rel, "\u2AB8", "\\succapprox", true); +defineSymbol(math, ams, rel, "\u22B3", "\\vartriangleright"); +defineSymbol(math, ams, rel, "\u22B5", "\\trianglerighteq"); +defineSymbol(math, ams, rel, "\u22A9", "\\Vdash", true); +defineSymbol(math, ams, rel, "\u2223", "\\shortmid"); +defineSymbol(math, ams, rel, "\u2225", "\\shortparallel"); +defineSymbol(math, ams, rel, "\u226C", "\\between", true); +defineSymbol(math, ams, rel, "\u22D4", "\\pitchfork", true); +defineSymbol(math, ams, rel, "\u221D", "\\varpropto"); +defineSymbol(math, ams, rel, "\u25C0", "\\blacktriangleleft"); // unicode-math says that \therefore is a mathord atom. +// We kept the amssymb atom type, which is rel. + +defineSymbol(math, ams, rel, "\u2234", "\\therefore", true); +defineSymbol(math, ams, rel, "\u220D", "\\backepsilon"); +defineSymbol(math, ams, rel, "\u25B6", "\\blacktriangleright"); // unicode-math says that \because is a mathord atom. +// We kept the amssymb atom type, which is rel. + +defineSymbol(math, ams, rel, "\u2235", "\\because", true); +defineSymbol(math, ams, rel, "\u22D8", "\\llless"); +defineSymbol(math, ams, rel, "\u22D9", "\\gggtr"); +defineSymbol(math, ams, bin, "\u22B2", "\\lhd"); +defineSymbol(math, ams, bin, "\u22B3", "\\rhd"); +defineSymbol(math, ams, rel, "\u2242", "\\eqsim", true); +defineSymbol(math, main, rel, "\u22C8", "\\Join"); +defineSymbol(math, ams, rel, "\u2251", "\\Doteq", true); // AMS Binary Operators + +defineSymbol(math, ams, bin, "\u2214", "\\dotplus", true); +defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus"); +defineSymbol(math, ams, bin, "\u22D2", "\\Cap", true); +defineSymbol(math, ams, bin, "\u22D3", "\\Cup", true); +defineSymbol(math, ams, bin, "\u2A5E", "\\doublebarwedge", true); +defineSymbol(math, ams, bin, "\u229F", "\\boxminus", true); +defineSymbol(math, ams, bin, "\u229E", "\\boxplus", true); +defineSymbol(math, ams, bin, "\u22C7", "\\divideontimes", true); +defineSymbol(math, ams, bin, "\u22C9", "\\ltimes", true); +defineSymbol(math, ams, bin, "\u22CA", "\\rtimes", true); +defineSymbol(math, ams, bin, "\u22CB", "\\leftthreetimes", true); +defineSymbol(math, ams, bin, "\u22CC", "\\rightthreetimes", true); +defineSymbol(math, ams, bin, "\u22CF", "\\curlywedge", true); +defineSymbol(math, ams, bin, "\u22CE", "\\curlyvee", true); +defineSymbol(math, ams, bin, "\u229D", "\\circleddash", true); +defineSymbol(math, ams, bin, "\u229B", "\\circledast", true); +defineSymbol(math, ams, bin, "\u22C5", "\\centerdot"); +defineSymbol(math, ams, bin, "\u22BA", "\\intercal", true); +defineSymbol(math, ams, bin, "\u22D2", "\\doublecap"); +defineSymbol(math, ams, bin, "\u22D3", "\\doublecup"); +defineSymbol(math, ams, bin, "\u22A0", "\\boxtimes", true); // AMS Arrows +// Note: unicode-math maps \u21e2 to their own function \rightdasharrow. +// We'll map it to AMS function \dashrightarrow. It produces the same atom. + +defineSymbol(math, ams, rel, "\u21E2", "\\dashrightarrow", true); // unicode-math maps \u21e0 to \leftdasharrow. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u21E0", "\\dashleftarrow", true); +defineSymbol(math, ams, rel, "\u21C7", "\\leftleftarrows", true); +defineSymbol(math, ams, rel, "\u21C6", "\\leftrightarrows", true); +defineSymbol(math, ams, rel, "\u21DA", "\\Lleftarrow", true); +defineSymbol(math, ams, rel, "\u219E", "\\twoheadleftarrow", true); +defineSymbol(math, ams, rel, "\u21A2", "\\leftarrowtail", true); +defineSymbol(math, ams, rel, "\u21AB", "\\looparrowleft", true); +defineSymbol(math, ams, rel, "\u21CB", "\\leftrightharpoons", true); +defineSymbol(math, ams, rel, "\u21B6", "\\curvearrowleft", true); // unicode-math maps \u21ba to \acwopencirclearrow. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u21BA", "\\circlearrowleft", true); +defineSymbol(math, ams, rel, "\u21B0", "\\Lsh", true); +defineSymbol(math, ams, rel, "\u21C8", "\\upuparrows", true); +defineSymbol(math, ams, rel, "\u21BF", "\\upharpoonleft", true); +defineSymbol(math, ams, rel, "\u21C3", "\\downharpoonleft", true); +defineSymbol(math, main, rel, "\u22B6", "\\origof", true); // not in font + +defineSymbol(math, main, rel, "\u22B7", "\\imageof", true); // not in font + +defineSymbol(math, ams, rel, "\u22B8", "\\multimap", true); +defineSymbol(math, ams, rel, "\u21AD", "\\leftrightsquigarrow", true); +defineSymbol(math, ams, rel, "\u21C9", "\\rightrightarrows", true); +defineSymbol(math, ams, rel, "\u21C4", "\\rightleftarrows", true); +defineSymbol(math, ams, rel, "\u21A0", "\\twoheadrightarrow", true); +defineSymbol(math, ams, rel, "\u21A3", "\\rightarrowtail", true); +defineSymbol(math, ams, rel, "\u21AC", "\\looparrowright", true); +defineSymbol(math, ams, rel, "\u21B7", "\\curvearrowright", true); // unicode-math maps \u21bb to \cwopencirclearrow. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u21BB", "\\circlearrowright", true); +defineSymbol(math, ams, rel, "\u21B1", "\\Rsh", true); +defineSymbol(math, ams, rel, "\u21CA", "\\downdownarrows", true); +defineSymbol(math, ams, rel, "\u21BE", "\\upharpoonright", true); +defineSymbol(math, ams, rel, "\u21C2", "\\downharpoonright", true); +defineSymbol(math, ams, rel, "\u21DD", "\\rightsquigarrow", true); +defineSymbol(math, ams, rel, "\u21DD", "\\leadsto"); +defineSymbol(math, ams, rel, "\u21DB", "\\Rrightarrow", true); +defineSymbol(math, ams, rel, "\u21BE", "\\restriction"); +defineSymbol(math, main, textord, "\u2018", "`"); +defineSymbol(math, main, textord, "$", "\\$"); +defineSymbol(symbols_text, main, textord, "$", "\\$"); +defineSymbol(symbols_text, main, textord, "$", "\\textdollar"); +defineSymbol(math, main, textord, "%", "\\%"); +defineSymbol(symbols_text, main, textord, "%", "\\%"); +defineSymbol(math, main, textord, "_", "\\_"); +defineSymbol(symbols_text, main, textord, "_", "\\_"); +defineSymbol(symbols_text, main, textord, "_", "\\textunderscore"); +defineSymbol(math, main, textord, "\u2220", "\\angle", true); +defineSymbol(math, main, textord, "\u221E", "\\infty", true); +defineSymbol(math, main, textord, "\u2032", "\\prime"); +defineSymbol(math, main, textord, "\u25B3", "\\triangle"); +defineSymbol(math, main, textord, "\u0393", "\\Gamma", true); +defineSymbol(math, main, textord, "\u0394", "\\Delta", true); +defineSymbol(math, main, textord, "\u0398", "\\Theta", true); +defineSymbol(math, main, textord, "\u039B", "\\Lambda", true); +defineSymbol(math, main, textord, "\u039E", "\\Xi", true); +defineSymbol(math, main, textord, "\u03A0", "\\Pi", true); +defineSymbol(math, main, textord, "\u03A3", "\\Sigma", true); +defineSymbol(math, main, textord, "\u03A5", "\\Upsilon", true); +defineSymbol(math, main, textord, "\u03A6", "\\Phi", true); +defineSymbol(math, main, textord, "\u03A8", "\\Psi", true); +defineSymbol(math, main, textord, "\u03A9", "\\Omega", true); +defineSymbol(math, main, textord, "A", "\u0391"); +defineSymbol(math, main, textord, "B", "\u0392"); +defineSymbol(math, main, textord, "E", "\u0395"); +defineSymbol(math, main, textord, "Z", "\u0396"); +defineSymbol(math, main, textord, "H", "\u0397"); +defineSymbol(math, main, textord, "I", "\u0399"); +defineSymbol(math, main, textord, "K", "\u039A"); +defineSymbol(math, main, textord, "M", "\u039C"); +defineSymbol(math, main, textord, "N", "\u039D"); +defineSymbol(math, main, textord, "O", "\u039F"); +defineSymbol(math, main, textord, "P", "\u03A1"); +defineSymbol(math, main, textord, "T", "\u03A4"); +defineSymbol(math, main, textord, "X", "\u03A7"); +defineSymbol(math, main, textord, "\xAC", "\\neg", true); +defineSymbol(math, main, textord, "\xAC", "\\lnot"); +defineSymbol(math, main, textord, "\u22A4", "\\top"); +defineSymbol(math, main, textord, "\u22A5", "\\bot"); +defineSymbol(math, main, textord, "\u2205", "\\emptyset"); +defineSymbol(math, ams, textord, "\u2205", "\\varnothing"); +defineSymbol(math, main, mathord, "\u03B1", "\\alpha", true); +defineSymbol(math, main, mathord, "\u03B2", "\\beta", true); +defineSymbol(math, main, mathord, "\u03B3", "\\gamma", true); +defineSymbol(math, main, mathord, "\u03B4", "\\delta", true); +defineSymbol(math, main, mathord, "\u03F5", "\\epsilon", true); +defineSymbol(math, main, mathord, "\u03B6", "\\zeta", true); +defineSymbol(math, main, mathord, "\u03B7", "\\eta", true); +defineSymbol(math, main, mathord, "\u03B8", "\\theta", true); +defineSymbol(math, main, mathord, "\u03B9", "\\iota", true); +defineSymbol(math, main, mathord, "\u03BA", "\\kappa", true); +defineSymbol(math, main, mathord, "\u03BB", "\\lambda", true); +defineSymbol(math, main, mathord, "\u03BC", "\\mu", true); +defineSymbol(math, main, mathord, "\u03BD", "\\nu", true); +defineSymbol(math, main, mathord, "\u03BE", "\\xi", true); +defineSymbol(math, main, mathord, "\u03BF", "\\omicron", true); +defineSymbol(math, main, mathord, "\u03C0", "\\pi", true); +defineSymbol(math, main, mathord, "\u03C1", "\\rho", true); +defineSymbol(math, main, mathord, "\u03C3", "\\sigma", true); +defineSymbol(math, main, mathord, "\u03C4", "\\tau", true); +defineSymbol(math, main, mathord, "\u03C5", "\\upsilon", true); +defineSymbol(math, main, mathord, "\u03D5", "\\phi", true); +defineSymbol(math, main, mathord, "\u03C7", "\\chi", true); +defineSymbol(math, main, mathord, "\u03C8", "\\psi", true); +defineSymbol(math, main, mathord, "\u03C9", "\\omega", true); +defineSymbol(math, main, mathord, "\u03B5", "\\varepsilon", true); +defineSymbol(math, main, mathord, "\u03D1", "\\vartheta", true); +defineSymbol(math, main, mathord, "\u03D6", "\\varpi", true); +defineSymbol(math, main, mathord, "\u03F1", "\\varrho", true); +defineSymbol(math, main, mathord, "\u03C2", "\\varsigma", true); +defineSymbol(math, main, mathord, "\u03C6", "\\varphi", true); +defineSymbol(math, main, bin, "\u2217", "*", true); +defineSymbol(math, main, bin, "+", "+"); +defineSymbol(math, main, bin, "\u2212", "-", true); +defineSymbol(math, main, bin, "\u22C5", "\\cdot", true); +defineSymbol(math, main, bin, "\u2218", "\\circ"); +defineSymbol(math, main, bin, "\xF7", "\\div", true); +defineSymbol(math, main, bin, "\xB1", "\\pm", true); +defineSymbol(math, main, bin, "\xD7", "\\times", true); +defineSymbol(math, main, bin, "\u2229", "\\cap", true); +defineSymbol(math, main, bin, "\u222A", "\\cup", true); +defineSymbol(math, main, bin, "\u2216", "\\setminus"); +defineSymbol(math, main, bin, "\u2227", "\\land"); +defineSymbol(math, main, bin, "\u2228", "\\lor"); +defineSymbol(math, main, bin, "\u2227", "\\wedge", true); +defineSymbol(math, main, bin, "\u2228", "\\vee", true); +defineSymbol(math, main, textord, "\u221A", "\\surd"); +defineSymbol(math, main, symbols_open, "\u27E8", "\\langle", true); +defineSymbol(math, main, symbols_open, "\u2223", "\\lvert"); +defineSymbol(math, main, symbols_open, "\u2225", "\\lVert"); +defineSymbol(math, main, symbols_close, "?", "?"); +defineSymbol(math, main, symbols_close, "!", "!"); +defineSymbol(math, main, symbols_close, "\u27E9", "\\rangle", true); +defineSymbol(math, main, symbols_close, "\u2223", "\\rvert"); +defineSymbol(math, main, symbols_close, "\u2225", "\\rVert"); +defineSymbol(math, main, rel, "=", "="); +defineSymbol(math, main, rel, ":", ":"); +defineSymbol(math, main, rel, "\u2248", "\\approx", true); +defineSymbol(math, main, rel, "\u2245", "\\cong", true); +defineSymbol(math, main, rel, "\u2265", "\\ge"); +defineSymbol(math, main, rel, "\u2265", "\\geq", true); +defineSymbol(math, main, rel, "\u2190", "\\gets"); +defineSymbol(math, main, rel, ">", "\\gt", true); +defineSymbol(math, main, rel, "\u2208", "\\in", true); +defineSymbol(math, main, rel, "\uE020", "\\@not"); +defineSymbol(math, main, rel, "\u2282", "\\subset", true); +defineSymbol(math, main, rel, "\u2283", "\\supset", true); +defineSymbol(math, main, rel, "\u2286", "\\subseteq", true); +defineSymbol(math, main, rel, "\u2287", "\\supseteq", true); +defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq", true); +defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq", true); +defineSymbol(math, main, rel, "\u22A8", "\\models"); +defineSymbol(math, main, rel, "\u2190", "\\leftarrow", true); +defineSymbol(math, main, rel, "\u2264", "\\le"); +defineSymbol(math, main, rel, "\u2264", "\\leq", true); +defineSymbol(math, main, rel, "<", "\\lt", true); +defineSymbol(math, main, rel, "\u2192", "\\rightarrow", true); +defineSymbol(math, main, rel, "\u2192", "\\to"); +defineSymbol(math, ams, rel, "\u2271", "\\ngeq", true); +defineSymbol(math, ams, rel, "\u2270", "\\nleq", true); +defineSymbol(math, main, spacing, "\xA0", "\\ "); +defineSymbol(math, main, spacing, "\xA0", "\\space"); // Ref: LaTeX Source 2e: \DeclareRobustCommand{\nobreakspace}{% + +defineSymbol(math, main, spacing, "\xA0", "\\nobreakspace"); +defineSymbol(symbols_text, main, spacing, "\xA0", "\\ "); +defineSymbol(symbols_text, main, spacing, "\xA0", " "); +defineSymbol(symbols_text, main, spacing, "\xA0", "\\space"); +defineSymbol(symbols_text, main, spacing, "\xA0", "\\nobreakspace"); +defineSymbol(math, main, spacing, null, "\\nobreak"); +defineSymbol(math, main, spacing, null, "\\allowbreak"); +defineSymbol(math, main, punct, ",", ","); +defineSymbol(math, main, punct, ";", ";"); +defineSymbol(math, ams, bin, "\u22BC", "\\barwedge", true); +defineSymbol(math, ams, bin, "\u22BB", "\\veebar", true); +defineSymbol(math, main, bin, "\u2299", "\\odot", true); +defineSymbol(math, main, bin, "\u2295", "\\oplus", true); +defineSymbol(math, main, bin, "\u2297", "\\otimes", true); +defineSymbol(math, main, textord, "\u2202", "\\partial", true); +defineSymbol(math, main, bin, "\u2298", "\\oslash", true); +defineSymbol(math, ams, bin, "\u229A", "\\circledcirc", true); +defineSymbol(math, ams, bin, "\u22A1", "\\boxdot", true); +defineSymbol(math, main, bin, "\u25B3", "\\bigtriangleup"); +defineSymbol(math, main, bin, "\u25BD", "\\bigtriangledown"); +defineSymbol(math, main, bin, "\u2020", "\\dagger"); +defineSymbol(math, main, bin, "\u22C4", "\\diamond"); +defineSymbol(math, main, bin, "\u22C6", "\\star"); +defineSymbol(math, main, bin, "\u25C3", "\\triangleleft"); +defineSymbol(math, main, bin, "\u25B9", "\\triangleright"); +defineSymbol(math, main, symbols_open, "{", "\\{"); +defineSymbol(symbols_text, main, textord, "{", "\\{"); +defineSymbol(symbols_text, main, textord, "{", "\\textbraceleft"); +defineSymbol(math, main, symbols_close, "}", "\\}"); +defineSymbol(symbols_text, main, textord, "}", "\\}"); +defineSymbol(symbols_text, main, textord, "}", "\\textbraceright"); +defineSymbol(math, main, symbols_open, "{", "\\lbrace"); +defineSymbol(math, main, symbols_close, "}", "\\rbrace"); +defineSymbol(math, main, symbols_open, "[", "\\lbrack", true); +defineSymbol(symbols_text, main, textord, "[", "\\lbrack", true); +defineSymbol(math, main, symbols_close, "]", "\\rbrack", true); +defineSymbol(symbols_text, main, textord, "]", "\\rbrack", true); +defineSymbol(math, main, symbols_open, "(", "\\lparen", true); +defineSymbol(math, main, symbols_close, ")", "\\rparen", true); +defineSymbol(symbols_text, main, textord, "<", "\\textless", true); // in T1 fontenc + +defineSymbol(symbols_text, main, textord, ">", "\\textgreater", true); // in T1 fontenc + +defineSymbol(math, main, symbols_open, "\u230A", "\\lfloor", true); +defineSymbol(math, main, symbols_close, "\u230B", "\\rfloor", true); +defineSymbol(math, main, symbols_open, "\u2308", "\\lceil", true); +defineSymbol(math, main, symbols_close, "\u2309", "\\rceil", true); +defineSymbol(math, main, textord, "\\", "\\backslash"); +defineSymbol(math, main, textord, "\u2223", "|"); +defineSymbol(math, main, textord, "\u2223", "\\vert"); +defineSymbol(symbols_text, main, textord, "|", "\\textbar", true); // in T1 fontenc + +defineSymbol(math, main, textord, "\u2225", "\\|"); +defineSymbol(math, main, textord, "\u2225", "\\Vert"); +defineSymbol(symbols_text, main, textord, "\u2225", "\\textbardbl"); +defineSymbol(symbols_text, main, textord, "~", "\\textasciitilde"); +defineSymbol(symbols_text, main, textord, "\\", "\\textbackslash"); +defineSymbol(symbols_text, main, textord, "^", "\\textasciicircum"); +defineSymbol(math, main, rel, "\u2191", "\\uparrow", true); +defineSymbol(math, main, rel, "\u21D1", "\\Uparrow", true); +defineSymbol(math, main, rel, "\u2193", "\\downarrow", true); +defineSymbol(math, main, rel, "\u21D3", "\\Downarrow", true); +defineSymbol(math, main, rel, "\u2195", "\\updownarrow", true); +defineSymbol(math, main, rel, "\u21D5", "\\Updownarrow", true); +defineSymbol(math, main, op, "\u2210", "\\coprod"); +defineSymbol(math, main, op, "\u22C1", "\\bigvee"); +defineSymbol(math, main, op, "\u22C0", "\\bigwedge"); +defineSymbol(math, main, op, "\u2A04", "\\biguplus"); +defineSymbol(math, main, op, "\u22C2", "\\bigcap"); +defineSymbol(math, main, op, "\u22C3", "\\bigcup"); +defineSymbol(math, main, op, "\u222B", "\\int"); +defineSymbol(math, main, op, "\u222B", "\\intop"); +defineSymbol(math, main, op, "\u222C", "\\iint"); +defineSymbol(math, main, op, "\u222D", "\\iiint"); +defineSymbol(math, main, op, "\u220F", "\\prod"); +defineSymbol(math, main, op, "\u2211", "\\sum"); +defineSymbol(math, main, op, "\u2A02", "\\bigotimes"); +defineSymbol(math, main, op, "\u2A01", "\\bigoplus"); +defineSymbol(math, main, op, "\u2A00", "\\bigodot"); +defineSymbol(math, main, op, "\u222E", "\\oint"); +defineSymbol(math, main, op, "\u222F", "\\oiint"); +defineSymbol(math, main, op, "\u2230", "\\oiiint"); +defineSymbol(math, main, op, "\u2A06", "\\bigsqcup"); +defineSymbol(math, main, op, "\u222B", "\\smallint"); +defineSymbol(symbols_text, main, inner, "\u2026", "\\textellipsis"); +defineSymbol(math, main, inner, "\u2026", "\\mathellipsis"); +defineSymbol(symbols_text, main, inner, "\u2026", "\\ldots", true); +defineSymbol(math, main, inner, "\u2026", "\\ldots", true); +defineSymbol(math, main, inner, "\u22EF", "\\@cdots", true); +defineSymbol(math, main, inner, "\u22F1", "\\ddots", true); +defineSymbol(math, main, textord, "\u22EE", "\\varvdots"); // \vdots is a macro + +defineSymbol(math, main, accent, "\u02CA", "\\acute"); +defineSymbol(math, main, accent, "\u02CB", "\\grave"); +defineSymbol(math, main, accent, "\xA8", "\\ddot"); +defineSymbol(math, main, accent, "~", "\\tilde"); +defineSymbol(math, main, accent, "\u02C9", "\\bar"); +defineSymbol(math, main, accent, "\u02D8", "\\breve"); +defineSymbol(math, main, accent, "\u02C7", "\\check"); +defineSymbol(math, main, accent, "^", "\\hat"); +defineSymbol(math, main, accent, "\u20D7", "\\vec"); +defineSymbol(math, main, accent, "\u02D9", "\\dot"); +defineSymbol(math, main, accent, "\u02DA", "\\mathring"); // \imath and \jmath should be invariant to \mathrm, \mathbf, etc., so use PUA + +defineSymbol(math, main, mathord, "\uE131", "\\@imath"); +defineSymbol(math, main, mathord, "\uE237", "\\@jmath"); +defineSymbol(math, main, textord, "\u0131", "\u0131"); +defineSymbol(math, main, textord, "\u0237", "\u0237"); +defineSymbol(symbols_text, main, textord, "\u0131", "\\i", true); +defineSymbol(symbols_text, main, textord, "\u0237", "\\j", true); +defineSymbol(symbols_text, main, textord, "\xDF", "\\ss", true); +defineSymbol(symbols_text, main, textord, "\xE6", "\\ae", true); +defineSymbol(symbols_text, main, textord, "\u0153", "\\oe", true); +defineSymbol(symbols_text, main, textord, "\xF8", "\\o", true); +defineSymbol(symbols_text, main, textord, "\xC6", "\\AE", true); +defineSymbol(symbols_text, main, textord, "\u0152", "\\OE", true); +defineSymbol(symbols_text, main, textord, "\xD8", "\\O", true); +defineSymbol(symbols_text, main, accent, "\u02CA", "\\'"); // acute + +defineSymbol(symbols_text, main, accent, "\u02CB", "\\`"); // grave + +defineSymbol(symbols_text, main, accent, "\u02C6", "\\^"); // circumflex + +defineSymbol(symbols_text, main, accent, "\u02DC", "\\~"); // tilde + +defineSymbol(symbols_text, main, accent, "\u02C9", "\\="); // macron + +defineSymbol(symbols_text, main, accent, "\u02D8", "\\u"); // breve + +defineSymbol(symbols_text, main, accent, "\u02D9", "\\."); // dot above + +defineSymbol(symbols_text, main, accent, "\xB8", "\\c"); // cedilla + +defineSymbol(symbols_text, main, accent, "\u02DA", "\\r"); // ring above + +defineSymbol(symbols_text, main, accent, "\u02C7", "\\v"); // caron + +defineSymbol(symbols_text, main, accent, "\xA8", '\\"'); // diaresis + +defineSymbol(symbols_text, main, accent, "\u02DD", "\\H"); // double acute + +defineSymbol(symbols_text, main, accent, "\u25EF", "\\textcircled"); // \bigcirc glyph +// These ligatures are detected and created in Parser.js's `formLigatures`. + +var ligatures = { + "--": true, + "---": true, + "``": true, + "''": true +}; +defineSymbol(symbols_text, main, textord, "\u2013", "--", true); +defineSymbol(symbols_text, main, textord, "\u2013", "\\textendash"); +defineSymbol(symbols_text, main, textord, "\u2014", "---", true); +defineSymbol(symbols_text, main, textord, "\u2014", "\\textemdash"); +defineSymbol(symbols_text, main, textord, "\u2018", "`", true); +defineSymbol(symbols_text, main, textord, "\u2018", "\\textquoteleft"); +defineSymbol(symbols_text, main, textord, "\u2019", "'", true); +defineSymbol(symbols_text, main, textord, "\u2019", "\\textquoteright"); +defineSymbol(symbols_text, main, textord, "\u201C", "``", true); +defineSymbol(symbols_text, main, textord, "\u201C", "\\textquotedblleft"); +defineSymbol(symbols_text, main, textord, "\u201D", "''", true); +defineSymbol(symbols_text, main, textord, "\u201D", "\\textquotedblright"); // \degree from gensymb package + +defineSymbol(math, main, textord, "\xB0", "\\degree", true); +defineSymbol(symbols_text, main, textord, "\xB0", "\\degree"); // \textdegree from inputenc package + +defineSymbol(symbols_text, main, textord, "\xB0", "\\textdegree", true); // TODO: In LaTeX, \pounds can generate a different character in text and math +// mode, but among our fonts, only Main-Regular defines this character "163". + +defineSymbol(math, main, textord, "\xA3", "\\pounds"); +defineSymbol(math, main, textord, "\xA3", "\\mathsterling", true); +defineSymbol(symbols_text, main, textord, "\xA3", "\\pounds"); +defineSymbol(symbols_text, main, textord, "\xA3", "\\textsterling", true); +defineSymbol(math, ams, textord, "\u2720", "\\maltese"); +defineSymbol(symbols_text, ams, textord, "\u2720", "\\maltese"); // There are lots of symbols which are the same, so we add them in afterwards. +// All of these are textords in math mode + +var mathTextSymbols = "0123456789/@.\""; + +for (var i = 0; i < mathTextSymbols.length; i++) { + var ch = mathTextSymbols.charAt(i); + defineSymbol(math, main, textord, ch, ch); +} // All of these are textords in text mode + + +var textSymbols = "0123456789!@*()-=+\";:?/.,"; + +for (var _i = 0; _i < textSymbols.length; _i++) { + var _ch = textSymbols.charAt(_i); + + defineSymbol(symbols_text, main, textord, _ch, _ch); +} // All of these are textords in text mode, and mathords in math mode + + +var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +for (var _i2 = 0; _i2 < letters.length; _i2++) { + var _ch2 = letters.charAt(_i2); + + defineSymbol(math, main, mathord, _ch2, _ch2); + defineSymbol(symbols_text, main, textord, _ch2, _ch2); +} // Blackboard bold and script letters in Unicode range + + +defineSymbol(math, ams, textord, "C", "\u2102"); // blackboard bold + +defineSymbol(symbols_text, ams, textord, "C", "\u2102"); +defineSymbol(math, ams, textord, "H", "\u210D"); +defineSymbol(symbols_text, ams, textord, "H", "\u210D"); +defineSymbol(math, ams, textord, "N", "\u2115"); +defineSymbol(symbols_text, ams, textord, "N", "\u2115"); +defineSymbol(math, ams, textord, "P", "\u2119"); +defineSymbol(symbols_text, ams, textord, "P", "\u2119"); +defineSymbol(math, ams, textord, "Q", "\u211A"); +defineSymbol(symbols_text, ams, textord, "Q", "\u211A"); +defineSymbol(math, ams, textord, "R", "\u211D"); +defineSymbol(symbols_text, ams, textord, "R", "\u211D"); +defineSymbol(math, ams, textord, "Z", "\u2124"); +defineSymbol(symbols_text, ams, textord, "Z", "\u2124"); +defineSymbol(math, main, mathord, "h", "\u210E"); // italic h, Planck constant + +defineSymbol(symbols_text, main, mathord, "h", "\u210E"); // The next loop loads wide (surrogate pair) characters. +// We support some letters in the Unicode range U+1D400 to U+1D7FF, +// Mathematical Alphanumeric Symbols. +// Some editors do not deal well with wide characters. So don't write the +// string into this file. Instead, create the string from the surrogate pair. + +var wideChar = ""; + +for (var _i3 = 0; _i3 < letters.length; _i3++) { + var _ch3 = letters.charAt(_i3); // The hex numbers in the next line are a surrogate pair. + // 0xD835 is the high surrogate for all letters in the range we support. + // 0xDC00 is the low surrogate for bold A. + + + wideChar = String.fromCharCode(0xD835, 0xDC00 + _i3); // A-Z a-z bold + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDC34 + _i3); // A-Z a-z italic + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDC68 + _i3); // A-Z a-z bold italic + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDD04 + _i3); // A-Z a-z Fractur + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDDA0 + _i3); // A-Z a-z sans-serif + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDDD4 + _i3); // A-Z a-z sans bold + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDE08 + _i3); // A-Z a-z sans italic + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDE70 + _i3); // A-Z a-z monospace + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + + if (_i3 < 26) { + // KaTeX fonts have only capital letters for blackboard bold and script. + // See exception for k below. + wideChar = String.fromCharCode(0xD835, 0xDD38 + _i3); // A-Z double struck + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDC9C + _i3); // A-Z script + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(symbols_text, main, textord, _ch3, wideChar); + } // TODO: Add bold script when it is supported by a KaTeX font. + +} // "k" is the only double struck lower case letter in the KaTeX fonts. + + +wideChar = String.fromCharCode(0xD835, 0xDD5C); // k double struck + +defineSymbol(math, main, mathord, "k", wideChar); +defineSymbol(symbols_text, main, textord, "k", wideChar); // Next, some wide character numerals + +for (var _i4 = 0; _i4 < 10; _i4++) { + var _ch4 = _i4.toString(); + + wideChar = String.fromCharCode(0xD835, 0xDFCE + _i4); // 0-9 bold + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(symbols_text, main, textord, _ch4, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDFE2 + _i4); // 0-9 sans serif + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(symbols_text, main, textord, _ch4, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDFEC + _i4); // 0-9 bold sans + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(symbols_text, main, textord, _ch4, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDFF6 + _i4); // 0-9 monospace + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(symbols_text, main, textord, _ch4, wideChar); +} // We add these Latin-1 letters as symbols for backwards-compatibility, +// but they are not actually in the font, nor are they supported by the +// Unicode accent mechanism, so they fall back to Times font and look ugly. +// TODO(edemaine): Fix this. + + +var extraLatin = "\xD0\xDE\xFE"; + +for (var _i5 = 0; _i5 < extraLatin.length; _i5++) { + var _ch5 = extraLatin.charAt(_i5); + + defineSymbol(math, main, mathord, _ch5, _ch5); + defineSymbol(symbols_text, main, textord, _ch5, _ch5); +} +/** + * This file provides support for Unicode range U+1D400 to U+1D7FF, + * Mathematical Alphanumeric Symbols. + * + * Function wideCharacterFont takes a wide character as input and returns + * the font information necessary to render it properly. + */ + +/** + * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf + * That document sorts characters into groups by font type, say bold or italic. + * + * In the arrays below, each subarray consists three elements: + * * The CSS class of that group when in math mode. + * * The CSS class of that group when in text mode. + * * The font name, so that KaTeX can get font metrics. + */ + +var wideLatinLetterData = [["mathbf", "textbf", "Main-Bold"], // A-Z bold upright +["mathbf", "textbf", "Main-Bold"], // a-z bold upright +["mathnormal", "textit", "Math-Italic"], // A-Z italic +["mathnormal", "textit", "Math-Italic"], // a-z italic +["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic +["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic +// Map fancy A-Z letters to script, not calligraphic. +// This aligns with unicode-math and math fonts (except Cambria Math). +["mathscr", "textscr", "Script-Regular"], // A-Z script +["", "", ""], // a-z script. No font +["", "", ""], // A-Z bold script. No font +["", "", ""], // a-z bold script. No font +["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur +["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur +["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck +["mathbb", "textbb", "AMS-Regular"], // k double-struck +["", "", ""], // A-Z bold Fraktur No font metrics +["", "", ""], // a-z bold Fraktur. No font. +["mathsf", "textsf", "SansSerif-Regular"], // A-Z sans-serif +["mathsf", "textsf", "SansSerif-Regular"], // a-z sans-serif +["mathboldsf", "textboldsf", "SansSerif-Bold"], // A-Z bold sans-serif +["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif +["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif +["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif +["", "", ""], // A-Z bold italic sans. No font +["", "", ""], // a-z bold italic sans. No font +["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace +["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace +]; +var wideNumeralData = [["mathbf", "textbf", "Main-Bold"], // 0-9 bold +["", "", ""], // 0-9 double-struck. No KaTeX font. +["mathsf", "textsf", "SansSerif-Regular"], // 0-9 sans-serif +["mathboldsf", "textboldsf", "SansSerif-Bold"], // 0-9 bold sans-serif +["mathtt", "texttt", "Typewriter-Regular"] // 0-9 monospace +]; +var wideCharacterFont = function wideCharacterFont(wideChar, mode) { + // IE doesn't support codePointAt(). So work with the surrogate pair. + var H = wideChar.charCodeAt(0); // high surrogate + + var L = wideChar.charCodeAt(1); // low surrogate + + var codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000; + var j = mode === "math" ? 0 : 1; // column index for CSS class. + + if (0x1D400 <= codePoint && codePoint < 0x1D6A4) { + // wideLatinLetterData contains exactly 26 chars on each row. + // So we can calculate the relevant row. No traverse necessary. + var i = Math.floor((codePoint - 0x1D400) / 26); + return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]]; + } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) { + // Numerals, ten per row. + var _i = Math.floor((codePoint - 0x1D7CE) / 10); + + return [wideNumeralData[_i][2], wideNumeralData[_i][j]]; + } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) { + // dotless i or j + return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]]; + } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) { + // Greek letters. Not supported, yet. + return ["", ""]; + } else { + // We don't support any wide characters outside 1D400–1D7FF. + throw new src_ParseError("Unsupported character: " + wideChar); + } +}; +/* eslint no-console:0 */ + +/** + * This module contains general functions that can be used for building + * different kinds of domTree nodes in a consistent manner. + */ + + + + + + + +/** + * Looks up the given symbol in fontMetrics, after applying any symbol + * replacements defined in symbol.js + */ +var lookupSymbol = function lookupSymbol(value, // TODO(#963): Use a union type for this. +fontName, mode) { + // Replace the value with its replaced value from symbol.js + if (src_symbols[mode][value] && src_symbols[mode][value].replace) { + value = src_symbols[mode][value].replace; + } + + return { + value: value, + metrics: getCharacterMetrics(value, fontName, mode) + }; +}; +/** + * Makes a symbolNode after translation via the list of symbols in symbols.js. + * Correctly pulls out metrics for the character, and optionally takes a list of + * classes to be attached to the node. + * + * TODO: make argument order closer to makeSpan + * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which + * should if present come first in `classes`. + * TODO(#953): Make `options` mandatory and always pass it in. + */ + + +var makeSymbol = function makeSymbol(value, fontName, mode, options, classes) { + var lookup = lookupSymbol(value, fontName, mode); + var metrics = lookup.metrics; + value = lookup.value; + var symbolNode; + + if (metrics) { + var italic = metrics.italic; + + if (mode === "text" || options && options.font === "mathit") { + italic = 0; + } + + symbolNode = new SymbolNode(value, metrics.height, metrics.depth, italic, metrics.skew, metrics.width, classes); + } else { + // TODO(emily): Figure out a good way to only print this in development + typeof console !== "undefined" && console.warn("No character metrics " + ("for '" + value + "' in style '" + fontName + "' and mode '" + mode + "'")); + symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes); + } + + if (options) { + symbolNode.maxFontSize = options.sizeMultiplier; + + if (options.style.isTight()) { + symbolNode.classes.push("mtight"); + } + + var color = options.getColor(); + + if (color) { + symbolNode.style.color = color; + } + } + + return symbolNode; +}; +/** + * Makes a symbol in Main-Regular or AMS-Regular. + * Used for rel, bin, open, close, inner, and punct. + */ + + +var mathsym = function mathsym(value, mode, options, classes) { + if (classes === void 0) { + classes = []; + } + + // Decide what font to render the symbol in by its entry in the symbols + // table. + // Have a special case for when the value = \ because the \ is used as a + // textord in unsupported command errors but cannot be parsed as a regular + // text ordinal and is therefore not present as a symbol in the symbols + // table for text, as well as a special case for boldsymbol because it + // can be used for bold + and - + if (options.font === "boldsymbol" && lookupSymbol(value, "Main-Bold", mode).metrics) { + return makeSymbol(value, "Main-Bold", mode, options, classes.concat(["mathbf"])); + } else if (value === "\\" || src_symbols[mode][value].font === "main") { + return makeSymbol(value, "Main-Regular", mode, options, classes); + } else { + return makeSymbol(value, "AMS-Regular", mode, options, classes.concat(["amsrm"])); + } +}; +/** + * Determines which of the two font names (Main-Bold and Math-BoldItalic) and + * corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol", + * depending on the symbol. Use this function instead of fontMap for font + * "boldsymbol". + */ + + +var boldsymbol = function boldsymbol(value, mode, options, classes, type) { + if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) { + return { + fontName: "Math-BoldItalic", + fontClass: "boldsymbol" + }; + } else { + // Some glyphs do not exist in Math-BoldItalic so we need to use + // Main-Bold instead. + return { + fontName: "Main-Bold", + fontClass: "mathbf" + }; + } +}; +/** + * Makes either a mathord or textord in the correct font and color. + */ + + +var makeOrd = function makeOrd(group, options, type) { + var mode = group.mode; + var text = group.text; + var classes = ["mord"]; // Math mode or Old font (i.e. \rm) + + var isFont = mode === "math" || mode === "text" && options.font; + var fontOrFamily = isFont ? options.font : options.fontFamily; + + if (text.charCodeAt(0) === 0xD835) { + // surrogate pairs get special treatment + var _wideCharacterFont = wideCharacterFont(text, mode), + wideFontName = _wideCharacterFont[0], + wideFontClass = _wideCharacterFont[1]; + + return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass)); + } else if (fontOrFamily) { + var fontName; + var fontClasses; + + if (fontOrFamily === "boldsymbol") { + var fontData = boldsymbol(text, mode, options, classes, type); + fontName = fontData.fontName; + fontClasses = [fontData.fontClass]; + } else if (isFont) { + fontName = fontMap[fontOrFamily].fontName; + fontClasses = [fontOrFamily]; + } else { + fontName = retrieveTextFontName(fontOrFamily, options.fontWeight, options.fontShape); + fontClasses = [fontOrFamily, options.fontWeight, options.fontShape]; + } + + if (lookupSymbol(text, fontName, mode).metrics) { + return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses)); + } else if (ligatures.hasOwnProperty(text) && fontName.substr(0, 10) === "Typewriter") { + // Deconstruct ligatures in monospace fonts (\texttt, \tt). + var parts = []; + + for (var i = 0; i < text.length; i++) { + parts.push(makeSymbol(text[i], fontName, mode, options, classes.concat(fontClasses))); + } + + return makeFragment(parts); + } + } // Makes a symbol in the default font for mathords and textords. + + + if (type === "mathord") { + return makeSymbol(text, "Math-Italic", mode, options, classes.concat(["mathnormal"])); + } else if (type === "textord") { + var font = src_symbols[mode][text] && src_symbols[mode][text].font; + + if (font === "ams") { + var _fontName = retrieveTextFontName("amsrm", options.fontWeight, options.fontShape); + + return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", options.fontWeight, options.fontShape)); + } else if (font === "main" || !font) { + var _fontName2 = retrieveTextFontName("textrm", options.fontWeight, options.fontShape); + + return makeSymbol(text, _fontName2, mode, options, classes.concat(options.fontWeight, options.fontShape)); + } else { + // fonts added by plugins + var _fontName3 = retrieveTextFontName(font, options.fontWeight, options.fontShape); // We add font name as a css class + + + return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, options.fontWeight, options.fontShape)); + } + } else { + throw new Error("unexpected type: " + type + " in makeOrd"); + } +}; +/** + * Returns true if subsequent symbolNodes have the same classes, skew, maxFont, + * and styles. + */ + + +var canCombine = function canCombine(prev, next) { + if (createClass(prev.classes) !== createClass(next.classes) || prev.skew !== next.skew || prev.maxFontSize !== next.maxFontSize) { + return false; + } // If prev and next both are just "mbin"s or "mord"s we don't combine them + // so that the proper spacing can be preserved. + + + if (prev.classes.length === 1) { + var cls = prev.classes[0]; + + if (cls === "mbin" || cls === "mord") { + return false; + } + } + + for (var style in prev.style) { + if (prev.style.hasOwnProperty(style) && prev.style[style] !== next.style[style]) { + return false; + } + } + + for (var _style in next.style) { + if (next.style.hasOwnProperty(_style) && prev.style[_style] !== next.style[_style]) { + return false; + } + } + + return true; +}; +/** + * Combine consecutive domTree.symbolNodes into a single symbolNode. + * Note: this function mutates the argument. + */ + + +var tryCombineChars = function tryCombineChars(chars) { + for (var i = 0; i < chars.length - 1; i++) { + var prev = chars[i]; + var next = chars[i + 1]; + + if (prev instanceof SymbolNode && next instanceof SymbolNode && canCombine(prev, next)) { + prev.text += next.text; + prev.height = Math.max(prev.height, next.height); + prev.depth = Math.max(prev.depth, next.depth); // Use the last character's italic correction since we use + // it to add padding to the right of the span created from + // the combined characters. + + prev.italic = next.italic; + chars.splice(i + 1, 1); + i--; + } + } + + return chars; +}; +/** + * Calculate the height, depth, and maxFontSize of an element based on its + * children. + */ + + +var sizeElementFromChildren = function sizeElementFromChildren(elem) { + var height = 0; + var depth = 0; + var maxFontSize = 0; + + for (var i = 0; i < elem.children.length; i++) { + var child = elem.children[i]; + + if (child.height > height) { + height = child.height; + } + + if (child.depth > depth) { + depth = child.depth; + } + + if (child.maxFontSize > maxFontSize) { + maxFontSize = child.maxFontSize; + } + } + + elem.height = height; + elem.depth = depth; + elem.maxFontSize = maxFontSize; +}; +/** + * Makes a span with the given list of classes, list of children, and options. + * + * TODO(#953): Ensure that `options` is always provided (currently some call + * sites don't pass it) and make the type below mandatory. + * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which + * should if present come first in `classes`. + */ + + +var makeSpan = function makeSpan(classes, children, options, style) { + var span = new Span(classes, children, options, style); + sizeElementFromChildren(span); + return span; +}; // SVG one is simpler -- doesn't require height, depth, max-font setting. +// This is also a separate method for typesafety. + + +var makeSvgSpan = function makeSvgSpan(classes, children, options, style) { + return new Span(classes, children, options, style); +}; + +var makeLineSpan = function makeLineSpan(className, options, thickness) { + var line = makeSpan([className], [], options); + line.height = Math.max(thickness || options.fontMetrics().defaultRuleThickness, options.minRuleThickness); + line.style.borderBottomWidth = makeEm(line.height); + line.maxFontSize = 1.0; + return line; +}; +/** + * Makes an anchor with the given href, list of classes, list of children, + * and options. + */ + + +var makeAnchor = function makeAnchor(href, classes, children, options) { + var anchor = new Anchor(href, classes, children, options); + sizeElementFromChildren(anchor); + return anchor; +}; +/** + * Makes a document fragment with the given list of children. + */ + + +var makeFragment = function makeFragment(children) { + var fragment = new DocumentFragment(children); + sizeElementFromChildren(fragment); + return fragment; +}; +/** + * Wraps group in a span if it's a document fragment, allowing to apply classes + * and styles + */ + + +var wrapFragment = function wrapFragment(group, options) { + if (group instanceof DocumentFragment) { + return makeSpan([], [group], options); + } + + return group; +}; // These are exact object types to catch typos in the names of the optional fields. + + +// Computes the updated `children` list and the overall depth. +// +// This helper function for makeVList makes it easier to enforce type safety by +// allowing early exits (returns) in the logic. +var getVListChildrenAndDepth = function getVListChildrenAndDepth(params) { + if (params.positionType === "individualShift") { + var oldChildren = params.children; + var children = [oldChildren[0]]; // Add in kerns to the list of params.children to get each element to be + // shifted to the correct specified shift + + var _depth = -oldChildren[0].shift - oldChildren[0].elem.depth; + + var currPos = _depth; + + for (var i = 1; i < oldChildren.length; i++) { + var diff = -oldChildren[i].shift - currPos - oldChildren[i].elem.depth; + var size = diff - (oldChildren[i - 1].elem.height + oldChildren[i - 1].elem.depth); + currPos = currPos + diff; + children.push({ + type: "kern", + size: size + }); + children.push(oldChildren[i]); + } + + return { + children: children, + depth: _depth + }; + } + + var depth; + + if (params.positionType === "top") { + // We always start at the bottom, so calculate the bottom by adding up + // all the sizes + var bottom = params.positionData; + + for (var _i = 0; _i < params.children.length; _i++) { + var child = params.children[_i]; + bottom -= child.type === "kern" ? child.size : child.elem.height + child.elem.depth; + } + + depth = bottom; + } else if (params.positionType === "bottom") { + depth = -params.positionData; + } else { + var firstChild = params.children[0]; + + if (firstChild.type !== "elem") { + throw new Error('First child must have type "elem".'); + } + + if (params.positionType === "shift") { + depth = -firstChild.elem.depth - params.positionData; + } else if (params.positionType === "firstBaseline") { + depth = -firstChild.elem.depth; + } else { + throw new Error("Invalid positionType " + params.positionType + "."); + } + } + + return { + children: params.children, + depth: depth + }; +}; +/** + * Makes a vertical list by stacking elements and kerns on top of each other. + * Allows for many different ways of specifying the positioning method. + * + * See VListParam documentation above. + */ + + +var makeVList = function makeVList(params, options) { + var _getVListChildrenAndD = getVListChildrenAndDepth(params), + children = _getVListChildrenAndD.children, + depth = _getVListChildrenAndD.depth; // Create a strut that is taller than any list item. The strut is added to + // each item, where it will determine the item's baseline. Since it has + // `overflow:hidden`, the strut's top edge will sit on the item's line box's + // top edge and the strut's bottom edge will sit on the item's baseline, + // with no additional line-height spacing. This allows the item baseline to + // be positioned precisely without worrying about font ascent and + // line-height. + + + var pstrutSize = 0; + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + + if (child.type === "elem") { + var elem = child.elem; + pstrutSize = Math.max(pstrutSize, elem.maxFontSize, elem.height); + } + } + + pstrutSize += 2; + var pstrut = makeSpan(["pstrut"], []); + pstrut.style.height = makeEm(pstrutSize); // Create a new list of actual children at the correct offsets + + var realChildren = []; + var minPos = depth; + var maxPos = depth; + var currPos = depth; + + for (var _i2 = 0; _i2 < children.length; _i2++) { + var _child = children[_i2]; + + if (_child.type === "kern") { + currPos += _child.size; + } else { + var _elem = _child.elem; + var classes = _child.wrapperClasses || []; + var style = _child.wrapperStyle || {}; + var childWrap = makeSpan(classes, [pstrut, _elem], undefined, style); + childWrap.style.top = makeEm(-pstrutSize - currPos - _elem.depth); + + if (_child.marginLeft) { + childWrap.style.marginLeft = _child.marginLeft; + } + + if (_child.marginRight) { + childWrap.style.marginRight = _child.marginRight; + } + + realChildren.push(childWrap); + currPos += _elem.height + _elem.depth; + } + + minPos = Math.min(minPos, currPos); + maxPos = Math.max(maxPos, currPos); + } // The vlist contents go in a table-cell with `vertical-align:bottom`. + // This cell's bottom edge will determine the containing table's baseline + // without overly expanding the containing line-box. + + + var vlist = makeSpan(["vlist"], realChildren); + vlist.style.height = makeEm(maxPos); // A second row is used if necessary to represent the vlist's depth. + + var rows; + + if (minPos < 0) { + // We will define depth in an empty span with display: table-cell. + // It should render with the height that we define. But Chrome, in + // contenteditable mode only, treats that span as if it contains some + // text content. And that min-height over-rides our desired height. + // So we put another empty span inside the depth strut span. + var emptySpan = makeSpan([], []); + var depthStrut = makeSpan(["vlist"], [emptySpan]); + depthStrut.style.height = makeEm(-minPos); // Safari wants the first row to have inline content; otherwise it + // puts the bottom of the *second* row on the baseline. + + var topStrut = makeSpan(["vlist-s"], [new SymbolNode("\u200B")]); + rows = [makeSpan(["vlist-r"], [vlist, topStrut]), makeSpan(["vlist-r"], [depthStrut])]; + } else { + rows = [makeSpan(["vlist-r"], [vlist])]; + } + + var vtable = makeSpan(["vlist-t"], rows); + + if (rows.length === 2) { + vtable.classes.push("vlist-t2"); + } + + vtable.height = maxPos; + vtable.depth = -minPos; + return vtable; +}; // Glue is a concept from TeX which is a flexible space between elements in +// either a vertical or horizontal list. In KaTeX, at least for now, it's +// static space between elements in a horizontal layout. + + +var makeGlue = function makeGlue(measurement, options) { + // Make an empty span for the space + var rule = makeSpan(["mspace"], [], options); + var size = calculateSize(measurement, options); + rule.style.marginRight = makeEm(size); + return rule; +}; // Takes font options, and returns the appropriate fontLookup name + + +var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight, fontShape) { + var baseFontName = ""; + + switch (fontFamily) { + case "amsrm": + baseFontName = "AMS"; + break; + + case "textrm": + baseFontName = "Main"; + break; + + case "textsf": + baseFontName = "SansSerif"; + break; + + case "texttt": + baseFontName = "Typewriter"; + break; + + default: + baseFontName = fontFamily; + // use fonts added by a plugin + } + + var fontStylesName; + + if (fontWeight === "textbf" && fontShape === "textit") { + fontStylesName = "BoldItalic"; + } else if (fontWeight === "textbf") { + fontStylesName = "Bold"; + } else if (fontWeight === "textit") { + fontStylesName = "Italic"; + } else { + fontStylesName = "Regular"; + } + + return baseFontName + "-" + fontStylesName; +}; +/** + * Maps TeX font commands to objects containing: + * - variant: string used for "mathvariant" attribute in buildMathML.js + * - fontName: the "style" parameter to fontMetrics.getCharacterMetrics + */ +// A map between tex font commands an MathML mathvariant attribute values + + +var fontMap = { + // styles + "mathbf": { + variant: "bold", + fontName: "Main-Bold" + }, + "mathrm": { + variant: "normal", + fontName: "Main-Regular" + }, + "textit": { + variant: "italic", + fontName: "Main-Italic" + }, + "mathit": { + variant: "italic", + fontName: "Main-Italic" + }, + "mathnormal": { + variant: "italic", + fontName: "Math-Italic" + }, + // "boldsymbol" is missing because they require the use of multiple fonts: + // Math-BoldItalic and Main-Bold. This is handled by a special case in + // makeOrd which ends up calling boldsymbol. + // families + "mathbb": { + variant: "double-struck", + fontName: "AMS-Regular" + }, + "mathcal": { + variant: "script", + fontName: "Caligraphic-Regular" + }, + "mathfrak": { + variant: "fraktur", + fontName: "Fraktur-Regular" + }, + "mathscr": { + variant: "script", + fontName: "Script-Regular" + }, + "mathsf": { + variant: "sans-serif", + fontName: "SansSerif-Regular" + }, + "mathtt": { + variant: "monospace", + fontName: "Typewriter-Regular" + } +}; +var svgData = { + // path, width, height + vec: ["vec", 0.471, 0.714], + // values from the font glyph + oiintSize1: ["oiintSize1", 0.957, 0.499], + // oval to overlay the integrand + oiintSize2: ["oiintSize2", 1.472, 0.659], + oiiintSize1: ["oiiintSize1", 1.304, 0.499], + oiiintSize2: ["oiiintSize2", 1.98, 0.659] +}; + +var staticSvg = function staticSvg(value, options) { + // Create a span with inline SVG for the element. + var _svgData$value = svgData[value], + pathName = _svgData$value[0], + width = _svgData$value[1], + height = _svgData$value[2]; + var path = new PathNode(pathName); + var svgNode = new SvgNode([path], { + "width": makeEm(width), + "height": makeEm(height), + // Override CSS rule `.katex svg { width: 100% }` + "style": "width:" + makeEm(width), + "viewBox": "0 0 " + 1000 * width + " " + 1000 * height, + "preserveAspectRatio": "xMinYMin" + }); + var span = makeSvgSpan(["overlay"], [svgNode], options); + span.height = height; + span.style.height = makeEm(height); + span.style.width = makeEm(width); + return span; +}; + +/* harmony default export */ var buildCommon = ({ + fontMap: fontMap, + makeSymbol: makeSymbol, + mathsym: mathsym, + makeSpan: makeSpan, + makeSvgSpan: makeSvgSpan, + makeLineSpan: makeLineSpan, + makeAnchor: makeAnchor, + makeFragment: makeFragment, + wrapFragment: wrapFragment, + makeVList: makeVList, + makeOrd: makeOrd, + makeGlue: makeGlue, + staticSvg: staticSvg, + svgData: svgData, + tryCombineChars: tryCombineChars +}); +/** + * Describes spaces between different classes of atoms. + */ +var thinspace = { + number: 3, + unit: "mu" +}; +var mediumspace = { + number: 4, + unit: "mu" +}; +var thickspace = { + number: 5, + unit: "mu" +}; // Making the type below exact with all optional fields doesn't work due to +// - https://github.com/facebook/flow/issues/4582 +// - https://github.com/facebook/flow/issues/5688 +// However, since *all* fields are optional, $Shape<> works as suggested in 5688 +// above. + +// Spacing relationships for display and text styles +var spacings = { + mord: { + mop: thinspace, + mbin: mediumspace, + mrel: thickspace, + minner: thinspace + }, + mop: { + mord: thinspace, + mop: thinspace, + mrel: thickspace, + minner: thinspace + }, + mbin: { + mord: mediumspace, + mop: mediumspace, + mopen: mediumspace, + minner: mediumspace + }, + mrel: { + mord: thickspace, + mop: thickspace, + mopen: thickspace, + minner: thickspace + }, + mopen: {}, + mclose: { + mop: thinspace, + mbin: mediumspace, + mrel: thickspace, + minner: thinspace + }, + mpunct: { + mord: thinspace, + mop: thinspace, + mrel: thickspace, + mopen: thinspace, + mclose: thinspace, + mpunct: thinspace, + minner: thinspace + }, + minner: { + mord: thinspace, + mop: thinspace, + mbin: mediumspace, + mrel: thickspace, + mopen: thinspace, + mpunct: thinspace, + minner: thinspace + } +}; // Spacing relationships for script and scriptscript styles + +var tightSpacings = { + mord: { + mop: thinspace + }, + mop: { + mord: thinspace, + mop: thinspace + }, + mbin: {}, + mrel: {}, + mopen: {}, + mclose: { + mop: thinspace + }, + mpunct: {}, + minner: { + mop: thinspace + } +}; +/** Context provided to function handlers for error messages. */ +// Note: reverse the order of the return type union will cause a flow error. +// See https://github.com/facebook/flow/issues/3663. +// More general version of `HtmlBuilder` for nodes (e.g. \sum, accent types) +// whose presence impacts super/subscripting. In this case, ParseNode<"supsub"> +// delegates its HTML building to the HtmlBuilder corresponding to these nodes. + +/** + * Final function spec for use at parse time. + * This is almost identical to `FunctionPropSpec`, except it + * 1. includes the function handler, and + * 2. requires all arguments except argTypes. + * It is generated by `defineFunction()` below. + */ + +/** + * All registered functions. + * `functions.js` just exports this same dictionary again and makes it public. + * `Parser.js` requires this dictionary. + */ +var _functions = {}; +/** + * All HTML builders. Should be only used in the `define*` and the `build*ML` + * functions. + */ + +var _htmlGroupBuilders = {}; +/** + * All MathML builders. Should be only used in the `define*` and the `build*ML` + * functions. + */ + +var _mathmlGroupBuilders = {}; +function defineFunction(_ref) { + var type = _ref.type, + names = _ref.names, + props = _ref.props, + handler = _ref.handler, + htmlBuilder = _ref.htmlBuilder, + mathmlBuilder = _ref.mathmlBuilder; + // Set default values of functions + var data = { + type: type, + numArgs: props.numArgs, + argTypes: props.argTypes, + allowedInArgument: !!props.allowedInArgument, + allowedInText: !!props.allowedInText, + allowedInMath: props.allowedInMath === undefined ? true : props.allowedInMath, + numOptionalArgs: props.numOptionalArgs || 0, + infix: !!props.infix, + primitive: !!props.primitive, + handler: handler + }; + + for (var i = 0; i < names.length; ++i) { + _functions[names[i]] = data; + } + + if (type) { + if (htmlBuilder) { + _htmlGroupBuilders[type] = htmlBuilder; + } + + if (mathmlBuilder) { + _mathmlGroupBuilders[type] = mathmlBuilder; + } + } +} +/** + * Use this to register only the HTML and MathML builders for a function (e.g. + * if the function's ParseNode is generated in Parser.js rather than via a + * stand-alone handler provided to `defineFunction`). + */ + +function defineFunctionBuilders(_ref2) { + var type = _ref2.type, + htmlBuilder = _ref2.htmlBuilder, + mathmlBuilder = _ref2.mathmlBuilder; + defineFunction({ + type: type, + names: [], + props: { + numArgs: 0 + }, + handler: function handler() { + throw new Error('Should never be called.'); + }, + htmlBuilder: htmlBuilder, + mathmlBuilder: mathmlBuilder + }); +} +var normalizeArgument = function normalizeArgument(arg) { + return arg.type === "ordgroup" && arg.body.length === 1 ? arg.body[0] : arg; +}; // Since the corresponding buildHTML/buildMathML function expects a +// list of elements, we normalize for different kinds of arguments + +var ordargument = function ordargument(arg) { + return arg.type === "ordgroup" ? arg.body : [arg]; +}; +/** + * This file does the main work of building a domTree structure from a parse + * tree. The entry point is the `buildHTML` function, which takes a parse tree. + * Then, the buildExpression, buildGroup, and various groupBuilders functions + * are called, to produce a final HTML tree. + */ + + + + + + + + + +var buildHTML_makeSpan = buildCommon.makeSpan; // Binary atoms (first class `mbin`) change into ordinary atoms (`mord`) +// depending on their surroundings. See TeXbook pg. 442-446, Rules 5 and 6, +// and the text before Rule 19. + +var binLeftCanceller = ["leftmost", "mbin", "mopen", "mrel", "mop", "mpunct"]; +var binRightCanceller = ["rightmost", "mrel", "mclose", "mpunct"]; +var styleMap = { + "display": src_Style.DISPLAY, + "text": src_Style.TEXT, + "script": src_Style.SCRIPT, + "scriptscript": src_Style.SCRIPTSCRIPT +}; +var DomEnum = { + mord: "mord", + mop: "mop", + mbin: "mbin", + mrel: "mrel", + mopen: "mopen", + mclose: "mclose", + mpunct: "mpunct", + minner: "minner" +}; + +/** + * Take a list of nodes, build them in order, and return a list of the built + * nodes. documentFragments are flattened into their contents, so the + * returned list contains no fragments. `isRealGroup` is true if `expression` + * is a real group (no atoms will be added on either side), as opposed to + * a partial group (e.g. one created by \color). `surrounding` is an array + * consisting type of nodes that will be added to the left and right. + */ +var buildExpression = function buildExpression(expression, options, isRealGroup, surrounding) { + if (surrounding === void 0) { + surrounding = [null, null]; + } + + // Parse expressions into `groups`. + var groups = []; + + for (var i = 0; i < expression.length; i++) { + var output = buildGroup(expression[i], options); + + if (output instanceof DocumentFragment) { + var children = output.children; + groups.push.apply(groups, children); + } else { + groups.push(output); + } + } // Combine consecutive domTree.symbolNodes into a single symbolNode. + + + buildCommon.tryCombineChars(groups); // If `expression` is a partial group, let the parent handle spacings + // to avoid processing groups multiple times. + + if (!isRealGroup) { + return groups; + } + + var glueOptions = options; + + if (expression.length === 1) { + var node = expression[0]; + + if (node.type === "sizing") { + glueOptions = options.havingSize(node.size); + } else if (node.type === "styling") { + glueOptions = options.havingStyle(styleMap[node.style]); + } + } // Dummy spans for determining spacings between surrounding atoms. + // If `expression` has no atoms on the left or right, class "leftmost" + // or "rightmost", respectively, is used to indicate it. + + + var dummyPrev = buildHTML_makeSpan([surrounding[0] || "leftmost"], [], options); + var dummyNext = buildHTML_makeSpan([surrounding[1] || "rightmost"], [], options); // TODO: These code assumes that a node's math class is the first element + // of its `classes` array. A later cleanup should ensure this, for + // instance by changing the signature of `makeSpan`. + // Before determining what spaces to insert, perform bin cancellation. + // Binary operators change to ordinary symbols in some contexts. + + var isRoot = isRealGroup === "root"; + traverseNonSpaceNodes(groups, function (node, prev) { + var prevType = prev.classes[0]; + var type = node.classes[0]; + + if (prevType === "mbin" && utils.contains(binRightCanceller, type)) { + prev.classes[0] = "mord"; + } else if (type === "mbin" && utils.contains(binLeftCanceller, prevType)) { + node.classes[0] = "mord"; + } + }, { + node: dummyPrev + }, dummyNext, isRoot); + traverseNonSpaceNodes(groups, function (node, prev) { + var prevType = getTypeOfDomTree(prev); + var type = getTypeOfDomTree(node); // 'mtight' indicates that the node is script or scriptscript style. + + var space = prevType && type ? node.hasClass("mtight") ? tightSpacings[prevType][type] : spacings[prevType][type] : null; + + if (space) { + // Insert glue (spacing) after the `prev`. + return buildCommon.makeGlue(space, glueOptions); + } + }, { + node: dummyPrev + }, dummyNext, isRoot); + return groups; +}; // Depth-first traverse non-space `nodes`, calling `callback` with the current and +// previous node as arguments, optionally returning a node to insert after the +// previous node. `prev` is an object with the previous node and `insertAfter` +// function to insert after it. `next` is a node that will be added to the right. +// Used for bin cancellation and inserting spacings. + +var traverseNonSpaceNodes = function traverseNonSpaceNodes(nodes, callback, prev, next, isRoot) { + if (next) { + // temporarily append the right node, if exists + nodes.push(next); + } + + var i = 0; + + for (; i < nodes.length; i++) { + var node = nodes[i]; + var partialGroup = checkPartialGroup(node); + + if (partialGroup) { + // Recursive DFS + // $FlowFixMe: make nodes a $ReadOnlyArray by returning a new array + traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot); + continue; + } // Ignore explicit spaces (e.g., \;, \,) when determining what implicit + // spacing should go between atoms of different classes + + + var nonspace = !node.hasClass("mspace"); + + if (nonspace) { + var result = callback(node, prev.node); + + if (result) { + if (prev.insertAfter) { + prev.insertAfter(result); + } else { + // insert at front + nodes.unshift(result); + i++; + } + } + } + + if (nonspace) { + prev.node = node; + } else if (isRoot && node.hasClass("newline")) { + prev.node = buildHTML_makeSpan(["leftmost"]); // treat like beginning of line + } + + prev.insertAfter = function (index) { + return function (n) { + nodes.splice(index + 1, 0, n); + i++; + }; + }(i); + } + + if (next) { + nodes.pop(); + } +}; // Check if given node is a partial group, i.e., does not affect spacing around. + + +var checkPartialGroup = function checkPartialGroup(node) { + if (node instanceof DocumentFragment || node instanceof Anchor || node instanceof Span && node.hasClass("enclosing")) { + return node; + } + + return null; +}; // Return the outermost node of a domTree. + + +var getOutermostNode = function getOutermostNode(node, side) { + var partialGroup = checkPartialGroup(node); + + if (partialGroup) { + var children = partialGroup.children; + + if (children.length) { + if (side === "right") { + return getOutermostNode(children[children.length - 1], "right"); + } else if (side === "left") { + return getOutermostNode(children[0], "left"); + } + } + } + + return node; +}; // Return math atom class (mclass) of a domTree. +// If `side` is given, it will get the type of the outermost node at given side. + + +var getTypeOfDomTree = function getTypeOfDomTree(node, side) { + if (!node) { + return null; + } + + if (side) { + node = getOutermostNode(node, side); + } // This makes a lot of assumptions as to where the type of atom + // appears. We should do a better job of enforcing this. + + + return DomEnum[node.classes[0]] || null; +}; +var makeNullDelimiter = function makeNullDelimiter(options, classes) { + var moreClasses = ["nulldelimiter"].concat(options.baseSizingClasses()); + return buildHTML_makeSpan(classes.concat(moreClasses)); +}; +/** + * buildGroup is the function that takes a group and calls the correct groupType + * function for it. It also handles the interaction of size and style changes + * between parents and children. + */ + +var buildGroup = function buildGroup(group, options, baseOptions) { + if (!group) { + return buildHTML_makeSpan(); + } + + if (_htmlGroupBuilders[group.type]) { + // Call the groupBuilders function + // $FlowFixMe + var groupNode = _htmlGroupBuilders[group.type](group, options); // If the size changed between the parent and the current group, account + // for that size difference. + + if (baseOptions && options.size !== baseOptions.size) { + groupNode = buildHTML_makeSpan(options.sizingClasses(baseOptions), [groupNode], options); + var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; + groupNode.height *= multiplier; + groupNode.depth *= multiplier; + } + + return groupNode; + } else { + throw new src_ParseError("Got group of unknown type: '" + group.type + "'"); + } +}; +/** + * Combine an array of HTML DOM nodes (e.g., the output of `buildExpression`) + * into an unbreakable HTML node of class .base, with proper struts to + * guarantee correct vertical extent. `buildHTML` calls this repeatedly to + * make up the entire expression as a sequence of unbreakable units. + */ + +function buildHTMLUnbreakable(children, options) { + // Compute height and depth of this chunk. + var body = buildHTML_makeSpan(["base"], children, options); // Add strut, which ensures that the top of the HTML element falls at + // the height of the expression, and the bottom of the HTML element + // falls at the depth of the expression. + + var strut = buildHTML_makeSpan(["strut"]); + strut.style.height = makeEm(body.height + body.depth); + + if (body.depth) { + strut.style.verticalAlign = makeEm(-body.depth); + } + + body.children.unshift(strut); + return body; +} +/** + * Take an entire parse tree, and build it into an appropriate set of HTML + * nodes. + */ + + +function buildHTML(tree, options) { + // Strip off outer tag wrapper for processing below. + var tag = null; + + if (tree.length === 1 && tree[0].type === "tag") { + tag = tree[0].tag; + tree = tree[0].body; + } // Build the expression contained in the tree + + + var expression = buildExpression(tree, options, "root"); + var eqnNum; + + if (expression.length === 2 && expression[1].hasClass("tag")) { + // An environment with automatic equation numbers, e.g. {gather}. + eqnNum = expression.pop(); + } + + var children = []; // Create one base node for each chunk between potential line breaks. + // The TeXBook [p.173] says "A formula will be broken only after a + // relation symbol like $=$ or $<$ or $\rightarrow$, or after a binary + // operation symbol like $+$ or $-$ or $\times$, where the relation or + // binary operation is on the ``outer level'' of the formula (i.e., not + // enclosed in {...} and not part of an \over construction)." + + var parts = []; + + for (var i = 0; i < expression.length; i++) { + parts.push(expression[i]); + + if (expression[i].hasClass("mbin") || expression[i].hasClass("mrel") || expression[i].hasClass("allowbreak")) { + // Put any post-operator glue on same line as operator. + // Watch for \nobreak along the way, and stop at \newline. + var nobreak = false; + + while (i < expression.length - 1 && expression[i + 1].hasClass("mspace") && !expression[i + 1].hasClass("newline")) { + i++; + parts.push(expression[i]); + + if (expression[i].hasClass("nobreak")) { + nobreak = true; + } + } // Don't allow break if \nobreak among the post-operator glue. + + + if (!nobreak) { + children.push(buildHTMLUnbreakable(parts, options)); + parts = []; + } + } else if (expression[i].hasClass("newline")) { + // Write the line except the newline + parts.pop(); + + if (parts.length > 0) { + children.push(buildHTMLUnbreakable(parts, options)); + parts = []; + } // Put the newline at the top level + + + children.push(expression[i]); + } + } + + if (parts.length > 0) { + children.push(buildHTMLUnbreakable(parts, options)); + } // Now, if there was a tag, build it too and append it as a final child. + + + var tagChild; + + if (tag) { + tagChild = buildHTMLUnbreakable(buildExpression(tag, options, true)); + tagChild.classes = ["tag"]; + children.push(tagChild); + } else if (eqnNum) { + children.push(eqnNum); + } + + var htmlNode = buildHTML_makeSpan(["katex-html"], children); + htmlNode.setAttribute("aria-hidden", "true"); // Adjust the strut of the tag to be the maximum height of all children + // (the height of the enclosing htmlNode) for proper vertical alignment. + + if (tagChild) { + var strut = tagChild.children[0]; + strut.style.height = makeEm(htmlNode.height + htmlNode.depth); + + if (htmlNode.depth) { + strut.style.verticalAlign = makeEm(-htmlNode.depth); + } + } + + return htmlNode; +} +/** + * These objects store data about MathML nodes. This is the MathML equivalent + * of the types in domTree.js. Since MathML handles its own rendering, and + * since we're mainly using MathML to improve accessibility, we don't manage + * any of the styling state that the plain DOM nodes do. + * + * The `toNode` and `toMarkup` functions work simlarly to how they do in + * domTree.js, creating namespaced DOM nodes and HTML text markup respectively. + */ + + + + +function newDocumentFragment(children) { + return new DocumentFragment(children); +} +/** + * This node represents a general purpose MathML node of any type. The + * constructor requires the type of node to create (for example, `"mo"` or + * `"mspace"`, corresponding to `` and `` tags). + */ + +var MathNode = /*#__PURE__*/function () { + function MathNode(type, children, classes) { + this.type = void 0; + this.attributes = void 0; + this.children = void 0; + this.classes = void 0; + this.type = type; + this.attributes = {}; + this.children = children || []; + this.classes = classes || []; + } + /** + * Sets an attribute on a MathML node. MathML depends on attributes to convey a + * semantic content, so this is used heavily. + */ + + + var _proto = MathNode.prototype; + + _proto.setAttribute = function setAttribute(name, value) { + this.attributes[name] = value; + } + /** + * Gets an attribute on a MathML node. + */ + ; + + _proto.getAttribute = function getAttribute(name) { + return this.attributes[name]; + } + /** + * Converts the math node into a MathML-namespaced DOM element. + */ + ; + + _proto.toNode = function toNode() { + var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", this.type); + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + if (this.classes.length > 0) { + node.className = createClass(this.classes); + } + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; + } + /** + * Converts the math node into an HTML markup string. + */ + ; + + _proto.toMarkup = function toMarkup() { + var markup = "<" + this.type; // Add the attributes + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + markup += " " + attr + "=\""; + markup += utils.escape(this.attributes[attr]); + markup += "\""; + } + } + + if (this.classes.length > 0) { + markup += " class =\"" + utils.escape(createClass(this.classes)) + "\""; + } + + markup += ">"; + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + markup += ""; + return markup; + } + /** + * Converts the math node into a string, similar to innerText, but escaped. + */ + ; + + _proto.toText = function toText() { + return this.children.map(function (child) { + return child.toText(); + }).join(""); + }; + + return MathNode; +}(); +/** + * This node represents a piece of text. + */ + +var TextNode = /*#__PURE__*/function () { + function TextNode(text) { + this.text = void 0; + this.text = text; + } + /** + * Converts the text node into a DOM text node. + */ + + + var _proto2 = TextNode.prototype; + + _proto2.toNode = function toNode() { + return document.createTextNode(this.text); + } + /** + * Converts the text node into escaped HTML markup + * (representing the text itself). + */ + ; + + _proto2.toMarkup = function toMarkup() { + return utils.escape(this.toText()); + } + /** + * Converts the text node into a string + * (representing the text iteself). + */ + ; + + _proto2.toText = function toText() { + return this.text; + }; + + return TextNode; +}(); +/** + * This node represents a space, but may render as or as text, + * depending on the width. + */ + +var SpaceNode = /*#__PURE__*/function () { + /** + * Create a Space node with width given in CSS ems. + */ + function SpaceNode(width) { + this.width = void 0; + this.character = void 0; + this.width = width; // See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html + // for a table of space-like characters. We use Unicode + // representations instead of &LongNames; as it's not clear how to + // make the latter via document.createTextNode. + + if (width >= 0.05555 && width <= 0.05556) { + this.character = "\u200A"; //   + } else if (width >= 0.1666 && width <= 0.1667) { + this.character = "\u2009"; //   + } else if (width >= 0.2222 && width <= 0.2223) { + this.character = "\u2005"; //   + } else if (width >= 0.2777 && width <= 0.2778) { + this.character = "\u2005\u200A"; //    + } else if (width >= -0.05556 && width <= -0.05555) { + this.character = "\u200A\u2063"; // ​ + } else if (width >= -0.1667 && width <= -0.1666) { + this.character = "\u2009\u2063"; // ​ + } else if (width >= -0.2223 && width <= -0.2222) { + this.character = "\u205F\u2063"; // ​ + } else if (width >= -0.2778 && width <= -0.2777) { + this.character = "\u2005\u2063"; // ​ + } else { + this.character = null; + } + } + /** + * Converts the math node into a MathML-namespaced DOM element. + */ + + + var _proto3 = SpaceNode.prototype; + + _proto3.toNode = function toNode() { + if (this.character) { + return document.createTextNode(this.character); + } else { + var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mspace"); + node.setAttribute("width", makeEm(this.width)); + return node; + } + } + /** + * Converts the math node into an HTML markup string. + */ + ; + + _proto3.toMarkup = function toMarkup() { + if (this.character) { + return "" + this.character + ""; + } else { + return ""; + } + } + /** + * Converts the math node into a string, similar to innerText. + */ + ; + + _proto3.toText = function toText() { + if (this.character) { + return this.character; + } else { + return " "; + } + }; + + return SpaceNode; +}(); + +/* harmony default export */ var mathMLTree = ({ + MathNode: MathNode, + TextNode: TextNode, + SpaceNode: SpaceNode, + newDocumentFragment: newDocumentFragment +}); +/** + * This file converts a parse tree into a cooresponding MathML tree. The main + * entry point is the `buildMathML` function, which takes a parse tree from the + * parser. + */ + + + + + + + + + +/** + * Takes a symbol and converts it into a MathML text node after performing + * optional replacement from symbols.js. + */ +var makeText = function makeText(text, mode, options) { + if (src_symbols[mode][text] && src_symbols[mode][text].replace && text.charCodeAt(0) !== 0xD835 && !(ligatures.hasOwnProperty(text) && options && (options.fontFamily && options.fontFamily.substr(4, 2) === "tt" || options.font && options.font.substr(4, 2) === "tt"))) { + text = src_symbols[mode][text].replace; + } + + return new mathMLTree.TextNode(text); +}; +/** + * Wrap the given array of nodes in an node if needed, i.e., + * unless the array has length 1. Always returns a single node. + */ + +var makeRow = function makeRow(body) { + if (body.length === 1) { + return body[0]; + } else { + return new mathMLTree.MathNode("mrow", body); + } +}; +/** + * Returns the math variant as a string or null if none is required. + */ + +var getVariant = function getVariant(group, options) { + // Handle \text... font specifiers as best we can. + // MathML has a limited list of allowable mathvariant specifiers; see + // https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt + if (options.fontFamily === "texttt") { + return "monospace"; + } else if (options.fontFamily === "textsf") { + if (options.fontShape === "textit" && options.fontWeight === "textbf") { + return "sans-serif-bold-italic"; + } else if (options.fontShape === "textit") { + return "sans-serif-italic"; + } else if (options.fontWeight === "textbf") { + return "bold-sans-serif"; + } else { + return "sans-serif"; + } + } else if (options.fontShape === "textit" && options.fontWeight === "textbf") { + return "bold-italic"; + } else if (options.fontShape === "textit") { + return "italic"; + } else if (options.fontWeight === "textbf") { + return "bold"; + } + + var font = options.font; + + if (!font || font === "mathnormal") { + return null; + } + + var mode = group.mode; + + if (font === "mathit") { + return "italic"; + } else if (font === "boldsymbol") { + return group.type === "textord" ? "bold" : "bold-italic"; + } else if (font === "mathbf") { + return "bold"; + } else if (font === "mathbb") { + return "double-struck"; + } else if (font === "mathfrak") { + return "fraktur"; + } else if (font === "mathscr" || font === "mathcal") { + // MathML makes no distinction between script and caligrahpic + return "script"; + } else if (font === "mathsf") { + return "sans-serif"; + } else if (font === "mathtt") { + return "monospace"; + } + + var text = group.text; + + if (utils.contains(["\\imath", "\\jmath"], text)) { + return null; + } + + if (src_symbols[mode][text] && src_symbols[mode][text].replace) { + text = src_symbols[mode][text].replace; + } + + var fontName = buildCommon.fontMap[font].fontName; + + if (getCharacterMetrics(text, fontName, mode)) { + return buildCommon.fontMap[font].variant; + } + + return null; +}; +/** + * Takes a list of nodes, builds them, and returns a list of the generated + * MathML nodes. Also combine consecutive outputs into a single + * tag. + */ + +var buildMathML_buildExpression = function buildExpression(expression, options, isOrdgroup) { + if (expression.length === 1) { + var group = buildMathML_buildGroup(expression[0], options); + + if (isOrdgroup && group instanceof MathNode && group.type === "mo") { + // When TeX writers want to suppress spacing on an operator, + // they often put the operator by itself inside braces. + group.setAttribute("lspace", "0em"); + group.setAttribute("rspace", "0em"); + } + + return [group]; + } + + var groups = []; + var lastGroup; + + for (var i = 0; i < expression.length; i++) { + var _group = buildMathML_buildGroup(expression[i], options); + + if (_group instanceof MathNode && lastGroup instanceof MathNode) { + // Concatenate adjacent s + if (_group.type === 'mtext' && lastGroup.type === 'mtext' && _group.getAttribute('mathvariant') === lastGroup.getAttribute('mathvariant')) { + var _lastGroup$children; + + (_lastGroup$children = lastGroup.children).push.apply(_lastGroup$children, _group.children); + + continue; // Concatenate adjacent s + } else if (_group.type === 'mn' && lastGroup.type === 'mn') { + var _lastGroup$children2; + + (_lastGroup$children2 = lastGroup.children).push.apply(_lastGroup$children2, _group.children); + + continue; // Concatenate ... followed by . + } else if (_group.type === 'mi' && _group.children.length === 1 && lastGroup.type === 'mn') { + var child = _group.children[0]; + + if (child instanceof TextNode && child.text === '.') { + var _lastGroup$children3; + + (_lastGroup$children3 = lastGroup.children).push.apply(_lastGroup$children3, _group.children); + + continue; + } + } else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) { + var lastChild = lastGroup.children[0]; + + if (lastChild instanceof TextNode && lastChild.text === "\u0338" && (_group.type === 'mo' || _group.type === 'mi' || _group.type === 'mn')) { + var _child = _group.children[0]; + + if (_child instanceof TextNode && _child.text.length > 0) { + // Overlay with combining character long solidus + _child.text = _child.text.slice(0, 1) + "\u0338" + _child.text.slice(1); + groups.pop(); + } + } + } + } + + groups.push(_group); + lastGroup = _group; + } + + return groups; +}; +/** + * Equivalent to buildExpression, but wraps the elements in an + * if there's more than one. Returns a single node instead of an array. + */ + +var buildExpressionRow = function buildExpressionRow(expression, options, isOrdgroup) { + return makeRow(buildMathML_buildExpression(expression, options, isOrdgroup)); +}; +/** + * Takes a group from the parser and calls the appropriate groupBuilders function + * on it to produce a MathML node. + */ + +var buildMathML_buildGroup = function buildGroup(group, options) { + if (!group) { + return new mathMLTree.MathNode("mrow"); + } + + if (_mathmlGroupBuilders[group.type]) { + // Call the groupBuilders function + // $FlowFixMe + var result = _mathmlGroupBuilders[group.type](group, options); // $FlowFixMe + + return result; + } else { + throw new src_ParseError("Got group of unknown type: '" + group.type + "'"); + } +}; +/** + * Takes a full parse tree and settings and builds a MathML representation of + * it. In particular, we put the elements from building the parse tree into a + * tag so we can also include that TeX source as an annotation. + * + * Note that we actually return a domTree element with a `` inside it so + * we can do appropriate styling. + */ + +function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly) { + var expression = buildMathML_buildExpression(tree, options); // TODO: Make a pass thru the MathML similar to buildHTML.traverseNonSpaceNodes + // and add spacing nodes. This is necessary only adjacent to math operators + // like \sin or \lim or to subsup elements that contain math operators. + // MathML takes care of the other spacing issues. + // Wrap up the expression in an mrow so it is presented in the semantics + // tag correctly, unless it's a single or . + + var wrapper; + + if (expression.length === 1 && expression[0] instanceof MathNode && utils.contains(["mrow", "mtable"], expression[0].type)) { + wrapper = expression[0]; + } else { + wrapper = new mathMLTree.MathNode("mrow", expression); + } // Build a TeX annotation of the source + + + var annotation = new mathMLTree.MathNode("annotation", [new mathMLTree.TextNode(texExpression)]); + annotation.setAttribute("encoding", "application/x-tex"); + var semantics = new mathMLTree.MathNode("semantics", [wrapper, annotation]); + var math = new mathMLTree.MathNode("math", [semantics]); + math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML"); + + if (isDisplayMode) { + math.setAttribute("display", "block"); + } // You can't style nodes, so we wrap the node in a span. + // NOTE: The span class is not typed to have nodes as children, and + // we don't want to make the children type more generic since the children + // of span are expected to have more fields in `buildHtml` contexts. + + + var wrapperClass = forMathmlOnly ? "katex" : "katex-mathml"; // $FlowFixMe + + return buildCommon.makeSpan([wrapperClass], [math]); +} + + + + + + + +var optionsFromSettings = function optionsFromSettings(settings) { + return new src_Options({ + style: settings.displayMode ? src_Style.DISPLAY : src_Style.TEXT, + maxSize: settings.maxSize, + minRuleThickness: settings.minRuleThickness + }); +}; + +var displayWrap = function displayWrap(node, settings) { + if (settings.displayMode) { + var classes = ["katex-display"]; + + if (settings.leqno) { + classes.push("leqno"); + } + + if (settings.fleqn) { + classes.push("fleqn"); + } + + node = buildCommon.makeSpan(classes, [node]); + } + + return node; +}; + +var buildTree = function buildTree(tree, expression, settings) { + var options = optionsFromSettings(settings); + var katexNode; + + if (settings.output === "mathml") { + return buildMathML(tree, expression, options, settings.displayMode, true); + } else if (settings.output === "html") { + var htmlNode = buildHTML(tree, options); + katexNode = buildCommon.makeSpan(["katex"], [htmlNode]); + } else { + var mathMLNode = buildMathML(tree, expression, options, settings.displayMode, false); + + var _htmlNode = buildHTML(tree, options); + + katexNode = buildCommon.makeSpan(["katex"], [mathMLNode, _htmlNode]); + } + + return displayWrap(katexNode, settings); +}; +var buildHTMLTree = function buildHTMLTree(tree, expression, settings) { + var options = optionsFromSettings(settings); + var htmlNode = buildHTML(tree, options); + var katexNode = buildCommon.makeSpan(["katex"], [htmlNode]); + return displayWrap(katexNode, settings); +}; +/** + * This file provides support to buildMathML.js and buildHTML.js + * for stretchy wide elements rendered from SVG files + * and other CSS trickery. + */ + + + + + +var stretchyCodePoint = { + widehat: "^", + widecheck: "ˇ", + widetilde: "~", + utilde: "~", + overleftarrow: "\u2190", + underleftarrow: "\u2190", + xleftarrow: "\u2190", + overrightarrow: "\u2192", + underrightarrow: "\u2192", + xrightarrow: "\u2192", + underbrace: "\u23DF", + overbrace: "\u23DE", + overgroup: "\u23E0", + undergroup: "\u23E1", + overleftrightarrow: "\u2194", + underleftrightarrow: "\u2194", + xleftrightarrow: "\u2194", + Overrightarrow: "\u21D2", + xRightarrow: "\u21D2", + overleftharpoon: "\u21BC", + xleftharpoonup: "\u21BC", + overrightharpoon: "\u21C0", + xrightharpoonup: "\u21C0", + xLeftarrow: "\u21D0", + xLeftrightarrow: "\u21D4", + xhookleftarrow: "\u21A9", + xhookrightarrow: "\u21AA", + xmapsto: "\u21A6", + xrightharpoondown: "\u21C1", + xleftharpoondown: "\u21BD", + xrightleftharpoons: "\u21CC", + xleftrightharpoons: "\u21CB", + xtwoheadleftarrow: "\u219E", + xtwoheadrightarrow: "\u21A0", + xlongequal: "=", + xtofrom: "\u21C4", + xrightleftarrows: "\u21C4", + xrightequilibrium: "\u21CC", + // Not a perfect match. + xleftequilibrium: "\u21CB", + // None better available. + "\\cdrightarrow": "\u2192", + "\\cdleftarrow": "\u2190", + "\\cdlongequal": "=" +}; + +var mathMLnode = function mathMLnode(label) { + var node = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(stretchyCodePoint[label.replace(/^\\/, '')])]); + node.setAttribute("stretchy", "true"); + return node; +}; // Many of the KaTeX SVG images have been adapted from glyphs in KaTeX fonts. +// Copyright (c) 2009-2010, Design Science, Inc. () +// Copyright (c) 2014-2017 Khan Academy () +// Licensed under the SIL Open Font License, Version 1.1. +// See \nhttp://scripts.sil.org/OFL +// Very Long SVGs +// Many of the KaTeX stretchy wide elements use a long SVG image and an +// overflow: hidden tactic to achieve a stretchy image while avoiding +// distortion of arrowheads or brace corners. +// The SVG typically contains a very long (400 em) arrow. +// The SVG is in a container span that has overflow: hidden, so the span +// acts like a window that exposes only part of the SVG. +// The SVG always has a longer, thinner aspect ratio than the container span. +// After the SVG fills 100% of the height of the container span, +// there is a long arrow shaft left over. That left-over shaft is not shown. +// Instead, it is sliced off because the span's CSS has overflow: hidden. +// Thus, the reader sees an arrow that matches the subject matter width +// without distortion. +// Some functions, such as \cancel, need to vary their aspect ratio. These +// functions do not get the overflow SVG treatment. +// Second Brush Stroke +// Low resolution monitors struggle to display images in fine detail. +// So browsers apply anti-aliasing. A long straight arrow shaft therefore +// will sometimes appear as if it has a blurred edge. +// To mitigate this, these SVG files contain a second "brush-stroke" on the +// arrow shafts. That is, a second long thin rectangular SVG path has been +// written directly on top of each arrow shaft. This reinforcement causes +// some of the screen pixels to display as black instead of the anti-aliased +// gray pixel that a single path would generate. So we get arrow shafts +// whose edges appear to be sharper. +// In the katexImagesData object just below, the dimensions all +// correspond to path geometry inside the relevant SVG. +// For example, \overrightarrow uses the same arrowhead as glyph U+2192 +// from the KaTeX Main font. The scaling factor is 1000. +// That is, inside the font, that arrowhead is 522 units tall, which +// corresponds to 0.522 em inside the document. + + +var katexImagesData = { + // path(s), minWidth, height, align + overrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"], + overleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"], + underrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"], + underleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"], + xrightarrow: [["rightarrow"], 1.469, 522, "xMaxYMin"], + "\\cdrightarrow": [["rightarrow"], 3.0, 522, "xMaxYMin"], + // CD minwwidth2.5pc + xleftarrow: [["leftarrow"], 1.469, 522, "xMinYMin"], + "\\cdleftarrow": [["leftarrow"], 3.0, 522, "xMinYMin"], + Overrightarrow: [["doublerightarrow"], 0.888, 560, "xMaxYMin"], + xRightarrow: [["doublerightarrow"], 1.526, 560, "xMaxYMin"], + xLeftarrow: [["doubleleftarrow"], 1.526, 560, "xMinYMin"], + overleftharpoon: [["leftharpoon"], 0.888, 522, "xMinYMin"], + xleftharpoonup: [["leftharpoon"], 0.888, 522, "xMinYMin"], + xleftharpoondown: [["leftharpoondown"], 0.888, 522, "xMinYMin"], + overrightharpoon: [["rightharpoon"], 0.888, 522, "xMaxYMin"], + xrightharpoonup: [["rightharpoon"], 0.888, 522, "xMaxYMin"], + xrightharpoondown: [["rightharpoondown"], 0.888, 522, "xMaxYMin"], + xlongequal: [["longequal"], 0.888, 334, "xMinYMin"], + "\\cdlongequal": [["longequal"], 3.0, 334, "xMinYMin"], + xtwoheadleftarrow: [["twoheadleftarrow"], 0.888, 334, "xMinYMin"], + xtwoheadrightarrow: [["twoheadrightarrow"], 0.888, 334, "xMaxYMin"], + overleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522], + overbrace: [["leftbrace", "midbrace", "rightbrace"], 1.6, 548], + underbrace: [["leftbraceunder", "midbraceunder", "rightbraceunder"], 1.6, 548], + underleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522], + xleftrightarrow: [["leftarrow", "rightarrow"], 1.75, 522], + xLeftrightarrow: [["doubleleftarrow", "doublerightarrow"], 1.75, 560], + xrightleftharpoons: [["leftharpoondownplus", "rightharpoonplus"], 1.75, 716], + xleftrightharpoons: [["leftharpoonplus", "rightharpoondownplus"], 1.75, 716], + xhookleftarrow: [["leftarrow", "righthook"], 1.08, 522], + xhookrightarrow: [["lefthook", "rightarrow"], 1.08, 522], + overlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522], + underlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522], + overgroup: [["leftgroup", "rightgroup"], 0.888, 342], + undergroup: [["leftgroupunder", "rightgroupunder"], 0.888, 342], + xmapsto: [["leftmapsto", "rightarrow"], 1.5, 522], + xtofrom: [["leftToFrom", "rightToFrom"], 1.75, 528], + // The next three arrows are from the mhchem package. + // In mhchem.sty, min-length is 2.0em. But these arrows might appear in the + // document as \xrightarrow or \xrightleftharpoons. Those have + // min-length = 1.75em, so we set min-length on these next three to match. + xrightleftarrows: [["baraboveleftarrow", "rightarrowabovebar"], 1.75, 901], + xrightequilibrium: [["baraboveshortleftharpoon", "rightharpoonaboveshortbar"], 1.75, 716], + xleftequilibrium: [["shortbaraboveleftharpoon", "shortrightharpoonabovebar"], 1.75, 716] +}; + +var groupLength = function groupLength(arg) { + if (arg.type === "ordgroup") { + return arg.body.length; + } else { + return 1; + } +}; + +var svgSpan = function svgSpan(group, options) { + // Create a span with inline SVG for the element. + function buildSvgSpan_() { + var viewBoxWidth = 400000; // default + + var label = group.label.substr(1); + + if (utils.contains(["widehat", "widecheck", "widetilde", "utilde"], label)) { + // Each type in the `if` statement corresponds to one of the ParseNode + // types below. This narrowing is required to access `grp.base`. + // $FlowFixMe + var grp = group; // There are four SVG images available for each function. + // Choose a taller image when there are more characters. + + var numChars = groupLength(grp.base); + var viewBoxHeight; + var pathName; + + var _height; + + if (numChars > 5) { + if (label === "widehat" || label === "widecheck") { + viewBoxHeight = 420; + viewBoxWidth = 2364; + _height = 0.42; + pathName = label + "4"; + } else { + viewBoxHeight = 312; + viewBoxWidth = 2340; + _height = 0.34; + pathName = "tilde4"; + } + } else { + var imgIndex = [1, 1, 2, 2, 3, 3][numChars]; + + if (label === "widehat" || label === "widecheck") { + viewBoxWidth = [0, 1062, 2364, 2364, 2364][imgIndex]; + viewBoxHeight = [0, 239, 300, 360, 420][imgIndex]; + _height = [0, 0.24, 0.3, 0.3, 0.36, 0.42][imgIndex]; + pathName = label + imgIndex; + } else { + viewBoxWidth = [0, 600, 1033, 2339, 2340][imgIndex]; + viewBoxHeight = [0, 260, 286, 306, 312][imgIndex]; + _height = [0, 0.26, 0.286, 0.3, 0.306, 0.34][imgIndex]; + pathName = "tilde" + imgIndex; + } + } + + var path = new PathNode(pathName); + var svgNode = new SvgNode([path], { + "width": "100%", + "height": makeEm(_height), + "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight, + "preserveAspectRatio": "none" + }); + return { + span: buildCommon.makeSvgSpan([], [svgNode], options), + minWidth: 0, + height: _height + }; + } else { + var spans = []; + var data = katexImagesData[label]; + var paths = data[0], + _minWidth = data[1], + _viewBoxHeight = data[2]; + + var _height2 = _viewBoxHeight / 1000; + + var numSvgChildren = paths.length; + var widthClasses; + var aligns; + + if (numSvgChildren === 1) { + // $FlowFixMe: All these cases must be of the 4-tuple type. + var align1 = data[3]; + widthClasses = ["hide-tail"]; + aligns = [align1]; + } else if (numSvgChildren === 2) { + widthClasses = ["halfarrow-left", "halfarrow-right"]; + aligns = ["xMinYMin", "xMaxYMin"]; + } else if (numSvgChildren === 3) { + widthClasses = ["brace-left", "brace-center", "brace-right"]; + aligns = ["xMinYMin", "xMidYMin", "xMaxYMin"]; + } else { + throw new Error("Correct katexImagesData or update code here to support\n " + numSvgChildren + " children."); + } + + for (var i = 0; i < numSvgChildren; i++) { + var _path = new PathNode(paths[i]); + + var _svgNode = new SvgNode([_path], { + "width": "400em", + "height": makeEm(_height2), + "viewBox": "0 0 " + viewBoxWidth + " " + _viewBoxHeight, + "preserveAspectRatio": aligns[i] + " slice" + }); + + var _span = buildCommon.makeSvgSpan([widthClasses[i]], [_svgNode], options); + + if (numSvgChildren === 1) { + return { + span: _span, + minWidth: _minWidth, + height: _height2 + }; + } else { + _span.style.height = makeEm(_height2); + spans.push(_span); + } + } + + return { + span: buildCommon.makeSpan(["stretchy"], spans, options), + minWidth: _minWidth, + height: _height2 + }; + } + } // buildSvgSpan_() + + + var _buildSvgSpan_ = buildSvgSpan_(), + span = _buildSvgSpan_.span, + minWidth = _buildSvgSpan_.minWidth, + height = _buildSvgSpan_.height; // Note that we are returning span.depth = 0. + // Any adjustments relative to the baseline must be done in buildHTML. + + + span.height = height; + span.style.height = makeEm(height); + + if (minWidth > 0) { + span.style.minWidth = makeEm(minWidth); + } + + return span; +}; + +var encloseSpan = function encloseSpan(inner, label, topPad, bottomPad, options) { + // Return an image span for \cancel, \bcancel, \xcancel, \fbox, or \angl + var img; + var totalHeight = inner.height + inner.depth + topPad + bottomPad; + + if (/fbox|color|angl/.test(label)) { + img = buildCommon.makeSpan(["stretchy", label], [], options); + + if (label === "fbox") { + var color = options.color && options.getColor(); + + if (color) { + img.style.borderColor = color; + } + } + } else { + // \cancel, \bcancel, or \xcancel + // Since \cancel's SVG is inline and it omits the viewBox attribute, + // its stroke-width will not vary with span area. + var lines = []; + + if (/^[bx]cancel$/.test(label)) { + lines.push(new LineNode({ + "x1": "0", + "y1": "0", + "x2": "100%", + "y2": "100%", + "stroke-width": "0.046em" + })); + } + + if (/^x?cancel$/.test(label)) { + lines.push(new LineNode({ + "x1": "0", + "y1": "100%", + "x2": "100%", + "y2": "0", + "stroke-width": "0.046em" + })); + } + + var svgNode = new SvgNode(lines, { + "width": "100%", + "height": makeEm(totalHeight) + }); + img = buildCommon.makeSvgSpan([], [svgNode], options); + } + + img.height = totalHeight; + img.style.height = makeEm(totalHeight); + return img; +}; + +/* harmony default export */ var stretchy = ({ + encloseSpan: encloseSpan, + mathMLnode: mathMLnode, + svgSpan: svgSpan +}); + + +/** + * Asserts that the node is of the given type and returns it with stricter + * typing. Throws if the node's type does not match. + */ +function assertNodeType(node, type) { + if (!node || node.type !== type) { + throw new Error("Expected node of type " + type + ", but got " + (node ? "node of type " + node.type : String(node))); + } // $FlowFixMe, >=0.125 + + + return node; +} +/** + * Returns the node more strictly typed iff it is of the given type. Otherwise, + * returns null. + */ + +function assertSymbolNodeType(node) { + var typedNode = checkSymbolNodeType(node); + + if (!typedNode) { + throw new Error("Expected node of symbol group type, but got " + (node ? "node of type " + node.type : String(node))); + } + + return typedNode; +} +/** + * Returns the node more strictly typed iff it is of the given type. Otherwise, + * returns null. + */ + +function checkSymbolNodeType(node) { + if (node && (node.type === "atom" || NON_ATOMS.hasOwnProperty(node.type))) { + // $FlowFixMe + return node; + } + + return null; +} + + + + + + + + + + +// NOTE: Unlike most `htmlBuilder`s, this one handles not only "accent", but +// also "supsub" since an accent can affect super/subscripting. +var htmlBuilder = function htmlBuilder(grp, options) { + // Accents are handled in the TeXbook pg. 443, rule 12. + var base; + var group; + var supSubGroup; + + if (grp && grp.type === "supsub") { + // If our base is a character box, and we have superscripts and + // subscripts, the supsub will defer to us. In particular, we want + // to attach the superscripts and subscripts to the inner body (so + // that the position of the superscripts and subscripts won't be + // affected by the height of the accent). We accomplish this by + // sticking the base of the accent into the base of the supsub, and + // rendering that, while keeping track of where the accent is. + // The real accent group is the base of the supsub group + group = assertNodeType(grp.base, "accent"); // The character box is the base of the accent group + + base = group.base; // Stick the character box into the base of the supsub group + + grp.base = base; // Rerender the supsub group with its new base, and store that + // result. + + supSubGroup = assertSpan(buildGroup(grp, options)); // reset original base + + grp.base = group; + } else { + group = assertNodeType(grp, "accent"); + base = group.base; + } // Build the base group + + + var body = buildGroup(base, options.havingCrampedStyle()); // Does the accent need to shift for the skew of a character? + + var mustShift = group.isShifty && utils.isCharacterBox(base); // Calculate the skew of the accent. This is based on the line "If the + // nucleus is not a single character, let s = 0; otherwise set s to the + // kern amount for the nucleus followed by the \skewchar of its font." + // Note that our skew metrics are just the kern between each character + // and the skewchar. + + var skew = 0; + + if (mustShift) { + // If the base is a character box, then we want the skew of the + // innermost character. To do that, we find the innermost character: + var baseChar = utils.getBaseElem(base); // Then, we render its group to get the symbol inside it + + var baseGroup = buildGroup(baseChar, options.havingCrampedStyle()); // Finally, we pull the skew off of the symbol. + + skew = assertSymbolDomNode(baseGroup).skew; // Note that we now throw away baseGroup, because the layers we + // removed with getBaseElem might contain things like \color which + // we can't get rid of. + // TODO(emily): Find a better way to get the skew + } + + var accentBelow = group.label === "\\c"; // calculate the amount of space between the body and the accent + + var clearance = accentBelow ? body.height + body.depth : Math.min(body.height, options.fontMetrics().xHeight); // Build the accent + + var accentBody; + + if (!group.isStretchy) { + var accent; + var width; + + if (group.label === "\\vec") { + // Before version 0.9, \vec used the combining font glyph U+20D7. + // But browsers, especially Safari, are not consistent in how they + // render combining characters when not preceded by a character. + // So now we use an SVG. + // If Safari reforms, we should consider reverting to the glyph. + accent = buildCommon.staticSvg("vec", options); + width = buildCommon.svgData.vec[1]; + } else { + accent = buildCommon.makeOrd({ + mode: group.mode, + text: group.label + }, options, "textord"); + accent = assertSymbolDomNode(accent); // Remove the italic correction of the accent, because it only serves to + // shift the accent over to a place we don't want. + + accent.italic = 0; + width = accent.width; + + if (accentBelow) { + clearance += accent.depth; + } + } + + accentBody = buildCommon.makeSpan(["accent-body"], [accent]); // "Full" accents expand the width of the resulting symbol to be + // at least the width of the accent, and overlap directly onto the + // character without any vertical offset. + + var accentFull = group.label === "\\textcircled"; + + if (accentFull) { + accentBody.classes.push('accent-full'); + clearance = body.height; + } // Shift the accent over by the skew. + + + var left = skew; // CSS defines `.katex .accent .accent-body:not(.accent-full) { width: 0 }` + // so that the accent doesn't contribute to the bounding box. + // We need to shift the character by its width (effectively half + // its width) to compensate. + + if (!accentFull) { + left -= width / 2; + } + + accentBody.style.left = makeEm(left); // \textcircled uses the \bigcirc glyph, so it needs some + // vertical adjustment to match LaTeX. + + if (group.label === "\\textcircled") { + accentBody.style.top = ".2em"; + } + + accentBody = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: body + }, { + type: "kern", + size: -clearance + }, { + type: "elem", + elem: accentBody + }] + }, options); + } else { + accentBody = stretchy.svgSpan(group, options); + accentBody = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: body + }, { + type: "elem", + elem: accentBody, + wrapperClasses: ["svg-align"], + wrapperStyle: skew > 0 ? { + width: "calc(100% - " + makeEm(2 * skew) + ")", + marginLeft: makeEm(2 * skew) + } : undefined + }] + }, options); + } + + var accentWrap = buildCommon.makeSpan(["mord", "accent"], [accentBody], options); + + if (supSubGroup) { + // Here, we replace the "base" child of the supsub with our newly + // generated accent. + supSubGroup.children[0] = accentWrap; // Since we don't rerun the height calculation after replacing the + // accent, we manually recalculate height. + + supSubGroup.height = Math.max(accentWrap.height, supSubGroup.height); // Accents should always be ords, even when their innards are not. + + supSubGroup.classes[0] = "mord"; + return supSubGroup; + } else { + return accentWrap; + } +}; + +var mathmlBuilder = function mathmlBuilder(group, options) { + var accentNode = group.isStretchy ? stretchy.mathMLnode(group.label) : new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]); + var node = new mathMLTree.MathNode("mover", [buildMathML_buildGroup(group.base, options), accentNode]); + node.setAttribute("accent", "true"); + return node; +}; + +var NON_STRETCHY_ACCENT_REGEX = new RegExp(["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring"].map(function (accent) { + return "\\" + accent; +}).join("|")); // Accents + +defineFunction({ + type: "accent", + names: ["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring", "\\widecheck", "\\widehat", "\\widetilde", "\\overrightarrow", "\\overleftarrow", "\\Overrightarrow", "\\overleftrightarrow", "\\overgroup", "\\overlinesegment", "\\overleftharpoon", "\\overrightharpoon"], + props: { + numArgs: 1 + }, + handler: function handler(context, args) { + var base = normalizeArgument(args[0]); + var isStretchy = !NON_STRETCHY_ACCENT_REGEX.test(context.funcName); + var isShifty = !isStretchy || context.funcName === "\\widehat" || context.funcName === "\\widetilde" || context.funcName === "\\widecheck"; + return { + type: "accent", + mode: context.parser.mode, + label: context.funcName, + isStretchy: isStretchy, + isShifty: isShifty, + base: base + }; + }, + htmlBuilder: htmlBuilder, + mathmlBuilder: mathmlBuilder +}); // Text-mode accents + +defineFunction({ + type: "accent", + names: ["\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\c", "\\r", "\\H", "\\v", "\\textcircled"], + props: { + numArgs: 1, + allowedInText: true, + allowedInMath: true, + // unless in strict mode + argTypes: ["primitive"] + }, + handler: function handler(context, args) { + var base = args[0]; + var mode = context.parser.mode; + + if (mode === "math") { + context.parser.settings.reportNonstrict("mathVsTextAccents", "LaTeX's accent " + context.funcName + " works only in text mode"); + mode = "text"; + } + + return { + type: "accent", + mode: mode, + label: context.funcName, + isStretchy: false, + isShifty: true, + base: base + }; + }, + htmlBuilder: htmlBuilder, + mathmlBuilder: mathmlBuilder +}); +// Horizontal overlap functions + + + + + + +defineFunction({ + type: "accentUnder", + names: ["\\underleftarrow", "\\underrightarrow", "\\underleftrightarrow", "\\undergroup", "\\underlinesegment", "\\utilde"], + props: { + numArgs: 1 + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var base = args[0]; + return { + type: "accentUnder", + mode: parser.mode, + label: funcName, + base: base + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Treat under accents much like underlines. + var innerGroup = buildGroup(group.base, options); + var accentBody = stretchy.svgSpan(group, options); + var kern = group.label === "\\utilde" ? 0.12 : 0; // Generate the vlist, with the appropriate kerns + + var vlist = buildCommon.makeVList({ + positionType: "top", + positionData: innerGroup.height, + children: [{ + type: "elem", + elem: accentBody, + wrapperClasses: ["svg-align"] + }, { + type: "kern", + size: kern + }, { + type: "elem", + elem: innerGroup + }] + }, options); + return buildCommon.makeSpan(["mord", "accentunder"], [vlist], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var accentNode = stretchy.mathMLnode(group.label); + var node = new mathMLTree.MathNode("munder", [buildMathML_buildGroup(group.base, options), accentNode]); + node.setAttribute("accentunder", "true"); + return node; + } +}); + + + + + + + +// Helper function +var paddedNode = function paddedNode(group) { + var node = new mathMLTree.MathNode("mpadded", group ? [group] : []); + node.setAttribute("width", "+0.6em"); + node.setAttribute("lspace", "0.3em"); + return node; +}; // Stretchy arrows with an optional argument + + +defineFunction({ + type: "xArrow", + names: ["\\xleftarrow", "\\xrightarrow", "\\xLeftarrow", "\\xRightarrow", "\\xleftrightarrow", "\\xLeftrightarrow", "\\xhookleftarrow", "\\xhookrightarrow", "\\xmapsto", "\\xrightharpoondown", "\\xrightharpoonup", "\\xleftharpoondown", "\\xleftharpoonup", "\\xrightleftharpoons", "\\xleftrightharpoons", "\\xlongequal", "\\xtwoheadrightarrow", "\\xtwoheadleftarrow", "\\xtofrom", // The next 3 functions are here to support the mhchem extension. + // Direct use of these functions is discouraged and may break someday. + "\\xrightleftarrows", "\\xrightequilibrium", "\\xleftequilibrium", // The next 3 functions are here only to support the {CD} environment. + "\\\\cdrightarrow", "\\\\cdleftarrow", "\\\\cdlongequal"], + props: { + numArgs: 1, + numOptionalArgs: 1 + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser, + funcName = _ref.funcName; + return { + type: "xArrow", + mode: parser.mode, + label: funcName, + body: args[0], + below: optArgs[0] + }; + }, + // Flow is unable to correctly infer the type of `group`, even though it's + // unamibiguously determined from the passed-in `type` above. + htmlBuilder: function htmlBuilder(group, options) { + var style = options.style; // Build the argument groups in the appropriate style. + // Ref: amsmath.dtx: \hbox{$\scriptstyle\mkern#3mu{#6}\mkern#4mu$}% + // Some groups can return document fragments. Handle those by wrapping + // them in a span. + + var newOptions = options.havingStyle(style.sup()); + var upperGroup = buildCommon.wrapFragment(buildGroup(group.body, newOptions, options), options); + var arrowPrefix = group.label.slice(0, 2) === "\\x" ? "x" : "cd"; + upperGroup.classes.push(arrowPrefix + "-arrow-pad"); + var lowerGroup; + + if (group.below) { + // Build the lower group + newOptions = options.havingStyle(style.sub()); + lowerGroup = buildCommon.wrapFragment(buildGroup(group.below, newOptions, options), options); + lowerGroup.classes.push(arrowPrefix + "-arrow-pad"); + } + + var arrowBody = stretchy.svgSpan(group, options); // Re shift: Note that stretchy.svgSpan returned arrowBody.depth = 0. + // The point we want on the math axis is at 0.5 * arrowBody.height. + + var arrowShift = -options.fontMetrics().axisHeight + 0.5 * arrowBody.height; // 2 mu kern. Ref: amsmath.dtx: #7\if0#2\else\mkern#2mu\fi + + var upperShift = -options.fontMetrics().axisHeight - 0.5 * arrowBody.height - 0.111; // 0.111 em = 2 mu + + if (upperGroup.depth > 0.25 || group.label === "\\xleftequilibrium") { + upperShift -= upperGroup.depth; // shift up if depth encroaches + } // Generate the vlist + + + var vlist; + + if (lowerGroup) { + var lowerShift = -options.fontMetrics().axisHeight + lowerGroup.height + 0.5 * arrowBody.height + 0.111; + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: upperGroup, + shift: upperShift + }, { + type: "elem", + elem: arrowBody, + shift: arrowShift + }, { + type: "elem", + elem: lowerGroup, + shift: lowerShift + }] + }, options); + } else { + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: upperGroup, + shift: upperShift + }, { + type: "elem", + elem: arrowBody, + shift: arrowShift + }] + }, options); + } // $FlowFixMe: Replace this with passing "svg-align" into makeVList. + + + vlist.children[0].children[0].children[1].classes.push("svg-align"); + return buildCommon.makeSpan(["mrel", "x-arrow"], [vlist], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var arrowNode = stretchy.mathMLnode(group.label); + arrowNode.setAttribute("minsize", group.label.charAt(0) === "x" ? "1.75em" : "3.0em"); + var node; + + if (group.body) { + var upperNode = paddedNode(buildMathML_buildGroup(group.body, options)); + + if (group.below) { + var lowerNode = paddedNode(buildMathML_buildGroup(group.below, options)); + node = new mathMLTree.MathNode("munderover", [arrowNode, lowerNode, upperNode]); + } else { + node = new mathMLTree.MathNode("mover", [arrowNode, upperNode]); + } + } else if (group.below) { + var _lowerNode = paddedNode(buildMathML_buildGroup(group.below, options)); + + node = new mathMLTree.MathNode("munder", [arrowNode, _lowerNode]); + } else { + // This should never happen. + // Parser.js throws an error if there is no argument. + node = paddedNode(); + node = new mathMLTree.MathNode("mover", [arrowNode, node]); + } + + return node; + } +}); + + + + + + + + +var cdArrowFunctionName = { + ">": "\\\\cdrightarrow", + "<": "\\\\cdleftarrow", + "=": "\\\\cdlongequal", + "A": "\\uparrow", + "V": "\\downarrow", + "|": "\\Vert", + ".": "no arrow" +}; + +var newCell = function newCell() { + // Create an empty cell, to be filled below with parse nodes. + // The parseTree from this module must be constructed like the + // one created by parseArray(), so an empty CD cell must + // be a ParseNode<"styling">. And CD is always displaystyle. + // So these values are fixed and flow can do implicit typing. + return { + type: "styling", + body: [], + mode: "math", + style: "display" + }; +}; + +var isStartOfArrow = function isStartOfArrow(node) { + return node.type === "textord" && node.text === "@"; +}; + +var isLabelEnd = function isLabelEnd(node, endChar) { + return (node.type === "mathord" || node.type === "atom") && node.text === endChar; +}; + +function cdArrow(arrowChar, labels, parser) { + // Return a parse tree of an arrow and its labels. + // This acts in a way similar to a macro expansion. + var funcName = cdArrowFunctionName[arrowChar]; + + switch (funcName) { + case "\\\\cdrightarrow": + case "\\\\cdleftarrow": + return parser.callFunction(funcName, [labels[0]], [labels[1]]); + + case "\\uparrow": + case "\\downarrow": + { + var leftLabel = parser.callFunction("\\\\cdleft", [labels[0]], []); + var bareArrow = { + type: "atom", + text: funcName, + mode: "math", + family: "rel" + }; + var sizedArrow = parser.callFunction("\\Big", [bareArrow], []); + var rightLabel = parser.callFunction("\\\\cdright", [labels[1]], []); + var arrowGroup = { + type: "ordgroup", + mode: "math", + body: [leftLabel, sizedArrow, rightLabel] + }; + return parser.callFunction("\\\\cdparent", [arrowGroup], []); + } + + case "\\\\cdlongequal": + return parser.callFunction("\\\\cdlongequal", [], []); + + case "\\Vert": + { + var arrow = { + type: "textord", + text: "\\Vert", + mode: "math" + }; + return parser.callFunction("\\Big", [arrow], []); + } + + default: + return { + type: "textord", + text: " ", + mode: "math" + }; + } +} + +function parseCD(parser) { + // Get the array's parse nodes with \\ temporarily mapped to \cr. + var parsedRows = []; + parser.gullet.beginGroup(); + parser.gullet.macros.set("\\cr", "\\\\\\relax"); + parser.gullet.beginGroup(); + + while (true) { + // eslint-disable-line no-constant-condition + // Get the parse nodes for the next row. + parsedRows.push(parser.parseExpression(false, "\\\\")); + parser.gullet.endGroup(); + parser.gullet.beginGroup(); + var next = parser.fetch().text; + + if (next === "&" || next === "\\\\") { + parser.consume(); + } else if (next === "\\end") { + if (parsedRows[parsedRows.length - 1].length === 0) { + parsedRows.pop(); // final row ended in \\ + } + + break; + } else { + throw new src_ParseError("Expected \\\\ or \\cr or \\end", parser.nextToken); + } + } + + var row = []; + var body = [row]; // Loop thru the parse nodes. Collect them into cells and arrows. + + for (var i = 0; i < parsedRows.length; i++) { + // Start a new row. + var rowNodes = parsedRows[i]; // Create the first cell. + + var cell = newCell(); + + for (var j = 0; j < rowNodes.length; j++) { + if (!isStartOfArrow(rowNodes[j])) { + // If a parseNode is not an arrow, it goes into a cell. + cell.body.push(rowNodes[j]); + } else { + // Parse node j is an "@", the start of an arrow. + // Before starting on the arrow, push the cell into `row`. + row.push(cell); // Now collect parseNodes into an arrow. + // The character after "@" defines the arrow type. + + j += 1; + var arrowChar = assertSymbolNodeType(rowNodes[j]).text; // Create two empty label nodes. We may or may not use them. + + var labels = new Array(2); + labels[0] = { + type: "ordgroup", + mode: "math", + body: [] + }; + labels[1] = { + type: "ordgroup", + mode: "math", + body: [] + }; // Process the arrow. + + if ("=|.".indexOf(arrowChar) > -1) ; else if ("<>AV".indexOf(arrowChar) > -1) { + // Four arrows, `@>>>`, `@<<<`, `@AAA`, and `@VVV`, each take + // two optional labels. E.g. the right-point arrow syntax is + // really: @>{optional label}>{optional label}> + // Collect parseNodes into labels. + for (var labelNum = 0; labelNum < 2; labelNum++) { + var inLabel = true; + + for (var k = j + 1; k < rowNodes.length; k++) { + if (isLabelEnd(rowNodes[k], arrowChar)) { + inLabel = false; + j = k; + break; + } + + if (isStartOfArrow(rowNodes[k])) { + throw new src_ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[k]); + } + + labels[labelNum].body.push(rowNodes[k]); + } + + if (inLabel) { + // isLabelEnd never returned a true. + throw new src_ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[j]); + } + } + } else { + throw new src_ParseError("Expected one of \"<>AV=|.\" after @", rowNodes[j]); + } // Now join the arrow to its labels. + + + var arrow = cdArrow(arrowChar, labels, parser); // Wrap the arrow in ParseNode<"styling">. + // This is done to match parseArray() behavior. + + var wrappedArrow = { + type: "styling", + body: [arrow], + mode: "math", + style: "display" // CD is always displaystyle. + + }; + row.push(wrappedArrow); // In CD's syntax, cells are implicit. That is, everything that + // is not an arrow gets collected into a cell. So create an empty + // cell now. It will collect upcoming parseNodes. + + cell = newCell(); + } + } + + if (i % 2 === 0) { + // Even-numbered rows consist of: cell, arrow, cell, arrow, ... cell + // The last cell is not yet pushed into `row`, so: + row.push(cell); + } else { + // Odd-numbered rows consist of: vert arrow, empty cell, ... vert arrow + // Remove the empty cell that was placed at the beginning of `row`. + row.shift(); + } + + row = []; + body.push(row); + } // End row group + + + parser.gullet.endGroup(); // End array group defining \\ + + parser.gullet.endGroup(); // define column separation. + + var cols = new Array(body[0].length).fill({ + type: "align", + align: "c", + pregap: 0.25, + // CD package sets \enskip between columns. + postgap: 0.25 // So pre and post each get half an \enskip, i.e. 0.25em. + + }); + return { + type: "array", + mode: "math", + body: body, + arraystretch: 1, + addJot: true, + rowGaps: [null], + cols: cols, + colSeparationType: "CD", + hLinesBeforeRow: new Array(body.length + 1).fill([]) + }; +} // The functions below are not available for general use. +// They are here only for internal use by the {CD} environment in placing labels +// next to vertical arrows. +// We don't need any such functions for horizontal arrows because we can reuse +// the functionality that already exists for extensible arrows. + +defineFunction({ + type: "cdlabel", + names: ["\\\\cdleft", "\\\\cdright"], + props: { + numArgs: 1 + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + return { + type: "cdlabel", + mode: parser.mode, + side: funcName.slice(4), + label: args[0] + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var newOptions = options.havingStyle(options.style.sup()); + var label = buildCommon.wrapFragment(buildGroup(group.label, newOptions, options), options); + label.classes.push("cd-label-" + group.side); + label.style.bottom = makeEm(0.8 - label.depth); // Zero out label height & depth, so vertical align of arrow is set + // by the arrow height, not by the label. + + label.height = 0; + label.depth = 0; + return label; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var label = new mathMLTree.MathNode("mrow", [buildMathML_buildGroup(group.label, options)]); + label = new mathMLTree.MathNode("mpadded", [label]); + label.setAttribute("width", "0"); + + if (group.side === "left") { + label.setAttribute("lspace", "-1width"); + } // We have to guess at vertical alignment. We know the arrow is 1.8em tall, + // But we don't know the height or depth of the label. + + + label.setAttribute("voffset", "0.7em"); + label = new mathMLTree.MathNode("mstyle", [label]); + label.setAttribute("displaystyle", "false"); + label.setAttribute("scriptlevel", "1"); + return label; + } +}); +defineFunction({ + type: "cdlabelparent", + names: ["\\\\cdparent"], + props: { + numArgs: 1 + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + return { + type: "cdlabelparent", + mode: parser.mode, + fragment: args[0] + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Wrap the vertical arrow and its labels. + // The parent gets position: relative. The child gets position: absolute. + // So CSS can locate the label correctly. + var parent = buildCommon.wrapFragment(buildGroup(group.fragment, options), options); + parent.classes.push("cd-vert-arrow"); + return parent; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + return new mathMLTree.MathNode("mrow", [buildMathML_buildGroup(group.fragment, options)]); + } +}); + + + // \@char is an internal function that takes a grouped decimal argument like +// {123} and converts into symbol with code 123. It is used by the *macro* +// \char defined in macros.js. + +defineFunction({ + type: "textord", + names: ["\\@char"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + var arg = assertNodeType(args[0], "ordgroup"); + var group = arg.body; + var number = ""; + + for (var i = 0; i < group.length; i++) { + var node = assertNodeType(group[i], "textord"); + number += node.text; + } + + var code = parseInt(number); + var text; + + if (isNaN(code)) { + throw new src_ParseError("\\@char has non-numeric argument " + number); // If we drop IE support, the following code could be replaced with + // text = String.fromCodePoint(code) + } else if (code < 0 || code >= 0x10ffff) { + throw new src_ParseError("\\@char with invalid code point " + number); + } else if (code <= 0xffff) { + text = String.fromCharCode(code); + } else { + // Astral code point; split into surrogate halves + code -= 0x10000; + text = String.fromCharCode((code >> 10) + 0xd800, (code & 0x3ff) + 0xdc00); + } + + return { + type: "textord", + mode: parser.mode, + text: text + }; + } +}); + + + + + + + +var color_htmlBuilder = function htmlBuilder(group, options) { + var elements = buildExpression(group.body, options.withColor(group.color), false); // \color isn't supposed to affect the type of the elements it contains. + // To accomplish this, we wrap the results in a fragment, so the inner + // elements will be able to directly interact with their neighbors. For + // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3` + + return buildCommon.makeFragment(elements); +}; + +var color_mathmlBuilder = function mathmlBuilder(group, options) { + var inner = buildMathML_buildExpression(group.body, options.withColor(group.color)); + var node = new mathMLTree.MathNode("mstyle", inner); + node.setAttribute("mathcolor", group.color); + return node; +}; + +defineFunction({ + type: "color", + names: ["\\textcolor"], + props: { + numArgs: 2, + allowedInText: true, + argTypes: ["color", "original"] + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + var color = assertNodeType(args[0], "color-token").color; + var body = args[1]; + return { + type: "color", + mode: parser.mode, + color: color, + body: ordargument(body) + }; + }, + htmlBuilder: color_htmlBuilder, + mathmlBuilder: color_mathmlBuilder +}); +defineFunction({ + type: "color", + names: ["\\color"], + props: { + numArgs: 1, + allowedInText: true, + argTypes: ["color"] + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser, + breakOnTokenText = _ref2.breakOnTokenText; + var color = assertNodeType(args[0], "color-token").color; // Set macro \current@color in current namespace to store the current + // color, mimicking the behavior of color.sty. + // This is currently used just to correctly color a \right + // that follows a \color command. + + parser.gullet.macros.set("\\current@color", color); // Parse out the implicit body that should be colored. + + var body = parser.parseExpression(true, breakOnTokenText); + return { + type: "color", + mode: parser.mode, + color: color, + body: body + }; + }, + htmlBuilder: color_htmlBuilder, + mathmlBuilder: color_mathmlBuilder +}); +// Row breaks within tabular environments, and line breaks at top level + + + + + // \DeclareRobustCommand\\{...\@xnewline} + +defineFunction({ + type: "cr", + names: ["\\\\"], + props: { + numArgs: 0, + numOptionalArgs: 1, + argTypes: ["size"], + allowedInText: true + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser; + var size = optArgs[0]; + var newLine = !parser.settings.displayMode || !parser.settings.useStrictBehavior("newLineInDisplayMode", "In LaTeX, \\\\ or \\newline " + "does nothing in display mode"); + return { + type: "cr", + mode: parser.mode, + newLine: newLine, + size: size && assertNodeType(size, "size").value + }; + }, + // The following builders are called only at the top level, + // not within tabular/array environments. + htmlBuilder: function htmlBuilder(group, options) { + var span = buildCommon.makeSpan(["mspace"], [], options); + + if (group.newLine) { + span.classes.push("newline"); + + if (group.size) { + span.style.marginTop = makeEm(calculateSize(group.size, options)); + } + } + + return span; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mspace"); + + if (group.newLine) { + node.setAttribute("linebreak", "newline"); + + if (group.size) { + node.setAttribute("height", makeEm(calculateSize(group.size, options))); + } + } + + return node; + } +}); + + + +var globalMap = { + "\\global": "\\global", + "\\long": "\\\\globallong", + "\\\\globallong": "\\\\globallong", + "\\def": "\\gdef", + "\\gdef": "\\gdef", + "\\edef": "\\xdef", + "\\xdef": "\\xdef", + "\\let": "\\\\globallet", + "\\futurelet": "\\\\globalfuture" +}; + +var checkControlSequence = function checkControlSequence(tok) { + var name = tok.text; + + if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) { + throw new src_ParseError("Expected a control sequence", tok); + } + + return name; +}; + +var getRHS = function getRHS(parser) { + var tok = parser.gullet.popToken(); + + if (tok.text === "=") { + // consume optional equals + tok = parser.gullet.popToken(); + + if (tok.text === " ") { + // consume one optional space + tok = parser.gullet.popToken(); + } + } + + return tok; +}; + +var letCommand = function letCommand(parser, name, tok, global) { + var macro = parser.gullet.macros.get(tok.text); + + if (macro == null) { + // don't expand it later even if a macro with the same name is defined + // e.g., \let\foo=\frac \def\frac{\relax} \frac12 + tok.noexpand = true; + macro = { + tokens: [tok], + numArgs: 0, + // reproduce the same behavior in expansion + unexpandable: !parser.gullet.isExpandable(tok.text) + }; + } + + parser.gullet.macros.set(name, macro, global); +}; // -> | +// -> |\global +// -> | +// -> \global|\long|\outer + + +defineFunction({ + type: "internal", + names: ["\\global", "\\long", "\\\\globallong" // can’t be entered directly + ], + props: { + numArgs: 0, + allowedInText: true + }, + handler: function handler(_ref) { + var parser = _ref.parser, + funcName = _ref.funcName; + parser.consumeSpaces(); + var token = parser.fetch(); + + if (globalMap[token.text]) { + // KaTeX doesn't have \par, so ignore \long + if (funcName === "\\global" || funcName === "\\\\globallong") { + token.text = globalMap[token.text]; + } + + return assertNodeType(parser.parseFunction(), "internal"); + } + + throw new src_ParseError("Invalid token after macro prefix", token); + } +}); // Basic support for macro definitions: \def, \gdef, \edef, \xdef +// -> +// -> \def|\gdef|\edef|\xdef +// -> + +defineFunction({ + type: "internal", + names: ["\\def", "\\gdef", "\\edef", "\\xdef"], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + handler: function handler(_ref2) { + var parser = _ref2.parser, + funcName = _ref2.funcName; + var tok = parser.gullet.popToken(); + var name = tok.text; + + if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) { + throw new src_ParseError("Expected a control sequence", tok); + } + + var numArgs = 0; + var insert; + var delimiters = [[]]; // contains no braces + + while (parser.gullet.future().text !== "{") { + tok = parser.gullet.popToken(); + + if (tok.text === "#") { + // If the very last character of the is #, so that + // this # is immediately followed by {, TeX will behave as if the { + // had been inserted at the right end of both the parameter text + // and the replacement text. + if (parser.gullet.future().text === "{") { + insert = parser.gullet.future(); + delimiters[numArgs].push("{"); + break; + } // A parameter, the first appearance of # must be followed by 1, + // the next by 2, and so on; up to nine #’s are allowed + + + tok = parser.gullet.popToken(); + + if (!/^[1-9]$/.test(tok.text)) { + throw new src_ParseError("Invalid argument number \"" + tok.text + "\""); + } + + if (parseInt(tok.text) !== numArgs + 1) { + throw new src_ParseError("Argument number \"" + tok.text + "\" out of order"); + } + + numArgs++; + delimiters.push([]); + } else if (tok.text === "EOF") { + throw new src_ParseError("Expected a macro definition"); + } else { + delimiters[numArgs].push(tok.text); + } + } // replacement text, enclosed in '{' and '}' and properly nested + + + var _parser$gullet$consum = parser.gullet.consumeArg(), + tokens = _parser$gullet$consum.tokens; + + if (insert) { + tokens.unshift(insert); + } + + if (funcName === "\\edef" || funcName === "\\xdef") { + tokens = parser.gullet.expandTokens(tokens); + tokens.reverse(); // to fit in with stack order + } // Final arg is the expansion of the macro + + + parser.gullet.macros.set(name, { + tokens: tokens, + numArgs: numArgs, + delimiters: delimiters + }, funcName === globalMap[funcName]); + return { + type: "internal", + mode: parser.mode + }; + } +}); // -> +// -> \futurelet +// | \let +// -> |= + +defineFunction({ + type: "internal", + names: ["\\let", "\\\\globallet" // can’t be entered directly + ], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + handler: function handler(_ref3) { + var parser = _ref3.parser, + funcName = _ref3.funcName; + var name = checkControlSequence(parser.gullet.popToken()); + parser.gullet.consumeSpaces(); + var tok = getRHS(parser); + letCommand(parser, name, tok, funcName === "\\\\globallet"); + return { + type: "internal", + mode: parser.mode + }; + } +}); // ref: https://www.tug.org/TUGboat/tb09-3/tb22bechtolsheim.pdf + +defineFunction({ + type: "internal", + names: ["\\futurelet", "\\\\globalfuture" // can’t be entered directly + ], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + handler: function handler(_ref4) { + var parser = _ref4.parser, + funcName = _ref4.funcName; + var name = checkControlSequence(parser.gullet.popToken()); + var middle = parser.gullet.popToken(); + var tok = parser.gullet.popToken(); + letCommand(parser, name, tok, funcName === "\\\\globalfuture"); + parser.gullet.pushToken(tok); + parser.gullet.pushToken(middle); + return { + type: "internal", + mode: parser.mode + }; + } +}); +/** + * This file deals with creating delimiters of various sizes. The TeXbook + * discusses these routines on page 441-442, in the "Another subroutine sets box + * x to a specified variable delimiter" paragraph. + * + * There are three main routines here. `makeSmallDelim` makes a delimiter in the + * normal font, but in either text, script, or scriptscript style. + * `makeLargeDelim` makes a delimiter in textstyle, but in one of the Size1, + * Size2, Size3, or Size4 fonts. `makeStackedDelim` makes a delimiter out of + * smaller pieces that are stacked on top of one another. + * + * The functions take a parameter `center`, which determines if the delimiter + * should be centered around the axis. + * + * Then, there are three exposed functions. `sizedDelim` makes a delimiter in + * one of the given sizes. This is used for things like `\bigl`. + * `customSizedDelim` makes a delimiter with a given total height+depth. It is + * called in places like `\sqrt`. `leftRightDelim` makes an appropriate + * delimiter which surrounds an expression of a given height an depth. It is + * used in `\left` and `\right`. + */ + + + + + + + + + + + +/** + * Get the metrics for a given symbol and font, after transformation (i.e. + * after following replacement from symbols.js) + */ +var getMetrics = function getMetrics(symbol, font, mode) { + var replace = src_symbols.math[symbol] && src_symbols.math[symbol].replace; + var metrics = getCharacterMetrics(replace || symbol, font, mode); + + if (!metrics) { + throw new Error("Unsupported symbol " + symbol + " and font size " + font + "."); + } + + return metrics; +}; +/** + * Puts a delimiter span in a given style, and adds appropriate height, depth, + * and maxFontSizes. + */ + + +var styleWrap = function styleWrap(delim, toStyle, options, classes) { + var newOptions = options.havingBaseStyle(toStyle); + var span = buildCommon.makeSpan(classes.concat(newOptions.sizingClasses(options)), [delim], options); + var delimSizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier; + span.height *= delimSizeMultiplier; + span.depth *= delimSizeMultiplier; + span.maxFontSize = newOptions.sizeMultiplier; + return span; +}; + +var centerSpan = function centerSpan(span, options, style) { + var newOptions = options.havingBaseStyle(style); + var shift = (1 - options.sizeMultiplier / newOptions.sizeMultiplier) * options.fontMetrics().axisHeight; + span.classes.push("delimcenter"); + span.style.top = makeEm(shift); + span.height -= shift; + span.depth += shift; +}; +/** + * Makes a small delimiter. This is a delimiter that comes in the Main-Regular + * font, but is restyled to either be in textstyle, scriptstyle, or + * scriptscriptstyle. + */ + + +var makeSmallDelim = function makeSmallDelim(delim, style, center, options, mode, classes) { + var text = buildCommon.makeSymbol(delim, "Main-Regular", mode, options); + var span = styleWrap(text, style, options, classes); + + if (center) { + centerSpan(span, options, style); + } + + return span; +}; +/** + * Builds a symbol in the given font size (note size is an integer) + */ + + +var mathrmSize = function mathrmSize(value, size, mode, options) { + return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode, options); +}; +/** + * Makes a large delimiter. This is a delimiter that comes in the Size1, Size2, + * Size3, or Size4 fonts. It is always rendered in textstyle. + */ + + +var makeLargeDelim = function makeLargeDelim(delim, size, center, options, mode, classes) { + var inner = mathrmSize(delim, size, mode, options); + var span = styleWrap(buildCommon.makeSpan(["delimsizing", "size" + size], [inner], options), src_Style.TEXT, options, classes); + + if (center) { + centerSpan(span, options, src_Style.TEXT); + } + + return span; +}; +/** + * Make a span from a font glyph with the given offset and in the given font. + * This is used in makeStackedDelim to make the stacking pieces for the delimiter. + */ + + +var makeGlyphSpan = function makeGlyphSpan(symbol, font, mode) { + var sizeClass; // Apply the correct CSS class to choose the right font. + + if (font === "Size1-Regular") { + sizeClass = "delim-size1"; + } else + /* if (font === "Size4-Regular") */ + { + sizeClass = "delim-size4"; + } + + var corner = buildCommon.makeSpan(["delimsizinginner", sizeClass], [buildCommon.makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]); // Since this will be passed into `makeVList` in the end, wrap the element + // in the appropriate tag that VList uses. + + return { + type: "elem", + elem: corner + }; +}; + +var makeInner = function makeInner(ch, height, options) { + // Create a span with inline SVG for the inner part of a tall stacked delimiter. + var width = fontMetricsData["Size4-Regular"][ch.charCodeAt(0)] ? fontMetricsData["Size4-Regular"][ch.charCodeAt(0)][4] : fontMetricsData["Size1-Regular"][ch.charCodeAt(0)][4]; + var path = new PathNode("inner", innerPath(ch, Math.round(1000 * height))); + var svgNode = new SvgNode([path], { + "width": makeEm(width), + "height": makeEm(height), + // Override CSS rule `.katex svg { width: 100% }` + "style": "width:" + makeEm(width), + "viewBox": "0 0 " + 1000 * width + " " + Math.round(1000 * height), + "preserveAspectRatio": "xMinYMin" + }); + var span = buildCommon.makeSvgSpan([], [svgNode], options); + span.height = height; + span.style.height = makeEm(height); + span.style.width = makeEm(width); + return { + type: "elem", + elem: span + }; +}; // Helpers for makeStackedDelim + + +var lapInEms = 0.008; +var lap = { + type: "kern", + size: -1 * lapInEms +}; +var verts = ["|", "\\lvert", "\\rvert", "\\vert"]; +var doubleVerts = ["\\|", "\\lVert", "\\rVert", "\\Vert"]; +/** + * Make a stacked delimiter out of a given delimiter, with the total height at + * least `heightTotal`. This routine is mentioned on page 442 of the TeXbook. + */ + +var makeStackedDelim = function makeStackedDelim(delim, heightTotal, center, options, mode, classes) { + // There are four parts, the top, an optional middle, a repeated part, and a + // bottom. + var top; + var middle; + var repeat; + var bottom; + top = repeat = bottom = delim; + middle = null; // Also keep track of what font the delimiters are in + + var font = "Size1-Regular"; // We set the parts and font based on the symbol. Note that we use + // '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the + // repeats of the arrows + + if (delim === "\\uparrow") { + repeat = bottom = "\u23D0"; + } else if (delim === "\\Uparrow") { + repeat = bottom = "\u2016"; + } else if (delim === "\\downarrow") { + top = repeat = "\u23D0"; + } else if (delim === "\\Downarrow") { + top = repeat = "\u2016"; + } else if (delim === "\\updownarrow") { + top = "\\uparrow"; + repeat = "\u23D0"; + bottom = "\\downarrow"; + } else if (delim === "\\Updownarrow") { + top = "\\Uparrow"; + repeat = "\u2016"; + bottom = "\\Downarrow"; + } else if (utils.contains(verts, delim)) { + repeat = "\u2223"; + } else if (utils.contains(doubleVerts, delim)) { + repeat = "\u2225"; + } else if (delim === "[" || delim === "\\lbrack") { + top = "\u23A1"; + repeat = "\u23A2"; + bottom = "\u23A3"; + font = "Size4-Regular"; + } else if (delim === "]" || delim === "\\rbrack") { + top = "\u23A4"; + repeat = "\u23A5"; + bottom = "\u23A6"; + font = "Size4-Regular"; + } else if (delim === "\\lfloor" || delim === "\u230A") { + repeat = top = "\u23A2"; + bottom = "\u23A3"; + font = "Size4-Regular"; + } else if (delim === "\\lceil" || delim === "\u2308") { + top = "\u23A1"; + repeat = bottom = "\u23A2"; + font = "Size4-Regular"; + } else if (delim === "\\rfloor" || delim === "\u230B") { + repeat = top = "\u23A5"; + bottom = "\u23A6"; + font = "Size4-Regular"; + } else if (delim === "\\rceil" || delim === "\u2309") { + top = "\u23A4"; + repeat = bottom = "\u23A5"; + font = "Size4-Regular"; + } else if (delim === "(" || delim === "\\lparen") { + top = "\u239B"; + repeat = "\u239C"; + bottom = "\u239D"; + font = "Size4-Regular"; + } else if (delim === ")" || delim === "\\rparen") { + top = "\u239E"; + repeat = "\u239F"; + bottom = "\u23A0"; + font = "Size4-Regular"; + } else if (delim === "\\{" || delim === "\\lbrace") { + top = "\u23A7"; + middle = "\u23A8"; + bottom = "\u23A9"; + repeat = "\u23AA"; + font = "Size4-Regular"; + } else if (delim === "\\}" || delim === "\\rbrace") { + top = "\u23AB"; + middle = "\u23AC"; + bottom = "\u23AD"; + repeat = "\u23AA"; + font = "Size4-Regular"; + } else if (delim === "\\lgroup" || delim === "\u27EE") { + top = "\u23A7"; + bottom = "\u23A9"; + repeat = "\u23AA"; + font = "Size4-Regular"; + } else if (delim === "\\rgroup" || delim === "\u27EF") { + top = "\u23AB"; + bottom = "\u23AD"; + repeat = "\u23AA"; + font = "Size4-Regular"; + } else if (delim === "\\lmoustache" || delim === "\u23B0") { + top = "\u23A7"; + bottom = "\u23AD"; + repeat = "\u23AA"; + font = "Size4-Regular"; + } else if (delim === "\\rmoustache" || delim === "\u23B1") { + top = "\u23AB"; + bottom = "\u23A9"; + repeat = "\u23AA"; + font = "Size4-Regular"; + } // Get the metrics of the four sections + + + var topMetrics = getMetrics(top, font, mode); + var topHeightTotal = topMetrics.height + topMetrics.depth; + var repeatMetrics = getMetrics(repeat, font, mode); + var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth; + var bottomMetrics = getMetrics(bottom, font, mode); + var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth; + var middleHeightTotal = 0; + var middleFactor = 1; + + if (middle !== null) { + var middleMetrics = getMetrics(middle, font, mode); + middleHeightTotal = middleMetrics.height + middleMetrics.depth; + middleFactor = 2; // repeat symmetrically above and below middle + } // Calcuate the minimal height that the delimiter can have. + // It is at least the size of the top, bottom, and optional middle combined. + + + var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal; // Compute the number of copies of the repeat symbol we will need + + var repeatCount = Math.max(0, Math.ceil((heightTotal - minHeight) / (middleFactor * repeatHeightTotal))); // Compute the total height of the delimiter including all the symbols + + var realHeightTotal = minHeight + repeatCount * middleFactor * repeatHeightTotal; // The center of the delimiter is placed at the center of the axis. Note + // that in this context, "center" means that the delimiter should be + // centered around the axis in the current style, while normally it is + // centered around the axis in textstyle. + + var axisHeight = options.fontMetrics().axisHeight; + + if (center) { + axisHeight *= options.sizeMultiplier; + } // Calculate the depth + + + var depth = realHeightTotal / 2 - axisHeight; // Now, we start building the pieces that will go into the vlist + // Keep a list of the pieces of the stacked delimiter + + var stack = []; // Add the bottom symbol + + stack.push(makeGlyphSpan(bottom, font, mode)); + stack.push(lap); // overlap + + if (middle === null) { + // The middle section will be an SVG. Make it an extra 0.016em tall. + // We'll overlap by 0.008em at top and bottom. + var innerHeight = realHeightTotal - topHeightTotal - bottomHeightTotal + 2 * lapInEms; + stack.push(makeInner(repeat, innerHeight, options)); + } else { + // When there is a middle bit, we need the middle part and two repeated + // sections + var _innerHeight = (realHeightTotal - topHeightTotal - bottomHeightTotal - middleHeightTotal) / 2 + 2 * lapInEms; + + stack.push(makeInner(repeat, _innerHeight, options)); // Now insert the middle of the brace. + + stack.push(lap); + stack.push(makeGlyphSpan(middle, font, mode)); + stack.push(lap); + stack.push(makeInner(repeat, _innerHeight, options)); + } // Add the top symbol + + + stack.push(lap); + stack.push(makeGlyphSpan(top, font, mode)); // Finally, build the vlist + + var newOptions = options.havingBaseStyle(src_Style.TEXT); + var inner = buildCommon.makeVList({ + positionType: "bottom", + positionData: depth, + children: stack + }, newOptions); + return styleWrap(buildCommon.makeSpan(["delimsizing", "mult"], [inner], newOptions), src_Style.TEXT, options, classes); +}; // All surds have 0.08em padding above the viniculum inside the SVG. +// That keeps browser span height rounding error from pinching the line. + + +var vbPad = 80; // padding above the surd, measured inside the viewBox. + +var emPad = 0.08; // padding, in ems, measured in the document. + +var sqrtSvg = function sqrtSvg(sqrtName, height, viewBoxHeight, extraViniculum, options) { + var path = sqrtPath(sqrtName, extraViniculum, viewBoxHeight); + var pathNode = new PathNode(sqrtName, path); + var svg = new SvgNode([pathNode], { + // Note: 1000:1 ratio of viewBox to document em width. + "width": "400em", + "height": makeEm(height), + "viewBox": "0 0 400000 " + viewBoxHeight, + "preserveAspectRatio": "xMinYMin slice" + }); + return buildCommon.makeSvgSpan(["hide-tail"], [svg], options); +}; +/** + * Make a sqrt image of the given height, + */ + + +var makeSqrtImage = function makeSqrtImage(height, options) { + // Define a newOptions that removes the effect of size changes such as \Huge. + // We don't pick different a height surd for \Huge. For it, we scale up. + var newOptions = options.havingBaseSizing(); // Pick the desired surd glyph from a sequence of surds. + + var delim = traverseSequence("\\surd", height * newOptions.sizeMultiplier, stackLargeDelimiterSequence, newOptions); + var sizeMultiplier = newOptions.sizeMultiplier; // default + // The standard sqrt SVGs each have a 0.04em thick viniculum. + // If Settings.minRuleThickness is larger than that, we add extraViniculum. + + var extraViniculum = Math.max(0, options.minRuleThickness - options.fontMetrics().sqrtRuleThickness); // Create a span containing an SVG image of a sqrt symbol. + + var span; + var spanHeight = 0; + var texHeight = 0; + var viewBoxHeight = 0; + var advanceWidth; // We create viewBoxes with 80 units of "padding" above each surd. + // Then browser rounding error on the parent span height will not + // encroach on the ink of the viniculum. But that padding is not + // included in the TeX-like `height` used for calculation of + // vertical alignment. So texHeight = span.height < span.style.height. + + if (delim.type === "small") { + // Get an SVG that is derived from glyph U+221A in font KaTeX-Main. + // 1000 unit normal glyph height. + viewBoxHeight = 1000 + 1000 * extraViniculum + vbPad; + + if (height < 1.0) { + sizeMultiplier = 1.0; // mimic a \textfont radical + } else if (height < 1.4) { + sizeMultiplier = 0.7; // mimic a \scriptfont radical + } + + spanHeight = (1.0 + extraViniculum + emPad) / sizeMultiplier; + texHeight = (1.00 + extraViniculum) / sizeMultiplier; + span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, extraViniculum, options); + span.style.minWidth = "0.853em"; + advanceWidth = 0.833 / sizeMultiplier; // from the font. + } else if (delim.type === "large") { + // These SVGs come from fonts: KaTeX_Size1, _Size2, etc. + viewBoxHeight = (1000 + vbPad) * sizeToMaxHeight[delim.size]; + texHeight = (sizeToMaxHeight[delim.size] + extraViniculum) / sizeMultiplier; + spanHeight = (sizeToMaxHeight[delim.size] + extraViniculum + emPad) / sizeMultiplier; + span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight, extraViniculum, options); + span.style.minWidth = "1.02em"; + advanceWidth = 1.0 / sizeMultiplier; // 1.0 from the font. + } else { + // Tall sqrt. In TeX, this would be stacked using multiple glyphs. + // We'll use a single SVG to accomplish the same thing. + spanHeight = height + extraViniculum + emPad; + texHeight = height + extraViniculum; + viewBoxHeight = Math.floor(1000 * height + extraViniculum) + vbPad; + span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, extraViniculum, options); + span.style.minWidth = "0.742em"; + advanceWidth = 1.056; + } + + span.height = texHeight; + span.style.height = makeEm(spanHeight); + return { + span: span, + advanceWidth: advanceWidth, + // Calculate the actual line width. + // This actually should depend on the chosen font -- e.g. \boldmath + // should use the thicker surd symbols from e.g. KaTeX_Main-Bold, and + // have thicker rules. + ruleWidth: (options.fontMetrics().sqrtRuleThickness + extraViniculum) * sizeMultiplier + }; +}; // There are three kinds of delimiters, delimiters that stack when they become +// too large + + +var stackLargeDelimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230A", "\u230B", "\\lceil", "\\rceil", "\u2308", "\u2309", "\\surd"]; // delimiters that always stack + +var stackAlwaysDelimiters = ["\\uparrow", "\\downarrow", "\\updownarrow", "\\Uparrow", "\\Downarrow", "\\Updownarrow", "|", "\\|", "\\vert", "\\Vert", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27EE", "\u27EF", "\\lmoustache", "\\rmoustache", "\u23B0", "\u23B1"]; // and delimiters that never stack + +var stackNeverDelimiters = ["<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt"]; // Metrics of the different sizes. Found by looking at TeX's output of +// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$ +// Used to create stacked delimiters of appropriate sizes in makeSizedDelim. + +var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0]; +/** + * Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4. + */ + +var makeSizedDelim = function makeSizedDelim(delim, size, options, mode, classes) { + // < and > turn into \langle and \rangle in delimiters + if (delim === "<" || delim === "\\lt" || delim === "\u27E8") { + delim = "\\langle"; + } else if (delim === ">" || delim === "\\gt" || delim === "\u27E9") { + delim = "\\rangle"; + } // Sized delimiters are never centered. + + + if (utils.contains(stackLargeDelimiters, delim) || utils.contains(stackNeverDelimiters, delim)) { + return makeLargeDelim(delim, size, false, options, mode, classes); + } else if (utils.contains(stackAlwaysDelimiters, delim)) { + return makeStackedDelim(delim, sizeToMaxHeight[size], false, options, mode, classes); + } else { + throw new src_ParseError("Illegal delimiter: '" + delim + "'"); + } +}; +/** + * There are three different sequences of delimiter sizes that the delimiters + * follow depending on the kind of delimiter. This is used when creating custom + * sized delimiters to decide whether to create a small, large, or stacked + * delimiter. + * + * In real TeX, these sequences aren't explicitly defined, but are instead + * defined inside the font metrics. Since there are only three sequences that + * are possible for the delimiters that TeX defines, it is easier to just encode + * them explicitly here. + */ + + +// Delimiters that never stack try small delimiters and large delimiters only +var stackNeverDelimiterSequence = [{ + type: "small", + style: src_Style.SCRIPTSCRIPT +}, { + type: "small", + style: src_Style.SCRIPT +}, { + type: "small", + style: src_Style.TEXT +}, { + type: "large", + size: 1 +}, { + type: "large", + size: 2 +}, { + type: "large", + size: 3 +}, { + type: "large", + size: 4 +}]; // Delimiters that always stack try the small delimiters first, then stack + +var stackAlwaysDelimiterSequence = [{ + type: "small", + style: src_Style.SCRIPTSCRIPT +}, { + type: "small", + style: src_Style.SCRIPT +}, { + type: "small", + style: src_Style.TEXT +}, { + type: "stack" +}]; // Delimiters that stack when large try the small and then large delimiters, and +// stack afterwards + +var stackLargeDelimiterSequence = [{ + type: "small", + style: src_Style.SCRIPTSCRIPT +}, { + type: "small", + style: src_Style.SCRIPT +}, { + type: "small", + style: src_Style.TEXT +}, { + type: "large", + size: 1 +}, { + type: "large", + size: 2 +}, { + type: "large", + size: 3 +}, { + type: "large", + size: 4 +}, { + type: "stack" +}]; +/** + * Get the font used in a delimiter based on what kind of delimiter it is. + * TODO(#963) Use more specific font family return type once that is introduced. + */ + +var delimTypeToFont = function delimTypeToFont(type) { + if (type.type === "small") { + return "Main-Regular"; + } else if (type.type === "large") { + return "Size" + type.size + "-Regular"; + } else if (type.type === "stack") { + return "Size4-Regular"; + } else { + throw new Error("Add support for delim type '" + type.type + "' here."); + } +}; +/** + * Traverse a sequence of types of delimiters to decide what kind of delimiter + * should be used to create a delimiter of the given height+depth. + */ + + +var traverseSequence = function traverseSequence(delim, height, sequence, options) { + // Here, we choose the index we should start at in the sequences. In smaller + // sizes (which correspond to larger numbers in style.size) we start earlier + // in the sequence. Thus, scriptscript starts at index 3-3=0, script starts + // at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2 + var start = Math.min(2, 3 - options.style.size); + + for (var i = start; i < sequence.length; i++) { + if (sequence[i].type === "stack") { + // This is always the last delimiter, so we just break the loop now. + break; + } + + var metrics = getMetrics(delim, delimTypeToFont(sequence[i]), "math"); + var heightDepth = metrics.height + metrics.depth; // Small delimiters are scaled down versions of the same font, so we + // account for the style change size. + + if (sequence[i].type === "small") { + var newOptions = options.havingBaseStyle(sequence[i].style); + heightDepth *= newOptions.sizeMultiplier; + } // Check if the delimiter at this size works for the given height. + + + if (heightDepth > height) { + return sequence[i]; + } + } // If we reached the end of the sequence, return the last sequence element. + + + return sequence[sequence.length - 1]; +}; +/** + * Make a delimiter of a given height+depth, with optional centering. Here, we + * traverse the sequences, and create a delimiter that the sequence tells us to. + */ + + +var makeCustomSizedDelim = function makeCustomSizedDelim(delim, height, center, options, mode, classes) { + if (delim === "<" || delim === "\\lt" || delim === "\u27E8") { + delim = "\\langle"; + } else if (delim === ">" || delim === "\\gt" || delim === "\u27E9") { + delim = "\\rangle"; + } // Decide what sequence to use + + + var sequence; + + if (utils.contains(stackNeverDelimiters, delim)) { + sequence = stackNeverDelimiterSequence; + } else if (utils.contains(stackLargeDelimiters, delim)) { + sequence = stackLargeDelimiterSequence; + } else { + sequence = stackAlwaysDelimiterSequence; + } // Look through the sequence + + + var delimType = traverseSequence(delim, height, sequence, options); // Get the delimiter from font glyphs. + // Depending on the sequence element we decided on, call the + // appropriate function. + + if (delimType.type === "small") { + return makeSmallDelim(delim, delimType.style, center, options, mode, classes); + } else if (delimType.type === "large") { + return makeLargeDelim(delim, delimType.size, center, options, mode, classes); + } else + /* if (delimType.type === "stack") */ + { + return makeStackedDelim(delim, height, center, options, mode, classes); + } +}; +/** + * Make a delimiter for use with `\left` and `\right`, given a height and depth + * of an expression that the delimiters surround. + */ + + +var makeLeftRightDelim = function makeLeftRightDelim(delim, height, depth, options, mode, classes) { + // We always center \left/\right delimiters, so the axis is always shifted + var axisHeight = options.fontMetrics().axisHeight * options.sizeMultiplier; // Taken from TeX source, tex.web, function make_left_right + + var delimiterFactor = 901; + var delimiterExtend = 5.0 / options.fontMetrics().ptPerEm; + var maxDistFromAxis = Math.max(height - axisHeight, depth + axisHeight); + var totalHeight = Math.max( // In real TeX, calculations are done using integral values which are + // 65536 per pt, or 655360 per em. So, the division here truncates in + // TeX but doesn't here, producing different results. If we wanted to + // exactly match TeX's calculation, we could do + // Math.floor(655360 * maxDistFromAxis / 500) * + // delimiterFactor / 655360 + // (To see the difference, compare + // x^{x^{\left(\rule{0.1em}{0.68em}\right)}} + // in TeX and KaTeX) + maxDistFromAxis / 500 * delimiterFactor, 2 * maxDistFromAxis - delimiterExtend); // Finally, we defer to `makeCustomSizedDelim` with our calculated total + // height + + return makeCustomSizedDelim(delim, totalHeight, true, options, mode, classes); +}; + +/* harmony default export */ var delimiter = ({ + sqrtImage: makeSqrtImage, + sizedDelim: makeSizedDelim, + sizeToMaxHeight: sizeToMaxHeight, + customSizedDelim: makeCustomSizedDelim, + leftRightDelim: makeLeftRightDelim +}); + + + + + + + + + + +// Extra data needed for the delimiter handler down below +var delimiterSizes = { + "\\bigl": { + mclass: "mopen", + size: 1 + }, + "\\Bigl": { + mclass: "mopen", + size: 2 + }, + "\\biggl": { + mclass: "mopen", + size: 3 + }, + "\\Biggl": { + mclass: "mopen", + size: 4 + }, + "\\bigr": { + mclass: "mclose", + size: 1 + }, + "\\Bigr": { + mclass: "mclose", + size: 2 + }, + "\\biggr": { + mclass: "mclose", + size: 3 + }, + "\\Biggr": { + mclass: "mclose", + size: 4 + }, + "\\bigm": { + mclass: "mrel", + size: 1 + }, + "\\Bigm": { + mclass: "mrel", + size: 2 + }, + "\\biggm": { + mclass: "mrel", + size: 3 + }, + "\\Biggm": { + mclass: "mrel", + size: 4 + }, + "\\big": { + mclass: "mord", + size: 1 + }, + "\\Big": { + mclass: "mord", + size: 2 + }, + "\\bigg": { + mclass: "mord", + size: 3 + }, + "\\Bigg": { + mclass: "mord", + size: 4 + } +}; +var delimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230A", "\u230B", "\\lceil", "\\rceil", "\u2308", "\u2309", "<", ">", "\\langle", "\u27E8", "\\rangle", "\u27E9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27EE", "\u27EF", "\\lmoustache", "\\rmoustache", "\u23B0", "\u23B1", "/", "\\backslash", "|", "\\vert", "\\|", "\\Vert", "\\uparrow", "\\Uparrow", "\\downarrow", "\\Downarrow", "\\updownarrow", "\\Updownarrow", "."]; + +// Delimiter functions +function checkDelimiter(delim, context) { + var symDelim = checkSymbolNodeType(delim); + + if (symDelim && utils.contains(delimiters, symDelim.text)) { + return symDelim; + } else if (symDelim) { + throw new src_ParseError("Invalid delimiter '" + symDelim.text + "' after '" + context.funcName + "'", delim); + } else { + throw new src_ParseError("Invalid delimiter type '" + delim.type + "'", delim); + } +} + +defineFunction({ + type: "delimsizing", + names: ["\\bigl", "\\Bigl", "\\biggl", "\\Biggl", "\\bigr", "\\Bigr", "\\biggr", "\\Biggr", "\\bigm", "\\Bigm", "\\biggm", "\\Biggm", "\\big", "\\Big", "\\bigg", "\\Bigg"], + props: { + numArgs: 1, + argTypes: ["primitive"] + }, + handler: function handler(context, args) { + var delim = checkDelimiter(args[0], context); + return { + type: "delimsizing", + mode: context.parser.mode, + size: delimiterSizes[context.funcName].size, + mclass: delimiterSizes[context.funcName].mclass, + delim: delim.text + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + if (group.delim === ".") { + // Empty delimiters still count as elements, even though they don't + // show anything. + return buildCommon.makeSpan([group.mclass]); + } // Use delimiter.sizedDelim to generate the delimiter. + + + return delimiter.sizedDelim(group.delim, group.size, options, group.mode, [group.mclass]); + }, + mathmlBuilder: function mathmlBuilder(group) { + var children = []; + + if (group.delim !== ".") { + children.push(makeText(group.delim, group.mode)); + } + + var node = new mathMLTree.MathNode("mo", children); + + if (group.mclass === "mopen" || group.mclass === "mclose") { + // Only some of the delimsizing functions act as fences, and they + // return "mopen" or "mclose" mclass. + node.setAttribute("fence", "true"); + } else { + // Explicitly disable fencing if it's not a fence, to override the + // defaults. + node.setAttribute("fence", "false"); + } + + node.setAttribute("stretchy", "true"); + var size = makeEm(delimiter.sizeToMaxHeight[group.size]); + node.setAttribute("minsize", size); + node.setAttribute("maxsize", size); + return node; + } +}); + +function assertParsed(group) { + if (!group.body) { + throw new Error("Bug: The leftright ParseNode wasn't fully parsed."); + } +} + +defineFunction({ + type: "leftright-right", + names: ["\\right"], + props: { + numArgs: 1, + primitive: true + }, + handler: function handler(context, args) { + // \left case below triggers parsing of \right in + // `const right = parser.parseFunction();` + // uses this return value. + var color = context.parser.gullet.macros.get("\\current@color"); + + if (color && typeof color !== "string") { + throw new src_ParseError("\\current@color set to non-string in \\right"); + } + + return { + type: "leftright-right", + mode: context.parser.mode, + delim: checkDelimiter(args[0], context).text, + color: color // undefined if not set via \color + + }; + } +}); +defineFunction({ + type: "leftright", + names: ["\\left"], + props: { + numArgs: 1, + primitive: true + }, + handler: function handler(context, args) { + var delim = checkDelimiter(args[0], context); + var parser = context.parser; // Parse out the implicit body + + ++parser.leftrightDepth; // parseExpression stops before '\\right' + + var body = parser.parseExpression(false); + --parser.leftrightDepth; // Check the next token + + parser.expect("\\right", false); + var right = assertNodeType(parser.parseFunction(), "leftright-right"); + return { + type: "leftright", + mode: parser.mode, + body: body, + left: delim.text, + right: right.delim, + rightColor: right.color + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + assertParsed(group); // Build the inner expression + + var inner = buildExpression(group.body, options, true, ["mopen", "mclose"]); + var innerHeight = 0; + var innerDepth = 0; + var hadMiddle = false; // Calculate its height and depth + + for (var i = 0; i < inner.length; i++) { + // Property `isMiddle` not defined on `span`. See comment in + // "middle"'s htmlBuilder. + // $FlowFixMe + if (inner[i].isMiddle) { + hadMiddle = true; + } else { + innerHeight = Math.max(inner[i].height, innerHeight); + innerDepth = Math.max(inner[i].depth, innerDepth); + } + } // The size of delimiters is the same, regardless of what style we are + // in. Thus, to correctly calculate the size of delimiter we need around + // a group, we scale down the inner size based on the size. + + + innerHeight *= options.sizeMultiplier; + innerDepth *= options.sizeMultiplier; + var leftDelim; + + if (group.left === ".") { + // Empty delimiters in \left and \right make null delimiter spaces. + leftDelim = makeNullDelimiter(options, ["mopen"]); + } else { + // Otherwise, use leftRightDelim to generate the correct sized + // delimiter. + leftDelim = delimiter.leftRightDelim(group.left, innerHeight, innerDepth, options, group.mode, ["mopen"]); + } // Add it to the beginning of the expression + + + inner.unshift(leftDelim); // Handle middle delimiters + + if (hadMiddle) { + for (var _i = 1; _i < inner.length; _i++) { + var middleDelim = inner[_i]; // Property `isMiddle` not defined on `span`. See comment in + // "middle"'s htmlBuilder. + // $FlowFixMe + + var isMiddle = middleDelim.isMiddle; + + if (isMiddle) { + // Apply the options that were active when \middle was called + inner[_i] = delimiter.leftRightDelim(isMiddle.delim, innerHeight, innerDepth, isMiddle.options, group.mode, []); + } + } + } + + var rightDelim; // Same for the right delimiter, but using color specified by \color + + if (group.right === ".") { + rightDelim = makeNullDelimiter(options, ["mclose"]); + } else { + var colorOptions = group.rightColor ? options.withColor(group.rightColor) : options; + rightDelim = delimiter.leftRightDelim(group.right, innerHeight, innerDepth, colorOptions, group.mode, ["mclose"]); + } // Add it to the end of the expression. + + + inner.push(rightDelim); + return buildCommon.makeSpan(["minner"], inner, options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + assertParsed(group); + var inner = buildMathML_buildExpression(group.body, options); + + if (group.left !== ".") { + var leftNode = new mathMLTree.MathNode("mo", [makeText(group.left, group.mode)]); + leftNode.setAttribute("fence", "true"); + inner.unshift(leftNode); + } + + if (group.right !== ".") { + var rightNode = new mathMLTree.MathNode("mo", [makeText(group.right, group.mode)]); + rightNode.setAttribute("fence", "true"); + + if (group.rightColor) { + rightNode.setAttribute("mathcolor", group.rightColor); + } + + inner.push(rightNode); + } + + return makeRow(inner); + } +}); +defineFunction({ + type: "middle", + names: ["\\middle"], + props: { + numArgs: 1, + primitive: true + }, + handler: function handler(context, args) { + var delim = checkDelimiter(args[0], context); + + if (!context.parser.leftrightDepth) { + throw new src_ParseError("\\middle without preceding \\left", delim); + } + + return { + type: "middle", + mode: context.parser.mode, + delim: delim.text + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var middleDelim; + + if (group.delim === ".") { + middleDelim = makeNullDelimiter(options, []); + } else { + middleDelim = delimiter.sizedDelim(group.delim, 1, options, group.mode, []); + var isMiddle = { + delim: group.delim, + options: options + }; // Property `isMiddle` not defined on `span`. It is only used in + // this file above. + // TODO: Fix this violation of the `span` type and possibly rename + // things since `isMiddle` sounds like a boolean, but is a struct. + // $FlowFixMe + + middleDelim.isMiddle = isMiddle; + } + + return middleDelim; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + // A Firefox \middle will strech a character vertically only if it + // is in the fence part of the operator dictionary at: + // https://www.w3.org/TR/MathML3/appendixc.html. + // So we need to avoid U+2223 and use plain "|" instead. + var textNode = group.delim === "\\vert" || group.delim === "|" ? makeText("|", "text") : makeText(group.delim, group.mode); + var middleNode = new mathMLTree.MathNode("mo", [textNode]); + middleNode.setAttribute("fence", "true"); // MathML gives 5/18em spacing to each element. + // \middle should get delimiter spacing instead. + + middleNode.setAttribute("lspace", "0.05em"); + middleNode.setAttribute("rspace", "0.05em"); + return middleNode; + } +}); + + + + + + + + + + + + +var enclose_htmlBuilder = function htmlBuilder(group, options) { + // \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox, \phase + // Some groups can return document fragments. Handle those by wrapping + // them in a span. + var inner = buildCommon.wrapFragment(buildGroup(group.body, options), options); + var label = group.label.substr(1); + var scale = options.sizeMultiplier; + var img; + var imgShift = 0; // In the LaTeX cancel package, line geometry is slightly different + // depending on whether the subject is wider than it is tall, or vice versa. + // We don't know the width of a group, so as a proxy, we test if + // the subject is a single character. This captures most of the + // subjects that should get the "tall" treatment. + + var isSingleChar = utils.isCharacterBox(group.body); + + if (label === "sout") { + img = buildCommon.makeSpan(["stretchy", "sout"]); + img.height = options.fontMetrics().defaultRuleThickness / scale; + imgShift = -0.5 * options.fontMetrics().xHeight; + } else if (label === "phase") { + // Set a couple of dimensions from the steinmetz package. + var lineWeight = calculateSize({ + number: 0.6, + unit: "pt" + }, options); + var clearance = calculateSize({ + number: 0.35, + unit: "ex" + }, options); // Prevent size changes like \Huge from affecting line thickness + + var newOptions = options.havingBaseSizing(); + scale = scale / newOptions.sizeMultiplier; + var angleHeight = inner.height + inner.depth + lineWeight + clearance; // Reserve a left pad for the angle. + + inner.style.paddingLeft = makeEm(angleHeight / 2 + lineWeight); // Create an SVG + + var viewBoxHeight = Math.floor(1000 * angleHeight * scale); + var path = phasePath(viewBoxHeight); + var svgNode = new SvgNode([new PathNode("phase", path)], { + "width": "400em", + "height": makeEm(viewBoxHeight / 1000), + "viewBox": "0 0 400000 " + viewBoxHeight, + "preserveAspectRatio": "xMinYMin slice" + }); // Wrap it in a span with overflow: hidden. + + img = buildCommon.makeSvgSpan(["hide-tail"], [svgNode], options); + img.style.height = makeEm(angleHeight); + imgShift = inner.depth + lineWeight + clearance; + } else { + // Add horizontal padding + if (/cancel/.test(label)) { + if (!isSingleChar) { + inner.classes.push("cancel-pad"); + } + } else if (label === "angl") { + inner.classes.push("anglpad"); + } else { + inner.classes.push("boxpad"); + } // Add vertical padding + + + var topPad = 0; + var bottomPad = 0; + var ruleThickness = 0; // ref: cancel package: \advance\totalheight2\p@ % "+2" + + if (/box/.test(label)) { + ruleThickness = Math.max(options.fontMetrics().fboxrule, // default + options.minRuleThickness // User override. + ); + topPad = options.fontMetrics().fboxsep + (label === "colorbox" ? 0 : ruleThickness); + bottomPad = topPad; + } else if (label === "angl") { + ruleThickness = Math.max(options.fontMetrics().defaultRuleThickness, options.minRuleThickness); + topPad = 4 * ruleThickness; // gap = 3 × line, plus the line itself. + + bottomPad = Math.max(0, 0.25 - inner.depth); + } else { + topPad = isSingleChar ? 0.2 : 0; + bottomPad = topPad; + } + + img = stretchy.encloseSpan(inner, label, topPad, bottomPad, options); + + if (/fbox|boxed|fcolorbox/.test(label)) { + img.style.borderStyle = "solid"; + img.style.borderWidth = makeEm(ruleThickness); + } else if (label === "angl" && ruleThickness !== 0.049) { + img.style.borderTopWidth = makeEm(ruleThickness); + img.style.borderRightWidth = makeEm(ruleThickness); + } + + imgShift = inner.depth + bottomPad; + + if (group.backgroundColor) { + img.style.backgroundColor = group.backgroundColor; + + if (group.borderColor) { + img.style.borderColor = group.borderColor; + } + } + } + + var vlist; + + if (group.backgroundColor) { + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [// Put the color background behind inner; + { + type: "elem", + elem: img, + shift: imgShift + }, { + type: "elem", + elem: inner, + shift: 0 + }] + }, options); + } else { + var classes = /cancel|phase/.test(label) ? ["svg-align"] : []; + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [// Write the \cancel stroke on top of inner. + { + type: "elem", + elem: inner, + shift: 0 + }, { + type: "elem", + elem: img, + shift: imgShift, + wrapperClasses: classes + }] + }, options); + } + + if (/cancel/.test(label)) { + // The cancel package documentation says that cancel lines add their height + // to the expression, but tests show that isn't how it actually works. + vlist.height = inner.height; + vlist.depth = inner.depth; + } + + if (/cancel/.test(label) && !isSingleChar) { + // cancel does not create horiz space for its line extension. + return buildCommon.makeSpan(["mord", "cancel-lap"], [vlist], options); + } else { + return buildCommon.makeSpan(["mord"], [vlist], options); + } +}; + +var enclose_mathmlBuilder = function mathmlBuilder(group, options) { + var fboxsep = 0; + var node = new mathMLTree.MathNode(group.label.indexOf("colorbox") > -1 ? "mpadded" : "menclose", [buildMathML_buildGroup(group.body, options)]); + + switch (group.label) { + case "\\cancel": + node.setAttribute("notation", "updiagonalstrike"); + break; + + case "\\bcancel": + node.setAttribute("notation", "downdiagonalstrike"); + break; + + case "\\phase": + node.setAttribute("notation", "phasorangle"); + break; + + case "\\sout": + node.setAttribute("notation", "horizontalstrike"); + break; + + case "\\fbox": + node.setAttribute("notation", "box"); + break; + + case "\\angl": + node.setAttribute("notation", "actuarial"); + break; + + case "\\fcolorbox": + case "\\colorbox": + // doesn't have a good notation option. So use + // instead. Set some attributes that come included with . + fboxsep = options.fontMetrics().fboxsep * options.fontMetrics().ptPerEm; + node.setAttribute("width", "+" + 2 * fboxsep + "pt"); + node.setAttribute("height", "+" + 2 * fboxsep + "pt"); + node.setAttribute("lspace", fboxsep + "pt"); // + + node.setAttribute("voffset", fboxsep + "pt"); + + if (group.label === "\\fcolorbox") { + var thk = Math.max(options.fontMetrics().fboxrule, // default + options.minRuleThickness // user override + ); + node.setAttribute("style", "border: " + thk + "em solid " + String(group.borderColor)); + } + + break; + + case "\\xcancel": + node.setAttribute("notation", "updiagonalstrike downdiagonalstrike"); + break; + } + + if (group.backgroundColor) { + node.setAttribute("mathbackground", group.backgroundColor); + } + + return node; +}; + +defineFunction({ + type: "enclose", + names: ["\\colorbox"], + props: { + numArgs: 2, + allowedInText: true, + argTypes: ["color", "text"] + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser, + funcName = _ref.funcName; + var color = assertNodeType(args[0], "color-token").color; + var body = args[1]; + return { + type: "enclose", + mode: parser.mode, + label: funcName, + backgroundColor: color, + body: body + }; + }, + htmlBuilder: enclose_htmlBuilder, + mathmlBuilder: enclose_mathmlBuilder +}); +defineFunction({ + type: "enclose", + names: ["\\fcolorbox"], + props: { + numArgs: 3, + allowedInText: true, + argTypes: ["color", "color", "text"] + }, + handler: function handler(_ref2, args, optArgs) { + var parser = _ref2.parser, + funcName = _ref2.funcName; + var borderColor = assertNodeType(args[0], "color-token").color; + var backgroundColor = assertNodeType(args[1], "color-token").color; + var body = args[2]; + return { + type: "enclose", + mode: parser.mode, + label: funcName, + backgroundColor: backgroundColor, + borderColor: borderColor, + body: body + }; + }, + htmlBuilder: enclose_htmlBuilder, + mathmlBuilder: enclose_mathmlBuilder +}); +defineFunction({ + type: "enclose", + names: ["\\fbox"], + props: { + numArgs: 1, + argTypes: ["hbox"], + allowedInText: true + }, + handler: function handler(_ref3, args) { + var parser = _ref3.parser; + return { + type: "enclose", + mode: parser.mode, + label: "\\fbox", + body: args[0] + }; + } +}); +defineFunction({ + type: "enclose", + names: ["\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\phase"], + props: { + numArgs: 1 + }, + handler: function handler(_ref4, args) { + var parser = _ref4.parser, + funcName = _ref4.funcName; + var body = args[0]; + return { + type: "enclose", + mode: parser.mode, + label: funcName, + body: body + }; + }, + htmlBuilder: enclose_htmlBuilder, + mathmlBuilder: enclose_mathmlBuilder +}); +defineFunction({ + type: "enclose", + names: ["\\angl"], + props: { + numArgs: 1, + argTypes: ["hbox"], + allowedInText: false + }, + handler: function handler(_ref5, args) { + var parser = _ref5.parser; + return { + type: "enclose", + mode: parser.mode, + label: "\\angl", + body: args[0] + }; + } +}); + + +/** + * All registered environments. + * `environments.js` exports this same dictionary again and makes it public. + * `Parser.js` requires this dictionary via `environments.js`. + */ +var _environments = {}; +function defineEnvironment(_ref) { + var type = _ref.type, + names = _ref.names, + props = _ref.props, + handler = _ref.handler, + htmlBuilder = _ref.htmlBuilder, + mathmlBuilder = _ref.mathmlBuilder; + // Set default values of environments. + var data = { + type: type, + numArgs: props.numArgs || 0, + allowedInText: false, + numOptionalArgs: 0, + handler: handler + }; + + for (var i = 0; i < names.length; ++i) { + // TODO: The value type of _environments should be a type union of all + // possible `EnvSpec<>` possibilities instead of `EnvSpec<*>`, which is + // an existential type. + _environments[names[i]] = data; + } + + if (htmlBuilder) { + _htmlGroupBuilders[type] = htmlBuilder; + } + + if (mathmlBuilder) { + _mathmlGroupBuilders[type] = mathmlBuilder; + } +} + + + + + + + + + + + + + + +// Helper functions +function getHLines(parser) { + // Return an array. The array length = number of hlines. + // Each element in the array tells if the line is dashed. + var hlineInfo = []; + parser.consumeSpaces(); + var nxt = parser.fetch().text; + + while (nxt === "\\hline" || nxt === "\\hdashline") { + parser.consume(); + hlineInfo.push(nxt === "\\hdashline"); + parser.consumeSpaces(); + nxt = parser.fetch().text; + } + + return hlineInfo; +} + +var validateAmsEnvironmentContext = function validateAmsEnvironmentContext(context) { + var settings = context.parser.settings; + + if (!settings.displayMode) { + throw new src_ParseError("{" + context.envName + "} can be used only in" + " display mode."); + } +}; +/** + * Parse the body of the environment, with rows delimited by \\ and + * columns delimited by &, and create a nested list in row-major order + * with one group per cell. If given an optional argument style + * ("text", "display", etc.), then each cell is cast into that style. + */ + + +function parseArray(parser, _ref, style) { + var hskipBeforeAndAfter = _ref.hskipBeforeAndAfter, + addJot = _ref.addJot, + cols = _ref.cols, + arraystretch = _ref.arraystretch, + colSeparationType = _ref.colSeparationType, + addEqnNum = _ref.addEqnNum, + singleRow = _ref.singleRow, + emptySingleRow = _ref.emptySingleRow, + maxNumCols = _ref.maxNumCols, + leqno = _ref.leqno; + parser.gullet.beginGroup(); + + if (!singleRow) { + // \cr is equivalent to \\ without the optional size argument (see below) + // TODO: provide helpful error when \cr is used outside array environment + parser.gullet.macros.set("\\cr", "\\\\\\relax"); + } // Get current arraystretch if it's not set by the environment + + + if (!arraystretch) { + var stretch = parser.gullet.expandMacroAsText("\\arraystretch"); + + if (stretch == null) { + // Default \arraystretch from lttab.dtx + arraystretch = 1; + } else { + arraystretch = parseFloat(stretch); + + if (!arraystretch || arraystretch < 0) { + throw new src_ParseError("Invalid \\arraystretch: " + stretch); + } + } + } // Start group for first cell + + + parser.gullet.beginGroup(); + var row = []; + var body = [row]; + var rowGaps = []; + var hLinesBeforeRow = []; // Test for \hline at the top of the array. + + hLinesBeforeRow.push(getHLines(parser)); + + while (true) { + // eslint-disable-line no-constant-condition + // Parse each cell in its own group (namespace) + var cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\"); + parser.gullet.endGroup(); + parser.gullet.beginGroup(); + cell = { + type: "ordgroup", + mode: parser.mode, + body: cell + }; + + if (style) { + cell = { + type: "styling", + mode: parser.mode, + style: style, + body: [cell] + }; + } + + row.push(cell); + var next = parser.fetch().text; + + if (next === "&") { + if (maxNumCols && row.length === maxNumCols) { + if (singleRow || colSeparationType) { + // {equation} or {split} + throw new src_ParseError("Too many tab characters: &", parser.nextToken); + } else { + // {array} environment + parser.settings.reportNonstrict("textEnv", "Too few columns " + "specified in the {array} column argument."); + } + } + + parser.consume(); + } else if (next === "\\end") { + // Arrays terminate newlines with `\crcr` which consumes a `\cr` if + // the last line is empty. However, AMS environments keep the + // empty row if it's the only one. + // NOTE: Currently, `cell` is the last item added into `row`. + if (row.length === 1 && cell.type === "styling" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) { + body.pop(); + } + + if (hLinesBeforeRow.length < body.length + 1) { + hLinesBeforeRow.push([]); + } + + break; + } else if (next === "\\\\") { + parser.consume(); + var size = void 0; // \def\Let@{\let\\\math@cr} + // \def\math@cr{...\math@cr@} + // \def\math@cr@{\new@ifnextchar[\math@cr@@{\math@cr@@[\z@]}} + // \def\math@cr@@[#1]{...\math@cr@@@...} + // \def\math@cr@@@{\cr} + + if (parser.gullet.future().text !== " ") { + size = parser.parseSizeGroup(true); + } + + rowGaps.push(size ? size.value : null); // check for \hline(s) following the row separator + + hLinesBeforeRow.push(getHLines(parser)); + row = []; + body.push(row); + } else { + throw new src_ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken); + } + } // End cell group + + + parser.gullet.endGroup(); // End array group defining \cr + + parser.gullet.endGroup(); + return { + type: "array", + mode: parser.mode, + addJot: addJot, + arraystretch: arraystretch, + body: body, + cols: cols, + rowGaps: rowGaps, + hskipBeforeAndAfter: hskipBeforeAndAfter, + hLinesBeforeRow: hLinesBeforeRow, + colSeparationType: colSeparationType, + addEqnNum: addEqnNum, + leqno: leqno + }; +} // Decides on a style for cells in an array according to whether the given +// environment name starts with the letter 'd'. + + +function dCellStyle(envName) { + if (envName.substr(0, 1) === "d") { + return "display"; + } else { + return "text"; + } +} + +var array_htmlBuilder = function htmlBuilder(group, options) { + var r; + var c; + var nr = group.body.length; + var hLinesBeforeRow = group.hLinesBeforeRow; + var nc = 0; + var body = new Array(nr); + var hlines = []; + var ruleThickness = Math.max( // From LaTeX \showthe\arrayrulewidth. Equals 0.04 em. + options.fontMetrics().arrayRuleWidth, options.minRuleThickness // User override. + ); // Horizontal spacing + + var pt = 1 / options.fontMetrics().ptPerEm; + var arraycolsep = 5 * pt; // default value, i.e. \arraycolsep in article.cls + + if (group.colSeparationType && group.colSeparationType === "small") { + // We're in a {smallmatrix}. Default column space is \thickspace, + // i.e. 5/18em = 0.2778em, per amsmath.dtx for {smallmatrix}. + // But that needs adjustment because LaTeX applies \scriptstyle to the + // entire array, including the colspace, but this function applies + // \scriptstyle only inside each element. + var localMultiplier = options.havingStyle(src_Style.SCRIPT).sizeMultiplier; + arraycolsep = 0.2778 * (localMultiplier / options.sizeMultiplier); + } // Vertical spacing + + + var baselineskip = group.colSeparationType === "CD" ? calculateSize({ + number: 3, + unit: "ex" + }, options) : 12 * pt; // see size10.clo + // Default \jot from ltmath.dtx + // TODO(edemaine): allow overriding \jot via \setlength (#687) + + var jot = 3 * pt; + var arrayskip = group.arraystretch * baselineskip; + var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and + + var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx + + var totalHeight = 0; // Set a position for \hline(s) at the top of the array, if any. + + function setHLinePos(hlinesInGap) { + for (var i = 0; i < hlinesInGap.length; ++i) { + if (i > 0) { + totalHeight += 0.25; + } + + hlines.push({ + pos: totalHeight, + isDashed: hlinesInGap[i] + }); + } + } + + setHLinePos(hLinesBeforeRow[0]); + + for (r = 0; r < group.body.length; ++r) { + var inrow = group.body[r]; + var height = arstrutHeight; // \@array adds an \@arstrut + + var depth = arstrutDepth; // to each tow (via the template) + + if (nc < inrow.length) { + nc = inrow.length; + } + + var outrow = new Array(inrow.length); + + for (c = 0; c < inrow.length; ++c) { + var elt = buildGroup(inrow[c], options); + + if (depth < elt.depth) { + depth = elt.depth; + } + + if (height < elt.height) { + height = elt.height; + } + + outrow[c] = elt; + } + + var rowGap = group.rowGaps[r]; + var gap = 0; + + if (rowGap) { + gap = calculateSize(rowGap, options); + + if (gap > 0) { + // \@argarraycr + gap += arstrutDepth; + + if (depth < gap) { + depth = gap; // \@xargarraycr + } + + gap = 0; + } + } // In AMS multiline environments such as aligned and gathered, rows + // correspond to lines that have additional \jot added to the + // \baselineskip via \openup. + + + if (group.addJot) { + depth += jot; + } + + outrow.height = height; + outrow.depth = depth; + totalHeight += height; + outrow.pos = totalHeight; + totalHeight += depth + gap; // \@yargarraycr + + body[r] = outrow; // Set a position for \hline(s), if any. + + setHLinePos(hLinesBeforeRow[r + 1]); + } + + var offset = totalHeight / 2 + options.fontMetrics().axisHeight; + var colDescriptions = group.cols || []; + var cols = []; + var colSep; + var colDescrNum; + var eqnNumSpans = []; + + if (group.addEqnNum) { + // An environment with automatic equation numbers. + // Create node(s) that will trigger CSS counter increment. + for (r = 0; r < nr; ++r) { + var rw = body[r]; + var shift = rw.pos - offset; + var eqnTag = buildCommon.makeSpan(["eqn-num"], [], options); + eqnTag.depth = rw.depth; + eqnTag.height = rw.height; + eqnNumSpans.push({ + type: "elem", + elem: eqnTag, + shift: shift + }); + } + } + + for (c = 0, colDescrNum = 0; // Continue while either there are more columns or more column + // descriptions, so trailing separators don't get lost. + c < nc || colDescrNum < colDescriptions.length; ++c, ++colDescrNum) { + var colDescr = colDescriptions[colDescrNum] || {}; + var firstSeparator = true; + + while (colDescr.type === "separator") { + // If there is more than one separator in a row, add a space + // between them. + if (!firstSeparator) { + colSep = buildCommon.makeSpan(["arraycolsep"], []); + colSep.style.width = makeEm(options.fontMetrics().doubleRuleSep); + cols.push(colSep); + } + + if (colDescr.separator === "|" || colDescr.separator === ":") { + var lineType = colDescr.separator === "|" ? "solid" : "dashed"; + var separator = buildCommon.makeSpan(["vertical-separator"], [], options); + separator.style.height = makeEm(totalHeight); + separator.style.borderRightWidth = makeEm(ruleThickness); + separator.style.borderRightStyle = lineType; + separator.style.margin = "0 " + makeEm(-ruleThickness / 2); + + var _shift = totalHeight - offset; + + if (_shift) { + separator.style.verticalAlign = makeEm(-_shift); + } + + cols.push(separator); + } else { + throw new src_ParseError("Invalid separator type: " + colDescr.separator); + } + + colDescrNum++; + colDescr = colDescriptions[colDescrNum] || {}; + firstSeparator = false; + } + + if (c >= nc) { + continue; + } + + var sepwidth = void 0; + + if (c > 0 || group.hskipBeforeAndAfter) { + sepwidth = utils.deflt(colDescr.pregap, arraycolsep); + + if (sepwidth !== 0) { + colSep = buildCommon.makeSpan(["arraycolsep"], []); + colSep.style.width = makeEm(sepwidth); + cols.push(colSep); + } + } + + var col = []; + + for (r = 0; r < nr; ++r) { + var row = body[r]; + var elem = row[c]; + + if (!elem) { + continue; + } + + var _shift2 = row.pos - offset; + + elem.depth = row.depth; + elem.height = row.height; + col.push({ + type: "elem", + elem: elem, + shift: _shift2 + }); + } + + col = buildCommon.makeVList({ + positionType: "individualShift", + children: col + }, options); + col = buildCommon.makeSpan(["col-align-" + (colDescr.align || "c")], [col]); + cols.push(col); + + if (c < nc - 1 || group.hskipBeforeAndAfter) { + sepwidth = utils.deflt(colDescr.postgap, arraycolsep); + + if (sepwidth !== 0) { + colSep = buildCommon.makeSpan(["arraycolsep"], []); + colSep.style.width = makeEm(sepwidth); + cols.push(colSep); + } + } + } + + body = buildCommon.makeSpan(["mtable"], cols); // Add \hline(s), if any. + + if (hlines.length > 0) { + var line = buildCommon.makeLineSpan("hline", options, ruleThickness); + var dashes = buildCommon.makeLineSpan("hdashline", options, ruleThickness); + var vListElems = [{ + type: "elem", + elem: body, + shift: 0 + }]; + + while (hlines.length > 0) { + var hline = hlines.pop(); + var lineShift = hline.pos - offset; + + if (hline.isDashed) { + vListElems.push({ + type: "elem", + elem: dashes, + shift: lineShift + }); + } else { + vListElems.push({ + type: "elem", + elem: line, + shift: lineShift + }); + } + } + + body = buildCommon.makeVList({ + positionType: "individualShift", + children: vListElems + }, options); + } + + if (!group.addEqnNum) { + return buildCommon.makeSpan(["mord"], [body], options); + } else { + var eqnNumCol = buildCommon.makeVList({ + positionType: "individualShift", + children: eqnNumSpans + }, options); + eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options); + return buildCommon.makeFragment([body, eqnNumCol]); + } +}; + +var alignMap = { + c: "center ", + l: "left ", + r: "right " +}; + +var array_mathmlBuilder = function mathmlBuilder(group, options) { + var tbl = []; + var glue = new mathMLTree.MathNode("mtd", [], ["mtr-glue"]); + var tag = new mathMLTree.MathNode("mtd", [], ["mml-eqn-num"]); + + for (var i = 0; i < group.body.length; i++) { + var rw = group.body[i]; + var row = []; + + for (var j = 0; j < rw.length; j++) { + row.push(new mathMLTree.MathNode("mtd", [buildMathML_buildGroup(rw[j], options)])); + } + + if (group.addEqnNum) { + row.unshift(glue); + row.push(glue); + + if (group.leqno) { + row.unshift(tag); + } else { + row.push(tag); + } + } + + tbl.push(new mathMLTree.MathNode("mtr", row)); + } + + var table = new mathMLTree.MathNode("mtable", tbl); // Set column alignment, row spacing, column spacing, and + // array lines by setting attributes on the table element. + // Set the row spacing. In MathML, we specify a gap distance. + // We do not use rowGap[] because MathML automatically increases + // cell height with the height/depth of the element content. + // LaTeX \arraystretch multiplies the row baseline-to-baseline distance. + // We simulate this by adding (arraystretch - 1)em to the gap. This + // does a reasonable job of adjusting arrays containing 1 em tall content. + // The 0.16 and 0.09 values are found emprically. They produce an array + // similar to LaTeX and in which content does not interfere with \hines. + + var gap = group.arraystretch === 0.5 ? 0.1 // {smallmatrix}, {subarray} + : 0.16 + group.arraystretch - 1 + (group.addJot ? 0.09 : 0); + table.setAttribute("rowspacing", makeEm(gap)); // MathML table lines go only between cells. + // To place a line on an edge we'll use , if necessary. + + var menclose = ""; + var align = ""; + + if (group.cols && group.cols.length > 0) { + // Find column alignment, column spacing, and vertical lines. + var cols = group.cols; + var columnLines = ""; + var prevTypeWasAlign = false; + var iStart = 0; + var iEnd = cols.length; + + if (cols[0].type === "separator") { + menclose += "top "; + iStart = 1; + } + + if (cols[cols.length - 1].type === "separator") { + menclose += "bottom "; + iEnd -= 1; + } + + for (var _i = iStart; _i < iEnd; _i++) { + if (cols[_i].type === "align") { + align += alignMap[cols[_i].align]; + + if (prevTypeWasAlign) { + columnLines += "none "; + } + + prevTypeWasAlign = true; + } else if (cols[_i].type === "separator") { + // MathML accepts only single lines between cells. + // So we read only the first of consecutive separators. + if (prevTypeWasAlign) { + columnLines += cols[_i].separator === "|" ? "solid " : "dashed "; + prevTypeWasAlign = false; + } + } + } + + table.setAttribute("columnalign", align.trim()); + + if (/[sd]/.test(columnLines)) { + table.setAttribute("columnlines", columnLines.trim()); + } + } // Set column spacing. + + + if (group.colSeparationType === "align") { + var _cols = group.cols || []; + + var spacing = ""; + + for (var _i2 = 1; _i2 < _cols.length; _i2++) { + spacing += _i2 % 2 ? "0em " : "1em "; + } + + table.setAttribute("columnspacing", spacing.trim()); + } else if (group.colSeparationType === "alignat" || group.colSeparationType === "gather") { + table.setAttribute("columnspacing", "0em"); + } else if (group.colSeparationType === "small") { + table.setAttribute("columnspacing", "0.2778em"); + } else if (group.colSeparationType === "CD") { + table.setAttribute("columnspacing", "0.5em"); + } else { + table.setAttribute("columnspacing", "1em"); + } // Address \hline and \hdashline + + + var rowLines = ""; + var hlines = group.hLinesBeforeRow; + menclose += hlines[0].length > 0 ? "left " : ""; + menclose += hlines[hlines.length - 1].length > 0 ? "right " : ""; + + for (var _i3 = 1; _i3 < hlines.length - 1; _i3++) { + rowLines += hlines[_i3].length === 0 ? "none " // MathML accepts only a single line between rows. Read one element. + : hlines[_i3][0] ? "dashed " : "solid "; + } + + if (/[sd]/.test(rowLines)) { + table.setAttribute("rowlines", rowLines.trim()); + } + + if (menclose !== "") { + table = new mathMLTree.MathNode("menclose", [table]); + table.setAttribute("notation", menclose.trim()); + } + + if (group.arraystretch && group.arraystretch < 1) { + // A small array. Wrap in scriptstyle so row gap is not too large. + table = new mathMLTree.MathNode("mstyle", [table]); + table.setAttribute("scriptlevel", "1"); + } + + return table; +}; // Convenience function for align, align*, aligned, alignat, alignat*, alignedat. + + +var alignedHandler = function alignedHandler(context, args) { + if (context.envName.indexOf("ed") === -1) { + validateAmsEnvironmentContext(context); + } + + var cols = []; + var separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align"; + var res = parseArray(context.parser, { + cols: cols, + addJot: true, + addEqnNum: context.envName === "align" || context.envName === "alignat", + emptySingleRow: true, + colSeparationType: separationType, + maxNumCols: context.envName === "split" ? 2 : undefined, + leqno: context.parser.settings.leqno + }, "display"); // Determining number of columns. + // 1. If the first argument is given, we use it as a number of columns, + // and makes sure that each row doesn't exceed that number. + // 2. Otherwise, just count number of columns = maximum number + // of cells in each row ("aligned" mode -- isAligned will be true). + // + // At the same time, prepend empty group {} at beginning of every second + // cell in each row (starting with second cell) so that operators become + // binary. This behavior is implemented in amsmath's \start@aligned. + + var numMaths; + var numCols = 0; + var emptyGroup = { + type: "ordgroup", + mode: context.mode, + body: [] + }; + + if (args[0] && args[0].type === "ordgroup") { + var arg0 = ""; + + for (var i = 0; i < args[0].body.length; i++) { + var textord = assertNodeType(args[0].body[i], "textord"); + arg0 += textord.text; + } + + numMaths = Number(arg0); + numCols = numMaths * 2; + } + + var isAligned = !numCols; + res.body.forEach(function (row) { + for (var _i4 = 1; _i4 < row.length; _i4 += 2) { + // Modify ordgroup node within styling node + var styling = assertNodeType(row[_i4], "styling"); + var ordgroup = assertNodeType(styling.body[0], "ordgroup"); + ordgroup.body.unshift(emptyGroup); + } + + if (!isAligned) { + // Case 1 + var curMaths = row.length / 2; + + if (numMaths < curMaths) { + throw new src_ParseError("Too many math in a row: " + ("expected " + numMaths + ", but got " + curMaths), row[0]); + } + } else if (numCols < row.length) { + // Case 2 + numCols = row.length; + } + }); // Adjusting alignment. + // In aligned mode, we add one \qquad between columns; + // otherwise we add nothing. + + for (var _i5 = 0; _i5 < numCols; ++_i5) { + var align = "r"; + var pregap = 0; + + if (_i5 % 2 === 1) { + align = "l"; + } else if (_i5 > 0 && isAligned) { + // "aligned" mode. + pregap = 1; // add one \quad + } + + cols[_i5] = { + type: "align", + align: align, + pregap: pregap, + postgap: 0 + }; + } + + res.colSeparationType = isAligned ? "align" : "alignat"; + return res; +}; // Arrays are part of LaTeX, defined in lttab.dtx so its documentation +// is part of the source2e.pdf file of LaTeX2e source documentation. +// {darray} is an {array} environment where cells are set in \displaystyle, +// as defined in nccmath.sty. + + +defineEnvironment({ + type: "array", + names: ["array", "darray"], + props: { + numArgs: 1 + }, + handler: function handler(context, args) { + // Since no types are specified above, the two possibilities are + // - The argument is wrapped in {} or [], in which case Parser's + // parseGroup() returns an "ordgroup" wrapping some symbol node. + // - The argument is a bare symbol node. + var symNode = checkSymbolNodeType(args[0]); + var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body; + var cols = colalign.map(function (nde) { + var node = assertSymbolNodeType(nde); + var ca = node.text; + + if ("lcr".indexOf(ca) !== -1) { + return { + type: "align", + align: ca + }; + } else if (ca === "|") { + return { + type: "separator", + separator: "|" + }; + } else if (ca === ":") { + return { + type: "separator", + separator: ":" + }; + } + + throw new src_ParseError("Unknown column alignment: " + ca, nde); + }); + var res = { + cols: cols, + hskipBeforeAndAfter: true, + // \@preamble in lttab.dtx + maxNumCols: cols.length + }; + return parseArray(context.parser, res, dCellStyle(context.envName)); + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); // The matrix environments of amsmath builds on the array environment +// of LaTeX, which is discussed above. +// The mathtools package adds starred versions of the same environments. +// These have an optional argument to choose left|center|right justification. + +defineEnvironment({ + type: "array", + names: ["matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix", "matrix*", "pmatrix*", "bmatrix*", "Bmatrix*", "vmatrix*", "Vmatrix*"], + props: { + numArgs: 0 + }, + handler: function handler(context) { + var delimiters = { + "matrix": null, + "pmatrix": ["(", ")"], + "bmatrix": ["[", "]"], + "Bmatrix": ["\\{", "\\}"], + "vmatrix": ["|", "|"], + "Vmatrix": ["\\Vert", "\\Vert"] + }[context.envName.replace("*", "")]; // \hskip -\arraycolsep in amsmath + + var colAlign = "c"; + var payload = { + hskipBeforeAndAfter: false, + cols: [{ + type: "align", + align: colAlign + }] + }; + + if (context.envName.charAt(context.envName.length - 1) === "*") { + // It's one of the mathtools starred functions. + // Parse the optional alignment argument. + var parser = context.parser; + parser.consumeSpaces(); + + if (parser.fetch().text === "[") { + parser.consume(); + parser.consumeSpaces(); + colAlign = parser.fetch().text; + + if ("lcr".indexOf(colAlign) === -1) { + throw new src_ParseError("Expected l or c or r", parser.nextToken); + } + + parser.consume(); + parser.consumeSpaces(); + parser.expect("]"); + parser.consume(); + payload.cols = [{ + type: "align", + align: colAlign + }]; + } + } + + var res = parseArray(context.parser, payload, dCellStyle(context.envName)); // Populate cols with the correct number of column alignment specs. + + var numCols = Math.max.apply(Math, [0].concat(res.body.map(function (row) { + return row.length; + }))); + res.cols = new Array(numCols).fill({ + type: "align", + align: colAlign + }); + return delimiters ? { + type: "leftright", + mode: context.mode, + body: [res], + left: delimiters[0], + right: delimiters[1], + rightColor: undefined // \right uninfluenced by \color in array + + } : res; + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); +defineEnvironment({ + type: "array", + names: ["smallmatrix"], + props: { + numArgs: 0 + }, + handler: function handler(context) { + var payload = { + arraystretch: 0.5 + }; + var res = parseArray(context.parser, payload, "script"); + res.colSeparationType = "small"; + return res; + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); +defineEnvironment({ + type: "array", + names: ["subarray"], + props: { + numArgs: 1 + }, + handler: function handler(context, args) { + // Parsing of {subarray} is similar to {array} + var symNode = checkSymbolNodeType(args[0]); + var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body; + var cols = colalign.map(function (nde) { + var node = assertSymbolNodeType(nde); + var ca = node.text; // {subarray} only recognizes "l" & "c" + + if ("lc".indexOf(ca) !== -1) { + return { + type: "align", + align: ca + }; + } + + throw new src_ParseError("Unknown column alignment: " + ca, nde); + }); + + if (cols.length > 1) { + throw new src_ParseError("{subarray} can contain only one column"); + } + + var res = { + cols: cols, + hskipBeforeAndAfter: false, + arraystretch: 0.5 + }; + res = parseArray(context.parser, res, "script"); + + if (res.body.length > 0 && res.body[0].length > 1) { + throw new src_ParseError("{subarray} can contain only one column"); + } + + return res; + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); // A cases environment (in amsmath.sty) is almost equivalent to +// \def\arraystretch{1.2}% +// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right. +// {dcases} is a {cases} environment where cells are set in \displaystyle, +// as defined in mathtools.sty. +// {rcases} is another mathtools environment. It's brace is on the right side. + +defineEnvironment({ + type: "array", + names: ["cases", "dcases", "rcases", "drcases"], + props: { + numArgs: 0 + }, + handler: function handler(context) { + var payload = { + arraystretch: 1.2, + cols: [{ + type: "align", + align: "l", + pregap: 0, + // TODO(kevinb) get the current style. + // For now we use the metrics for TEXT style which is what we were + // doing before. Before attempting to get the current style we + // should look at TeX's behavior especially for \over and matrices. + postgap: 1.0 + /* 1em quad */ + + }, { + type: "align", + align: "l", + pregap: 0, + postgap: 0 + }] + }; + var res = parseArray(context.parser, payload, dCellStyle(context.envName)); + return { + type: "leftright", + mode: context.mode, + body: [res], + left: context.envName.indexOf("r") > -1 ? "." : "\\{", + right: context.envName.indexOf("r") > -1 ? "\\}" : ".", + rightColor: undefined + }; + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); // In the align environment, one uses ampersands, &, to specify number of +// columns in each row, and to locate spacing between each column. +// align gets automatic numbering. align* and aligned do not. +// The alignedat environment can be used in math mode. +// Note that we assume \nomallineskiplimit to be zero, +// so that \strut@ is the same as \strut. + +defineEnvironment({ + type: "array", + names: ["align", "align*", "aligned", "split"], + props: { + numArgs: 0 + }, + handler: alignedHandler, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); // A gathered environment is like an array environment with one centered +// column, but where rows are considered lines so get \jot line spacing +// and contents are set in \displaystyle. + +defineEnvironment({ + type: "array", + names: ["gathered", "gather", "gather*"], + props: { + numArgs: 0 + }, + handler: function handler(context) { + if (utils.contains(["gather", "gather*"], context.envName)) { + validateAmsEnvironmentContext(context); + } + + var res = { + cols: [{ + type: "align", + align: "c" + }], + addJot: true, + colSeparationType: "gather", + addEqnNum: context.envName === "gather", + emptySingleRow: true, + leqno: context.parser.settings.leqno + }; + return parseArray(context.parser, res, "display"); + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); // alignat environment is like an align environment, but one must explicitly +// specify maximum number of columns in each row, and can adjust spacing between +// each columns. + +defineEnvironment({ + type: "array", + names: ["alignat", "alignat*", "alignedat"], + props: { + numArgs: 1 + }, + handler: alignedHandler, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); +defineEnvironment({ + type: "array", + names: ["equation", "equation*"], + props: { + numArgs: 0 + }, + handler: function handler(context) { + validateAmsEnvironmentContext(context); + var res = { + addEqnNum: context.envName === "equation", + emptySingleRow: true, + singleRow: true, + maxNumCols: 1, + leqno: context.parser.settings.leqno + }; + return parseArray(context.parser, res, "display"); + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); +defineEnvironment({ + type: "array", + names: ["CD"], + props: { + numArgs: 0 + }, + handler: function handler(context) { + validateAmsEnvironmentContext(context); + return parseCD(context.parser); + }, + htmlBuilder: array_htmlBuilder, + mathmlBuilder: array_mathmlBuilder +}); // Catch \hline outside array environment + +defineFunction({ + type: "text", + // Doesn't matter what this is. + names: ["\\hline", "\\hdashline"], + props: { + numArgs: 0, + allowedInText: true, + allowedInMath: true + }, + handler: function handler(context, args) { + throw new src_ParseError(context.funcName + " valid only within array environment"); + } +}); + +var environments = _environments; +/* harmony default export */ var src_environments = (environments); // All environment definitions should be imported below + + + + // Environment delimiters. HTML/MathML rendering is defined in the corresponding +// defineEnvironment definitions. + +defineFunction({ + type: "environment", + names: ["\\begin", "\\end"], + props: { + numArgs: 1, + argTypes: ["text"] + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var nameGroup = args[0]; + + if (nameGroup.type !== "ordgroup") { + throw new src_ParseError("Invalid environment name", nameGroup); + } + + var envName = ""; + + for (var i = 0; i < nameGroup.body.length; ++i) { + envName += assertNodeType(nameGroup.body[i], "textord").text; + } + + if (funcName === "\\begin") { + // begin...end is similar to left...right + if (!src_environments.hasOwnProperty(envName)) { + throw new src_ParseError("No such environment: " + envName, nameGroup); + } // Build the environment object. Arguments and other information will + // be made available to the begin and end methods using properties. + + + var env = src_environments[envName]; + + var _parser$parseArgument = parser.parseArguments("\\begin{" + envName + "}", env), + _args = _parser$parseArgument.args, + optArgs = _parser$parseArgument.optArgs; + + var context = { + mode: parser.mode, + envName: envName, + parser: parser + }; + var result = env.handler(context, _args, optArgs); + parser.expect("\\end", false); + var endNameToken = parser.nextToken; + var end = assertNodeType(parser.parseFunction(), "environment"); + + if (end.name !== envName) { + throw new src_ParseError("Mismatch: \\begin{" + envName + "} matched by \\end{" + end.name + "}", endNameToken); + } // $FlowFixMe, "environment" handler returns an environment ParseNode + + + return result; + } + + return { + type: "environment", + mode: parser.mode, + name: envName, + nameGroup: nameGroup + }; + } +}); + + + + + + +var mclass_makeSpan = buildCommon.makeSpan; + +function mclass_htmlBuilder(group, options) { + var elements = buildExpression(group.body, options, true); + return mclass_makeSpan([group.mclass], elements, options); +} + +function mclass_mathmlBuilder(group, options) { + var node; + var inner = buildMathML_buildExpression(group.body, options); + + if (group.mclass === "minner") { + return mathMLTree.newDocumentFragment(inner); + } else if (group.mclass === "mord") { + if (group.isCharacterBox) { + node = inner[0]; + node.type = "mi"; + } else { + node = new mathMLTree.MathNode("mi", inner); + } + } else { + if (group.isCharacterBox) { + node = inner[0]; + node.type = "mo"; + } else { + node = new mathMLTree.MathNode("mo", inner); + } // Set spacing based on what is the most likely adjacent atom type. + // See TeXbook p170. + + + if (group.mclass === "mbin") { + node.attributes.lspace = "0.22em"; // medium space + + node.attributes.rspace = "0.22em"; + } else if (group.mclass === "mpunct") { + node.attributes.lspace = "0em"; + node.attributes.rspace = "0.17em"; // thinspace + } else if (group.mclass === "mopen" || group.mclass === "mclose") { + node.attributes.lspace = "0em"; + node.attributes.rspace = "0em"; + } // MathML default space is 5/18 em, so needs no action. + // Ref: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo + + } + + return node; +} // Math class commands except \mathop + + +defineFunction({ + type: "mclass", + names: ["\\mathord", "\\mathbin", "\\mathrel", "\\mathopen", "\\mathclose", "\\mathpunct", "\\mathinner"], + props: { + numArgs: 1, + primitive: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var body = args[0]; + return { + type: "mclass", + mode: parser.mode, + mclass: "m" + funcName.substr(5), + // TODO(kevinb): don't prefix with 'm' + body: ordargument(body), + isCharacterBox: utils.isCharacterBox(body) + }; + }, + htmlBuilder: mclass_htmlBuilder, + mathmlBuilder: mclass_mathmlBuilder +}); +var binrelClass = function binrelClass(arg) { + // \binrel@ spacing varies with (bin|rel|ord) of the atom in the argument. + // (by rendering separately and with {}s before and after, and measuring + // the change in spacing). We'll do roughly the same by detecting the + // atom type directly. + var atom = arg.type === "ordgroup" && arg.body.length ? arg.body[0] : arg; + + if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) { + return "m" + atom.family; + } else { + return "mord"; + } +}; // \@binrel{x}{y} renders like y but as mbin/mrel/mord if x is mbin/mrel/mord. +// This is equivalent to \binrel@{x}\binrel@@{y} in AMSTeX. + +defineFunction({ + type: "mclass", + names: ["\\@binrel"], + props: { + numArgs: 2 + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + return { + type: "mclass", + mode: parser.mode, + mclass: binrelClass(args[0]), + body: ordargument(args[1]), + isCharacterBox: utils.isCharacterBox(args[1]) + }; + } +}); // Build a relation or stacked op by placing one symbol on top of another + +defineFunction({ + type: "mclass", + names: ["\\stackrel", "\\overset", "\\underset"], + props: { + numArgs: 2 + }, + handler: function handler(_ref3, args) { + var parser = _ref3.parser, + funcName = _ref3.funcName; + var baseArg = args[1]; + var shiftedArg = args[0]; + var mclass; + + if (funcName !== "\\stackrel") { + // LaTeX applies \binrel spacing to \overset and \underset. + mclass = binrelClass(baseArg); + } else { + mclass = "mrel"; // for \stackrel + } + + var baseOp = { + type: "op", + mode: baseArg.mode, + limits: true, + alwaysHandleSupSub: true, + parentIsSupSub: false, + symbol: false, + suppressBaseShift: funcName !== "\\stackrel", + body: ordargument(baseArg) + }; + var supsub = { + type: "supsub", + mode: shiftedArg.mode, + base: baseOp, + sup: funcName === "\\underset" ? null : shiftedArg, + sub: funcName === "\\underset" ? shiftedArg : null + }; + return { + type: "mclass", + mode: parser.mode, + mclass: mclass, + body: [supsub], + isCharacterBox: utils.isCharacterBox(supsub) + }; + }, + htmlBuilder: mclass_htmlBuilder, + mathmlBuilder: mclass_mathmlBuilder +}); +// TODO(kevinb): implement \\sl and \\sc + + + + + + +var font_htmlBuilder = function htmlBuilder(group, options) { + var font = group.font; + var newOptions = options.withFont(font); + return buildGroup(group.body, newOptions); +}; + +var font_mathmlBuilder = function mathmlBuilder(group, options) { + var font = group.font; + var newOptions = options.withFont(font); + return buildMathML_buildGroup(group.body, newOptions); +}; + +var fontAliases = { + "\\Bbb": "\\mathbb", + "\\bold": "\\mathbf", + "\\frak": "\\mathfrak", + "\\bm": "\\boldsymbol" +}; +defineFunction({ + type: "font", + names: [// styles, except \boldsymbol defined below + "\\mathrm", "\\mathit", "\\mathbf", "\\mathnormal", // families + "\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf", "\\mathtt", // aliases, except \bm defined below + "\\Bbb", "\\bold", "\\frak"], + props: { + numArgs: 1, + allowedInArgument: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var body = normalizeArgument(args[0]); + var func = funcName; + + if (func in fontAliases) { + func = fontAliases[func]; + } + + return { + type: "font", + mode: parser.mode, + font: func.slice(1), + body: body + }; + }, + htmlBuilder: font_htmlBuilder, + mathmlBuilder: font_mathmlBuilder +}); +defineFunction({ + type: "mclass", + names: ["\\boldsymbol", "\\bm"], + props: { + numArgs: 1 + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + var body = args[0]; + var isCharacterBox = utils.isCharacterBox(body); // amsbsy.sty's \boldsymbol uses \binrel spacing to inherit the + // argument's bin|rel|ord status + + return { + type: "mclass", + mode: parser.mode, + mclass: binrelClass(body), + body: [{ + type: "font", + mode: parser.mode, + font: "boldsymbol", + body: body + }], + isCharacterBox: isCharacterBox + }; + } +}); // Old font changing functions + +defineFunction({ + type: "font", + names: ["\\rm", "\\sf", "\\tt", "\\bf", "\\it", "\\cal"], + props: { + numArgs: 0, + allowedInText: true + }, + handler: function handler(_ref3, args) { + var parser = _ref3.parser, + funcName = _ref3.funcName, + breakOnTokenText = _ref3.breakOnTokenText; + var mode = parser.mode; + var body = parser.parseExpression(true, breakOnTokenText); + var style = "math" + funcName.slice(1); + return { + type: "font", + mode: mode, + font: style, + body: { + type: "ordgroup", + mode: parser.mode, + body: body + } + }; + }, + htmlBuilder: font_htmlBuilder, + mathmlBuilder: font_mathmlBuilder +}); + + + + + + + + + + + +var adjustStyle = function adjustStyle(size, originalStyle) { + // Figure out what style this fraction should be in based on the + // function used + var style = originalStyle; + + if (size === "display") { + // Get display style as a default. + // If incoming style is sub/sup, use style.text() to get correct size. + style = style.id >= src_Style.SCRIPT.id ? style.text() : src_Style.DISPLAY; + } else if (size === "text" && style.size === src_Style.DISPLAY.size) { + // We're in a \tfrac but incoming style is displaystyle, so: + style = src_Style.TEXT; + } else if (size === "script") { + style = src_Style.SCRIPT; + } else if (size === "scriptscript") { + style = src_Style.SCRIPTSCRIPT; + } + + return style; +}; + +var genfrac_htmlBuilder = function htmlBuilder(group, options) { + // Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e). + var style = adjustStyle(group.size, options.style); + var nstyle = style.fracNum(); + var dstyle = style.fracDen(); + var newOptions; + newOptions = options.havingStyle(nstyle); + var numerm = buildGroup(group.numer, newOptions, options); + + if (group.continued) { + // \cfrac inserts a \strut into the numerator. + // Get \strut dimensions from TeXbook page 353. + var hStrut = 8.5 / options.fontMetrics().ptPerEm; + var dStrut = 3.5 / options.fontMetrics().ptPerEm; + numerm.height = numerm.height < hStrut ? hStrut : numerm.height; + numerm.depth = numerm.depth < dStrut ? dStrut : numerm.depth; + } + + newOptions = options.havingStyle(dstyle); + var denomm = buildGroup(group.denom, newOptions, options); + var rule; + var ruleWidth; + var ruleSpacing; + + if (group.hasBarLine) { + if (group.barSize) { + ruleWidth = calculateSize(group.barSize, options); + rule = buildCommon.makeLineSpan("frac-line", options, ruleWidth); + } else { + rule = buildCommon.makeLineSpan("frac-line", options); + } + + ruleWidth = rule.height; + ruleSpacing = rule.height; + } else { + rule = null; + ruleWidth = 0; + ruleSpacing = options.fontMetrics().defaultRuleThickness; + } // Rule 15b + + + var numShift; + var clearance; + var denomShift; + + if (style.size === src_Style.DISPLAY.size || group.size === "display") { + numShift = options.fontMetrics().num1; + + if (ruleWidth > 0) { + clearance = 3 * ruleSpacing; + } else { + clearance = 7 * ruleSpacing; + } + + denomShift = options.fontMetrics().denom1; + } else { + if (ruleWidth > 0) { + numShift = options.fontMetrics().num2; + clearance = ruleSpacing; + } else { + numShift = options.fontMetrics().num3; + clearance = 3 * ruleSpacing; + } + + denomShift = options.fontMetrics().denom2; + } + + var frac; + + if (!rule) { + // Rule 15c + var candidateClearance = numShift - numerm.depth - (denomm.height - denomShift); + + if (candidateClearance < clearance) { + numShift += 0.5 * (clearance - candidateClearance); + denomShift += 0.5 * (clearance - candidateClearance); + } + + frac = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: denomm, + shift: denomShift + }, { + type: "elem", + elem: numerm, + shift: -numShift + }] + }, options); + } else { + // Rule 15d + var axisHeight = options.fontMetrics().axisHeight; + + if (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth) < clearance) { + numShift += clearance - (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth)); + } + + if (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift) < clearance) { + denomShift += clearance - (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift)); + } + + var midShift = -(axisHeight - 0.5 * ruleWidth); + frac = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: denomm, + shift: denomShift + }, { + type: "elem", + elem: rule, + shift: midShift + }, { + type: "elem", + elem: numerm, + shift: -numShift + }] + }, options); + } // Since we manually change the style sometimes (with \dfrac or \tfrac), + // account for the possible size change here. + + + newOptions = options.havingStyle(style); + frac.height *= newOptions.sizeMultiplier / options.sizeMultiplier; + frac.depth *= newOptions.sizeMultiplier / options.sizeMultiplier; // Rule 15e + + var delimSize; + + if (style.size === src_Style.DISPLAY.size) { + delimSize = options.fontMetrics().delim1; + } else if (style.size === src_Style.SCRIPTSCRIPT.size) { + delimSize = options.havingStyle(src_Style.SCRIPT).fontMetrics().delim2; + } else { + delimSize = options.fontMetrics().delim2; + } + + var leftDelim; + var rightDelim; + + if (group.leftDelim == null) { + leftDelim = makeNullDelimiter(options, ["mopen"]); + } else { + leftDelim = delimiter.customSizedDelim(group.leftDelim, delimSize, true, options.havingStyle(style), group.mode, ["mopen"]); + } + + if (group.continued) { + rightDelim = buildCommon.makeSpan([]); // zero width for \cfrac + } else if (group.rightDelim == null) { + rightDelim = makeNullDelimiter(options, ["mclose"]); + } else { + rightDelim = delimiter.customSizedDelim(group.rightDelim, delimSize, true, options.havingStyle(style), group.mode, ["mclose"]); + } + + return buildCommon.makeSpan(["mord"].concat(newOptions.sizingClasses(options)), [leftDelim, buildCommon.makeSpan(["mfrac"], [frac]), rightDelim], options); +}; + +var genfrac_mathmlBuilder = function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mfrac", [buildMathML_buildGroup(group.numer, options), buildMathML_buildGroup(group.denom, options)]); + + if (!group.hasBarLine) { + node.setAttribute("linethickness", "0px"); + } else if (group.barSize) { + var ruleWidth = calculateSize(group.barSize, options); + node.setAttribute("linethickness", makeEm(ruleWidth)); + } + + var style = adjustStyle(group.size, options.style); + + if (style.size !== options.style.size) { + node = new mathMLTree.MathNode("mstyle", [node]); + var isDisplay = style.size === src_Style.DISPLAY.size ? "true" : "false"; + node.setAttribute("displaystyle", isDisplay); + node.setAttribute("scriptlevel", "0"); + } + + if (group.leftDelim != null || group.rightDelim != null) { + var withDelims = []; + + if (group.leftDelim != null) { + var leftOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.leftDelim.replace("\\", ""))]); + leftOp.setAttribute("fence", "true"); + withDelims.push(leftOp); + } + + withDelims.push(node); + + if (group.rightDelim != null) { + var rightOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.rightDelim.replace("\\", ""))]); + rightOp.setAttribute("fence", "true"); + withDelims.push(rightOp); + } + + return makeRow(withDelims); + } + + return node; +}; + +defineFunction({ + type: "genfrac", + names: ["\\dfrac", "\\frac", "\\tfrac", "\\dbinom", "\\binom", "\\tbinom", "\\\\atopfrac", // can’t be entered directly + "\\\\bracefrac", "\\\\brackfrac" // ditto + ], + props: { + numArgs: 2, + allowedInArgument: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var numer = args[0]; + var denom = args[1]; + var hasBarLine; + var leftDelim = null; + var rightDelim = null; + var size = "auto"; + + switch (funcName) { + case "\\dfrac": + case "\\frac": + case "\\tfrac": + hasBarLine = true; + break; + + case "\\\\atopfrac": + hasBarLine = false; + break; + + case "\\dbinom": + case "\\binom": + case "\\tbinom": + hasBarLine = false; + leftDelim = "("; + rightDelim = ")"; + break; + + case "\\\\bracefrac": + hasBarLine = false; + leftDelim = "\\{"; + rightDelim = "\\}"; + break; + + case "\\\\brackfrac": + hasBarLine = false; + leftDelim = "["; + rightDelim = "]"; + break; + + default: + throw new Error("Unrecognized genfrac command"); + } + + switch (funcName) { + case "\\dfrac": + case "\\dbinom": + size = "display"; + break; + + case "\\tfrac": + case "\\tbinom": + size = "text"; + break; + } + + return { + type: "genfrac", + mode: parser.mode, + continued: false, + numer: numer, + denom: denom, + hasBarLine: hasBarLine, + leftDelim: leftDelim, + rightDelim: rightDelim, + size: size, + barSize: null + }; + }, + htmlBuilder: genfrac_htmlBuilder, + mathmlBuilder: genfrac_mathmlBuilder +}); +defineFunction({ + type: "genfrac", + names: ["\\cfrac"], + props: { + numArgs: 2 + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + _ref2.funcName; + var numer = args[0]; + var denom = args[1]; + return { + type: "genfrac", + mode: parser.mode, + continued: true, + numer: numer, + denom: denom, + hasBarLine: true, + leftDelim: null, + rightDelim: null, + size: "display", + barSize: null + }; + } +}); // Infix generalized fractions -- these are not rendered directly, but replaced +// immediately by one of the variants above. + +defineFunction({ + type: "infix", + names: ["\\over", "\\choose", "\\atop", "\\brace", "\\brack"], + props: { + numArgs: 0, + infix: true + }, + handler: function handler(_ref3) { + var parser = _ref3.parser, + funcName = _ref3.funcName, + token = _ref3.token; + var replaceWith; + + switch (funcName) { + case "\\over": + replaceWith = "\\frac"; + break; + + case "\\choose": + replaceWith = "\\binom"; + break; + + case "\\atop": + replaceWith = "\\\\atopfrac"; + break; + + case "\\brace": + replaceWith = "\\\\bracefrac"; + break; + + case "\\brack": + replaceWith = "\\\\brackfrac"; + break; + + default: + throw new Error("Unrecognized infix genfrac command"); + } + + return { + type: "infix", + mode: parser.mode, + replaceWith: replaceWith, + token: token + }; + } +}); +var stylArray = ["display", "text", "script", "scriptscript"]; + +var delimFromValue = function delimFromValue(delimString) { + var delim = null; + + if (delimString.length > 0) { + delim = delimString; + delim = delim === "." ? null : delim; + } + + return delim; +}; + +defineFunction({ + type: "genfrac", + names: ["\\genfrac"], + props: { + numArgs: 6, + allowedInArgument: true, + argTypes: ["math", "math", "size", "text", "math", "math"] + }, + handler: function handler(_ref4, args) { + var parser = _ref4.parser; + var numer = args[4]; + var denom = args[5]; // Look into the parse nodes to get the desired delimiters. + + var leftNode = normalizeArgument(args[0]); + var leftDelim = leftNode.type === "atom" && leftNode.family === "open" ? delimFromValue(leftNode.text) : null; + var rightNode = normalizeArgument(args[1]); + var rightDelim = rightNode.type === "atom" && rightNode.family === "close" ? delimFromValue(rightNode.text) : null; + var barNode = assertNodeType(args[2], "size"); + var hasBarLine; + var barSize = null; + + if (barNode.isBlank) { + // \genfrac acts differently than \above. + // \genfrac treats an empty size group as a signal to use a + // standard bar size. \above would see size = 0 and omit the bar. + hasBarLine = true; + } else { + barSize = barNode.value; + hasBarLine = barSize.number > 0; + } // Find out if we want displaystyle, textstyle, etc. + + + var size = "auto"; + var styl = args[3]; + + if (styl.type === "ordgroup") { + if (styl.body.length > 0) { + var textOrd = assertNodeType(styl.body[0], "textord"); + size = stylArray[Number(textOrd.text)]; + } + } else { + styl = assertNodeType(styl, "textord"); + size = stylArray[Number(styl.text)]; + } + + return { + type: "genfrac", + mode: parser.mode, + numer: numer, + denom: denom, + continued: false, + hasBarLine: hasBarLine, + barSize: barSize, + leftDelim: leftDelim, + rightDelim: rightDelim, + size: size + }; + }, + htmlBuilder: genfrac_htmlBuilder, + mathmlBuilder: genfrac_mathmlBuilder +}); // \above is an infix fraction that also defines a fraction bar size. + +defineFunction({ + type: "infix", + names: ["\\above"], + props: { + numArgs: 1, + argTypes: ["size"], + infix: true + }, + handler: function handler(_ref5, args) { + var parser = _ref5.parser; + _ref5.funcName; + var token = _ref5.token; + return { + type: "infix", + mode: parser.mode, + replaceWith: "\\\\abovefrac", + size: assertNodeType(args[0], "size").value, + token: token + }; + } +}); +defineFunction({ + type: "genfrac", + names: ["\\\\abovefrac"], + props: { + numArgs: 3, + argTypes: ["math", "size", "math"] + }, + handler: function handler(_ref6, args) { + var parser = _ref6.parser; + _ref6.funcName; + var numer = args[0]; + var barSize = assert(assertNodeType(args[1], "infix").size); + var denom = args[2]; + var hasBarLine = barSize.number > 0; + return { + type: "genfrac", + mode: parser.mode, + numer: numer, + denom: denom, + continued: false, + hasBarLine: hasBarLine, + barSize: barSize, + leftDelim: null, + rightDelim: null, + size: "auto" + }; + }, + htmlBuilder: genfrac_htmlBuilder, + mathmlBuilder: genfrac_mathmlBuilder +}); + + + + + + + + +// NOTE: Unlike most `htmlBuilder`s, this one handles not only "horizBrace", but +// also "supsub" since an over/underbrace can affect super/subscripting. +var horizBrace_htmlBuilder = function htmlBuilder(grp, options) { + var style = options.style; // Pull out the `ParseNode<"horizBrace">` if `grp` is a "supsub" node. + + var supSubGroup; + var group; + + if (grp.type === "supsub") { + // Ref: LaTeX source2e: }}}}\limits} + // i.e. LaTeX treats the brace similar to an op and passes it + // with \limits, so we need to assign supsub style. + supSubGroup = grp.sup ? buildGroup(grp.sup, options.havingStyle(style.sup()), options) : buildGroup(grp.sub, options.havingStyle(style.sub()), options); + group = assertNodeType(grp.base, "horizBrace"); + } else { + group = assertNodeType(grp, "horizBrace"); + } // Build the base group + + + var body = buildGroup(group.base, options.havingBaseStyle(src_Style.DISPLAY)); // Create the stretchy element + + var braceBody = stretchy.svgSpan(group, options); // Generate the vlist, with the appropriate kerns ┏━━━━━━━━┓ + // This first vlist contains the content and the brace: equation + + var vlist; + + if (group.isOver) { + vlist = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: body + }, { + type: "kern", + size: 0.1 + }, { + type: "elem", + elem: braceBody + }] + }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList. + + vlist.children[0].children[0].children[1].classes.push("svg-align"); + } else { + vlist = buildCommon.makeVList({ + positionType: "bottom", + positionData: body.depth + 0.1 + braceBody.height, + children: [{ + type: "elem", + elem: braceBody + }, { + type: "kern", + size: 0.1 + }, { + type: "elem", + elem: body + }] + }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList. + + vlist.children[0].children[0].children[0].classes.push("svg-align"); + } + + if (supSubGroup) { + // To write the supsub, wrap the first vlist in another vlist: + // They can't all go in the same vlist, because the note might be + // wider than the equation. We want the equation to control the + // brace width. + // note long note long note + // ┏━━━━━━━━┓ or ┏━━━┓ not ┏━━━━━━━━━┓ + // equation eqn eqn + var vSpan = buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options); + + if (group.isOver) { + vlist = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: vSpan + }, { + type: "kern", + size: 0.2 + }, { + type: "elem", + elem: supSubGroup + }] + }, options); + } else { + vlist = buildCommon.makeVList({ + positionType: "bottom", + positionData: vSpan.depth + 0.2 + supSubGroup.height + supSubGroup.depth, + children: [{ + type: "elem", + elem: supSubGroup + }, { + type: "kern", + size: 0.2 + }, { + type: "elem", + elem: vSpan + }] + }, options); + } + } + + return buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options); +}; + +var horizBrace_mathmlBuilder = function mathmlBuilder(group, options) { + var accentNode = stretchy.mathMLnode(group.label); + return new mathMLTree.MathNode(group.isOver ? "mover" : "munder", [buildMathML_buildGroup(group.base, options), accentNode]); +}; // Horizontal stretchy braces + + +defineFunction({ + type: "horizBrace", + names: ["\\overbrace", "\\underbrace"], + props: { + numArgs: 1 + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + return { + type: "horizBrace", + mode: parser.mode, + label: funcName, + isOver: /^\\over/.test(funcName), + base: args[0] + }; + }, + htmlBuilder: horizBrace_htmlBuilder, + mathmlBuilder: horizBrace_mathmlBuilder +}); + + + + + + +defineFunction({ + type: "href", + names: ["\\href"], + props: { + numArgs: 2, + argTypes: ["url", "original"], + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + var body = args[1]; + var href = assertNodeType(args[0], "url").url; + + if (!parser.settings.isTrusted({ + command: "\\href", + url: href + })) { + return parser.formatUnsupportedCmd("\\href"); + } + + return { + type: "href", + mode: parser.mode, + href: href, + body: ordargument(body) + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var elements = buildExpression(group.body, options, false); + return buildCommon.makeAnchor(group.href, [], elements, options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var math = buildExpressionRow(group.body, options); + + if (!(math instanceof MathNode)) { + math = new MathNode("mrow", [math]); + } + + math.setAttribute("href", group.href); + return math; + } +}); +defineFunction({ + type: "href", + names: ["\\url"], + props: { + numArgs: 1, + argTypes: ["url"], + allowedInText: true + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + var href = assertNodeType(args[0], "url").url; + + if (!parser.settings.isTrusted({ + command: "\\url", + url: href + })) { + return parser.formatUnsupportedCmd("\\url"); + } + + var chars = []; + + for (var i = 0; i < href.length; i++) { + var c = href[i]; + + if (c === "~") { + c = "\\textasciitilde"; + } + + chars.push({ + type: "textord", + mode: "text", + text: c + }); + } + + var body = { + type: "text", + mode: parser.mode, + font: "\\texttt", + body: chars + }; + return { + type: "href", + mode: parser.mode, + href: href, + body: ordargument(body) + }; + } +}); + + + + + // \hbox is provided for compatibility with LaTeX \vcenter. +// In LaTeX, \vcenter can act only on a box, as in +// \vcenter{\hbox{$\frac{a+b}{\dfrac{c}{d}}$}} +// This function by itself doesn't do anything but prevent a soft line break. + +defineFunction({ + type: "hbox", + names: ["\\hbox"], + props: { + numArgs: 1, + argTypes: ["text"], + allowedInText: true, + primitive: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + return { + type: "hbox", + mode: parser.mode, + body: ordargument(args[0]) + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var elements = buildExpression(group.body, options, false); + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + return new mathMLTree.MathNode("mrow", buildMathML_buildExpression(group.body, options)); + } +}); + + + + + + +defineFunction({ + type: "html", + names: ["\\htmlClass", "\\htmlId", "\\htmlStyle", "\\htmlData"], + props: { + numArgs: 2, + argTypes: ["raw", "original"], + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + _ref.token; + var value = assertNodeType(args[0], "raw").string; + var body = args[1]; + + if (parser.settings.strict) { + parser.settings.reportNonstrict("htmlExtension", "HTML extension is disabled on strict mode"); + } + + var trustContext; + var attributes = {}; + + switch (funcName) { + case "\\htmlClass": + attributes.class = value; + trustContext = { + command: "\\htmlClass", + class: value + }; + break; + + case "\\htmlId": + attributes.id = value; + trustContext = { + command: "\\htmlId", + id: value + }; + break; + + case "\\htmlStyle": + attributes.style = value; + trustContext = { + command: "\\htmlStyle", + style: value + }; + break; + + case "\\htmlData": + { + var data = value.split(","); + + for (var i = 0; i < data.length; i++) { + var keyVal = data[i].split("="); + + if (keyVal.length !== 2) { + throw new src_ParseError("Error parsing key-value for \\htmlData"); + } + + attributes["data-" + keyVal[0].trim()] = keyVal[1].trim(); + } + + trustContext = { + command: "\\htmlData", + attributes: attributes + }; + break; + } + + default: + throw new Error("Unrecognized html command"); + } + + if (!parser.settings.isTrusted(trustContext)) { + return parser.formatUnsupportedCmd(funcName); + } + + return { + type: "html", + mode: parser.mode, + attributes: attributes, + body: ordargument(body) + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var elements = buildExpression(group.body, options, false); + var classes = ["enclosing"]; + + if (group.attributes.class) { + classes.push.apply(classes, group.attributes.class.trim().split(/\s+/)); + } + + var span = buildCommon.makeSpan(classes, elements, options); + + for (var attr in group.attributes) { + if (attr !== "class" && group.attributes.hasOwnProperty(attr)) { + span.setAttribute(attr, group.attributes[attr]); + } + } + + return span; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + return buildExpressionRow(group.body, options); + } +}); + + + + +defineFunction({ + type: "htmlmathml", + names: ["\\html@mathml"], + props: { + numArgs: 2, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + return { + type: "htmlmathml", + mode: parser.mode, + html: ordargument(args[0]), + mathml: ordargument(args[1]) + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var elements = buildExpression(group.html, options, false); + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + return buildExpressionRow(group.mathml, options); + } +}); + + + + + + + +var sizeData = function sizeData(str) { + if (/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(str)) { + // str is a number with no unit specified. + // default unit is bp, per graphix package. + return { + number: +str, + unit: "bp" + }; + } else { + var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(str); + + if (!match) { + throw new src_ParseError("Invalid size: '" + str + "' in \\includegraphics"); + } + + var data = { + number: +(match[1] + match[2]), + // sign + magnitude, cast to number + unit: match[3] + }; + + if (!validUnit(data)) { + throw new src_ParseError("Invalid unit: '" + data.unit + "' in \\includegraphics."); + } + + return data; + } +}; + +defineFunction({ + type: "includegraphics", + names: ["\\includegraphics"], + props: { + numArgs: 1, + numOptionalArgs: 1, + argTypes: ["raw", "url"], + allowedInText: false + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser; + var width = { + number: 0, + unit: "em" + }; + var height = { + number: 0.9, + unit: "em" + }; // sorta character sized. + + var totalheight = { + number: 0, + unit: "em" + }; + var alt = ""; + + if (optArgs[0]) { + var attributeStr = assertNodeType(optArgs[0], "raw").string; // Parser.js does not parse key/value pairs. We get a string. + + var attributes = attributeStr.split(","); + + for (var i = 0; i < attributes.length; i++) { + var keyVal = attributes[i].split("="); + + if (keyVal.length === 2) { + var str = keyVal[1].trim(); + + switch (keyVal[0].trim()) { + case "alt": + alt = str; + break; + + case "width": + width = sizeData(str); + break; + + case "height": + height = sizeData(str); + break; + + case "totalheight": + totalheight = sizeData(str); + break; + + default: + throw new src_ParseError("Invalid key: '" + keyVal[0] + "' in \\includegraphics."); + } + } + } + } + + var src = assertNodeType(args[0], "url").url; + + if (alt === "") { + // No alt given. Use the file name. Strip away the path. + alt = src; + alt = alt.replace(/^.*[\\/]/, ''); + alt = alt.substring(0, alt.lastIndexOf('.')); + } + + if (!parser.settings.isTrusted({ + command: "\\includegraphics", + url: src + })) { + return parser.formatUnsupportedCmd("\\includegraphics"); + } + + return { + type: "includegraphics", + mode: parser.mode, + alt: alt, + width: width, + height: height, + totalheight: totalheight, + src: src + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var height = calculateSize(group.height, options); + var depth = 0; + + if (group.totalheight.number > 0) { + depth = calculateSize(group.totalheight, options) - height; + } + + var width = 0; + + if (group.width.number > 0) { + width = calculateSize(group.width, options); + } + + var style = { + height: makeEm(height + depth) + }; + + if (width > 0) { + style.width = makeEm(width); + } + + if (depth > 0) { + style.verticalAlign = makeEm(-depth); + } + + var node = new Img(group.src, group.alt, style); + node.height = height; + node.depth = depth; + return node; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mglyph", []); + node.setAttribute("alt", group.alt); + var height = calculateSize(group.height, options); + var depth = 0; + + if (group.totalheight.number > 0) { + depth = calculateSize(group.totalheight, options) - height; + node.setAttribute("valign", makeEm(-depth)); + } + + node.setAttribute("height", makeEm(height + depth)); + + if (group.width.number > 0) { + var width = calculateSize(group.width, options); + node.setAttribute("width", makeEm(width)); + } + + node.setAttribute("src", group.src); + return node; + } +}); +// Horizontal spacing commands + + + + + // TODO: \hskip and \mskip should support plus and minus in lengths + +defineFunction({ + type: "kern", + names: ["\\kern", "\\mkern", "\\hskip", "\\mskip"], + props: { + numArgs: 1, + argTypes: ["size"], + primitive: true, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var size = assertNodeType(args[0], "size"); + + if (parser.settings.strict) { + var mathFunction = funcName[1] === 'm'; // \mkern, \mskip + + var muUnit = size.value.unit === 'mu'; + + if (mathFunction) { + if (!muUnit) { + parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " supports only mu units, " + ("not " + size.value.unit + " units")); + } + + if (parser.mode !== "math") { + parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " works only in math mode"); + } + } else { + // !mathFunction + if (muUnit) { + parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " doesn't support mu units"); + } + } + } + + return { + type: "kern", + mode: parser.mode, + dimension: size.value + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + return buildCommon.makeGlue(group.dimension, options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var dimension = calculateSize(group.dimension, options); + return new mathMLTree.SpaceNode(dimension); + } +}); +// Horizontal overlap functions + + + + + + +defineFunction({ + type: "lap", + names: ["\\mathllap", "\\mathrlap", "\\mathclap"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var body = args[0]; + return { + type: "lap", + mode: parser.mode, + alignment: funcName.slice(5), + body: body + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // mathllap, mathrlap, mathclap + var inner; + + if (group.alignment === "clap") { + // ref: https://www.math.lsu.edu/~aperlis/publications/mathclap/ + inner = buildCommon.makeSpan([], [buildGroup(group.body, options)]); // wrap, since CSS will center a .clap > .inner > span + + inner = buildCommon.makeSpan(["inner"], [inner], options); + } else { + inner = buildCommon.makeSpan(["inner"], [buildGroup(group.body, options)]); + } + + var fix = buildCommon.makeSpan(["fix"], []); + var node = buildCommon.makeSpan([group.alignment], [inner, fix], options); // At this point, we have correctly set horizontal alignment of the + // two items involved in the lap. + // Next, use a strut to set the height of the HTML bounding box. + // Otherwise, a tall argument may be misplaced. + // This code resolved issue #1153 + + var strut = buildCommon.makeSpan(["strut"]); + strut.style.height = makeEm(node.height + node.depth); + + if (node.depth) { + strut.style.verticalAlign = makeEm(-node.depth); + } + + node.children.unshift(strut); // Next, prevent vertical misplacement when next to something tall. + // This code resolves issue #1234 + + node = buildCommon.makeSpan(["thinbox"], [node], options); + return buildCommon.makeSpan(["mord", "vbox"], [node], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + // mathllap, mathrlap, mathclap + var node = new mathMLTree.MathNode("mpadded", [buildMathML_buildGroup(group.body, options)]); + + if (group.alignment !== "rlap") { + var offset = group.alignment === "llap" ? "-1" : "-0.5"; + node.setAttribute("lspace", offset + "width"); + } + + node.setAttribute("width", "0px"); + return node; + } +}); + + // Switching from text mode back to math mode + +defineFunction({ + type: "styling", + names: ["\\(", "$"], + props: { + numArgs: 0, + allowedInText: true, + allowedInMath: false + }, + handler: function handler(_ref, args) { + var funcName = _ref.funcName, + parser = _ref.parser; + var outerMode = parser.mode; + parser.switchMode("math"); + var close = funcName === "\\(" ? "\\)" : "$"; + var body = parser.parseExpression(false, close); + parser.expect(close); + parser.switchMode(outerMode); + return { + type: "styling", + mode: parser.mode, + style: "text", + body: body + }; + } +}); // Check for extra closing math delimiters + +defineFunction({ + type: "text", + // Doesn't matter what this is. + names: ["\\)", "\\]"], + props: { + numArgs: 0, + allowedInText: true, + allowedInMath: false + }, + handler: function handler(context, args) { + throw new src_ParseError("Mismatched " + context.funcName); + } +}); + + + + + + +var chooseMathStyle = function chooseMathStyle(group, options) { + switch (options.style.size) { + case src_Style.DISPLAY.size: + return group.display; + + case src_Style.TEXT.size: + return group.text; + + case src_Style.SCRIPT.size: + return group.script; + + case src_Style.SCRIPTSCRIPT.size: + return group.scriptscript; + + default: + return group.text; + } +}; + +defineFunction({ + type: "mathchoice", + names: ["\\mathchoice"], + props: { + numArgs: 4, + primitive: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + return { + type: "mathchoice", + mode: parser.mode, + display: ordargument(args[0]), + text: ordargument(args[1]), + script: ordargument(args[2]), + scriptscript: ordargument(args[3]) + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var body = chooseMathStyle(group, options); + var elements = buildExpression(body, options, false); + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var body = chooseMathStyle(group, options); + return buildExpressionRow(body, options); + } +}); + + + + // For an operator with limits, assemble the base, sup, and sub into a span. + +var assembleSupSub = function assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift) { + base = buildCommon.makeSpan([], [base]); + var subIsSingleCharacter = subGroup && utils.isCharacterBox(subGroup); + var sub; + var sup; // We manually have to handle the superscripts and subscripts. This, + // aside from the kern calculations, is copied from supsub. + + if (supGroup) { + var elem = buildGroup(supGroup, options.havingStyle(style.sup()), options); + sup = { + elem: elem, + kern: Math.max(options.fontMetrics().bigOpSpacing1, options.fontMetrics().bigOpSpacing3 - elem.depth) + }; + } + + if (subGroup) { + var _elem = buildGroup(subGroup, options.havingStyle(style.sub()), options); + + sub = { + elem: _elem, + kern: Math.max(options.fontMetrics().bigOpSpacing2, options.fontMetrics().bigOpSpacing4 - _elem.height) + }; + } // Build the final group as a vlist of the possible subscript, base, + // and possible superscript. + + + var finalGroup; + + if (sup && sub) { + var bottom = options.fontMetrics().bigOpSpacing5 + sub.elem.height + sub.elem.depth + sub.kern + base.depth + baseShift; + finalGroup = buildCommon.makeVList({ + positionType: "bottom", + positionData: bottom, + children: [{ + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }, { + type: "elem", + elem: sub.elem, + marginLeft: makeEm(-slant) + }, { + type: "kern", + size: sub.kern + }, { + type: "elem", + elem: base + }, { + type: "kern", + size: sup.kern + }, { + type: "elem", + elem: sup.elem, + marginLeft: makeEm(slant) + }, { + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }] + }, options); + } else if (sub) { + var top = base.height - baseShift; // Shift the limits by the slant of the symbol. Note + // that we are supposed to shift the limits by 1/2 of the slant, + // but since we are centering the limits adding a full slant of + // margin will shift by 1/2 that. + + finalGroup = buildCommon.makeVList({ + positionType: "top", + positionData: top, + children: [{ + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }, { + type: "elem", + elem: sub.elem, + marginLeft: makeEm(-slant) + }, { + type: "kern", + size: sub.kern + }, { + type: "elem", + elem: base + }] + }, options); + } else if (sup) { + var _bottom = base.depth + baseShift; + + finalGroup = buildCommon.makeVList({ + positionType: "bottom", + positionData: _bottom, + children: [{ + type: "elem", + elem: base + }, { + type: "kern", + size: sup.kern + }, { + type: "elem", + elem: sup.elem, + marginLeft: makeEm(slant) + }, { + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }] + }, options); + } else { + // This case probably shouldn't occur (this would mean the + // supsub was sending us a group with no superscript or + // subscript) but be safe. + return base; + } + + var parts = [finalGroup]; + + if (sub && slant !== 0 && !subIsSingleCharacter) { + // A negative margin-left was applied to the lower limit. + // Avoid an overlap by placing a spacer on the left on the group. + var spacer = buildCommon.makeSpan(["mspace"], [], options); + spacer.style.marginRight = makeEm(slant); + parts.unshift(spacer); + } + + return buildCommon.makeSpan(["mop", "op-limits"], parts, options); +}; +// Limits, symbols + + + + + + + + + + + +// Most operators have a large successor symbol, but these don't. +var noSuccessor = ["\\smallint"]; // NOTE: Unlike most `htmlBuilder`s, this one handles not only "op", but also +// "supsub" since some of them (like \int) can affect super/subscripting. + +var op_htmlBuilder = function htmlBuilder(grp, options) { + // Operators are handled in the TeXbook pg. 443-444, rule 13(a). + var supGroup; + var subGroup; + var hasLimits = false; + var group; + + if (grp.type === "supsub") { + // If we have limits, supsub will pass us its group to handle. Pull + // out the superscript and subscript and set the group to the op in + // its base. + supGroup = grp.sup; + subGroup = grp.sub; + group = assertNodeType(grp.base, "op"); + hasLimits = true; + } else { + group = assertNodeType(grp, "op"); + } + + var style = options.style; + var large = false; + + if (style.size === src_Style.DISPLAY.size && group.symbol && !utils.contains(noSuccessor, group.name)) { + // Most symbol operators get larger in displaystyle (rule 13) + large = true; + } + + var base; + + if (group.symbol) { + // If this is a symbol, create the symbol. + var fontName = large ? "Size2-Regular" : "Size1-Regular"; + var stash = ""; + + if (group.name === "\\oiint" || group.name === "\\oiiint") { + // No font glyphs yet, so use a glyph w/o the oval. + // TODO: When font glyphs are available, delete this code. + stash = group.name.substr(1); + group.name = stash === "oiint" ? "\\iint" : "\\iiint"; + } + + base = buildCommon.makeSymbol(group.name, fontName, "math", options, ["mop", "op-symbol", large ? "large-op" : "small-op"]); + + if (stash.length > 0) { + // We're in \oiint or \oiiint. Overlay the oval. + // TODO: When font glyphs are available, delete this code. + var italic = base.italic; + var oval = buildCommon.staticSvg(stash + "Size" + (large ? "2" : "1"), options); + base = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: base, + shift: 0 + }, { + type: "elem", + elem: oval, + shift: large ? 0.08 : 0 + }] + }, options); + group.name = "\\" + stash; + base.classes.unshift("mop"); // $FlowFixMe + + base.italic = italic; + } + } else if (group.body) { + // If this is a list, compose that list. + var inner = buildExpression(group.body, options, true); + + if (inner.length === 1 && inner[0] instanceof SymbolNode) { + base = inner[0]; + base.classes[0] = "mop"; // replace old mclass + } else { + base = buildCommon.makeSpan(["mop"], inner, options); + } + } else { + // Otherwise, this is a text operator. Build the text from the + // operator's name. + var output = []; + + for (var i = 1; i < group.name.length; i++) { + output.push(buildCommon.mathsym(group.name[i], group.mode, options)); + } + + base = buildCommon.makeSpan(["mop"], output, options); + } // If content of op is a single symbol, shift it vertically. + + + var baseShift = 0; + var slant = 0; + + if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) { + // We suppress the shift of the base of \overset and \underset. Otherwise, + // shift the symbol so its center lies on the axis (rule 13). It + // appears that our fonts have the centers of the symbols already + // almost on the axis, so these numbers are very small. Note we + // don't actually apply this here, but instead it is used either in + // the vlist creation or separately when there are no limits. + baseShift = (base.height - base.depth) / 2 - options.fontMetrics().axisHeight; // The slant of the symbol is just its italic correction. + // $FlowFixMe + + slant = base.italic; + } + + if (hasLimits) { + return assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift); + } else { + if (baseShift) { + base.style.position = "relative"; + base.style.top = makeEm(baseShift); + } + + return base; + } +}; + +var op_mathmlBuilder = function mathmlBuilder(group, options) { + var node; + + if (group.symbol) { + // This is a symbol. Just add the symbol. + node = new MathNode("mo", [makeText(group.name, group.mode)]); + + if (utils.contains(noSuccessor, group.name)) { + node.setAttribute("largeop", "false"); + } + } else if (group.body) { + // This is an operator with children. Add them. + node = new MathNode("mo", buildMathML_buildExpression(group.body, options)); + } else { + // This is a text operator. Add all of the characters from the + // operator's name. + node = new MathNode("mi", [new TextNode(group.name.slice(1))]); // Append an . + // ref: https://www.w3.org/TR/REC-MathML/chap3_2.html#sec3.2.4 + + var operator = new MathNode("mo", [makeText("\u2061", "text")]); + + if (group.parentIsSupSub) { + node = new MathNode("mrow", [node, operator]); + } else { + node = newDocumentFragment([node, operator]); + } + } + + return node; +}; + +var singleCharBigOps = { + "\u220F": "\\prod", + "\u2210": "\\coprod", + "\u2211": "\\sum", + "\u22C0": "\\bigwedge", + "\u22C1": "\\bigvee", + "\u22C2": "\\bigcap", + "\u22C3": "\\bigcup", + "\u2A00": "\\bigodot", + "\u2A01": "\\bigoplus", + "\u2A02": "\\bigotimes", + "\u2A04": "\\biguplus", + "\u2A06": "\\bigsqcup" +}; +defineFunction({ + type: "op", + names: ["\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap", "\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes", "\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint", "\u220F", "\u2210", "\u2211", "\u22C0", "\u22C1", "\u22C2", "\u22C3", "\u2A00", "\u2A01", "\u2A02", "\u2A04", "\u2A06"], + props: { + numArgs: 0 + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var fName = funcName; + + if (fName.length === 1) { + fName = singleCharBigOps[fName]; + } + + return { + type: "op", + mode: parser.mode, + limits: true, + parentIsSupSub: false, + symbol: true, + name: fName + }; + }, + htmlBuilder: op_htmlBuilder, + mathmlBuilder: op_mathmlBuilder +}); // Note: calling defineFunction with a type that's already been defined only +// works because the same htmlBuilder and mathmlBuilder are being used. + +defineFunction({ + type: "op", + names: ["\\mathop"], + props: { + numArgs: 1, + primitive: true + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + var body = args[0]; + return { + type: "op", + mode: parser.mode, + limits: false, + parentIsSupSub: false, + symbol: false, + body: ordargument(body) + }; + }, + htmlBuilder: op_htmlBuilder, + mathmlBuilder: op_mathmlBuilder +}); // There are 2 flags for operators; whether they produce limits in +// displaystyle, and whether they are symbols and should grow in +// displaystyle. These four groups cover the four possible choices. + +var singleCharIntegrals = { + "\u222B": "\\int", + "\u222C": "\\iint", + "\u222D": "\\iiint", + "\u222E": "\\oint", + "\u222F": "\\oiint", + "\u2230": "\\oiiint" +}; // No limits, not symbols + +defineFunction({ + type: "op", + names: ["\\arcsin", "\\arccos", "\\arctan", "\\arctg", "\\arcctg", "\\arg", "\\ch", "\\cos", "\\cosec", "\\cosh", "\\cot", "\\cotg", "\\coth", "\\csc", "\\ctg", "\\cth", "\\deg", "\\dim", "\\exp", "\\hom", "\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin", "\\sinh", "\\sh", "\\tan", "\\tanh", "\\tg", "\\th"], + props: { + numArgs: 0 + }, + handler: function handler(_ref3) { + var parser = _ref3.parser, + funcName = _ref3.funcName; + return { + type: "op", + mode: parser.mode, + limits: false, + parentIsSupSub: false, + symbol: false, + name: funcName + }; + }, + htmlBuilder: op_htmlBuilder, + mathmlBuilder: op_mathmlBuilder +}); // Limits, not symbols + +defineFunction({ + type: "op", + names: ["\\det", "\\gcd", "\\inf", "\\lim", "\\max", "\\min", "\\Pr", "\\sup"], + props: { + numArgs: 0 + }, + handler: function handler(_ref4) { + var parser = _ref4.parser, + funcName = _ref4.funcName; + return { + type: "op", + mode: parser.mode, + limits: true, + parentIsSupSub: false, + symbol: false, + name: funcName + }; + }, + htmlBuilder: op_htmlBuilder, + mathmlBuilder: op_mathmlBuilder +}); // No limits, symbols + +defineFunction({ + type: "op", + names: ["\\int", "\\iint", "\\iiint", "\\oint", "\\oiint", "\\oiiint", "\u222B", "\u222C", "\u222D", "\u222E", "\u222F", "\u2230"], + props: { + numArgs: 0 + }, + handler: function handler(_ref5) { + var parser = _ref5.parser, + funcName = _ref5.funcName; + var fName = funcName; + + if (fName.length === 1) { + fName = singleCharIntegrals[fName]; + } + + return { + type: "op", + mode: parser.mode, + limits: false, + parentIsSupSub: false, + symbol: true, + name: fName + }; + }, + htmlBuilder: op_htmlBuilder, + mathmlBuilder: op_mathmlBuilder +}); + + +/** + * All registered global/built-in macros. + * `macros.js` exports this same dictionary again and makes it public. + * `Parser.js` requires this dictionary via `macros.js`. + */ +var _macros = {}; // This function might one day accept an additional argument and do more things. + +function defineMacro(name, body) { + _macros[name] = body; +} + + + + + + + + + +// NOTE: Unlike most `htmlBuilder`s, this one handles not only +// "operatorname", but also "supsub" since \operatorname* can +// affect super/subscripting. +var operatorname_htmlBuilder = function htmlBuilder(grp, options) { + // Operators are handled in the TeXbook pg. 443-444, rule 13(a). + var supGroup; + var subGroup; + var hasLimits = false; + var group; + + if (grp.type === "supsub") { + // If we have limits, supsub will pass us its group to handle. Pull + // out the superscript and subscript and set the group to the op in + // its base. + supGroup = grp.sup; + subGroup = grp.sub; + group = assertNodeType(grp.base, "operatorname"); + hasLimits = true; + } else { + group = assertNodeType(grp, "operatorname"); + } + + var base; + + if (group.body.length > 0) { + var body = group.body.map(function (child) { + // $FlowFixMe: Check if the node has a string `text` property. + var childText = child.text; + + if (typeof childText === "string") { + return { + type: "textord", + mode: child.mode, + text: childText + }; + } else { + return child; + } + }); // Consolidate function names into symbol characters. + + var expression = buildExpression(body, options.withFont("mathrm"), true); + + for (var i = 0; i < expression.length; i++) { + var child = expression[i]; + + if (child instanceof SymbolNode) { + // Per amsopn package, + // change minus to hyphen and \ast to asterisk + child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*"); + } + } + + base = buildCommon.makeSpan(["mop"], expression, options); + } else { + base = buildCommon.makeSpan(["mop"], [], options); + } + + if (hasLimits) { + return assembleSupSub(base, supGroup, subGroup, options, options.style, 0, 0); + } else { + return base; + } +}; + +var operatorname_mathmlBuilder = function mathmlBuilder(group, options) { + // The steps taken here are similar to the html version. + var expression = buildMathML_buildExpression(group.body, options.withFont("mathrm")); // Is expression a string or has it something like a fraction? + + var isAllString = true; // default + + for (var i = 0; i < expression.length; i++) { + var node = expression[i]; + + if (node instanceof mathMLTree.SpaceNode) ; else if (node instanceof mathMLTree.MathNode) { + switch (node.type) { + case "mi": + case "mn": + case "ms": + case "mspace": + case "mtext": + break; + // Do nothing yet. + + case "mo": + { + var child = node.children[0]; + + if (node.children.length === 1 && child instanceof mathMLTree.TextNode) { + child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*"); + } else { + isAllString = false; + } + + break; + } + + default: + isAllString = false; + } + } else { + isAllString = false; + } + } + + if (isAllString) { + // Write a single TextNode instead of multiple nested tags. + var word = expression.map(function (node) { + return node.toText(); + }).join(""); + expression = [new mathMLTree.TextNode(word)]; + } + + var identifier = new mathMLTree.MathNode("mi", expression); + identifier.setAttribute("mathvariant", "normal"); // \u2061 is the same as ⁡ + // ref: https://www.w3schools.com/charsets/ref_html_entities_a.asp + + var operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]); + + if (group.parentIsSupSub) { + return new mathMLTree.MathNode("mrow", [identifier, operator]); + } else { + return mathMLTree.newDocumentFragment([identifier, operator]); + } +}; // \operatorname +// amsopn.dtx: \mathop{#1\kern\z@\operator@font#3}\newmcodes@ + + +defineFunction({ + type: "operatorname", + names: ["\\operatorname@", "\\operatornamewithlimits"], + props: { + numArgs: 1 + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var body = args[0]; + return { + type: "operatorname", + mode: parser.mode, + body: ordargument(body), + alwaysHandleSupSub: funcName === "\\operatornamewithlimits", + limits: false, + parentIsSupSub: false + }; + }, + htmlBuilder: operatorname_htmlBuilder, + mathmlBuilder: operatorname_mathmlBuilder +}); +defineMacro("\\operatorname", "\\@ifstar\\operatornamewithlimits\\operatorname@"); + + + + +defineFunctionBuilders({ + type: "ordgroup", + htmlBuilder: function htmlBuilder(group, options) { + if (group.semisimple) { + return buildCommon.makeFragment(buildExpression(group.body, options, false)); + } + + return buildCommon.makeSpan(["mord"], buildExpression(group.body, options, true), options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + return buildExpressionRow(group.body, options, true); + } +}); + + + + + +defineFunction({ + type: "overline", + names: ["\\overline"], + props: { + numArgs: 1 + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + var body = args[0]; + return { + type: "overline", + mode: parser.mode, + body: body + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Overlines are handled in the TeXbook pg 443, Rule 9. + // Build the inner group in the cramped style. + var innerGroup = buildGroup(group.body, options.havingCrampedStyle()); // Create the line above the body + + var line = buildCommon.makeLineSpan("overline-line", options); // Generate the vlist, with the appropriate kerns + + var defaultRuleThickness = options.fontMetrics().defaultRuleThickness; + var vlist = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: innerGroup + }, { + type: "kern", + size: 3 * defaultRuleThickness + }, { + type: "elem", + elem: line + }, { + type: "kern", + size: defaultRuleThickness + }] + }, options); + return buildCommon.makeSpan(["mord", "overline"], [vlist], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203E")]); + operator.setAttribute("stretchy", "true"); + var node = new mathMLTree.MathNode("mover", [buildMathML_buildGroup(group.body, options), operator]); + node.setAttribute("accent", "true"); + return node; + } +}); + + + + + +defineFunction({ + type: "phantom", + names: ["\\phantom"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + var body = args[0]; + return { + type: "phantom", + mode: parser.mode, + body: ordargument(body) + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var elements = buildExpression(group.body, options.withPhantom(), false); // \phantom isn't supposed to affect the elements it contains. + // See "color" for more details. + + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var inner = buildMathML_buildExpression(group.body, options); + return new mathMLTree.MathNode("mphantom", inner); + } +}); +defineFunction({ + type: "hphantom", + names: ["\\hphantom"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: function handler(_ref2, args) { + var parser = _ref2.parser; + var body = args[0]; + return { + type: "hphantom", + mode: parser.mode, + body: body + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var node = buildCommon.makeSpan([], [buildGroup(group.body, options.withPhantom())]); + node.height = 0; + node.depth = 0; + + if (node.children) { + for (var i = 0; i < node.children.length; i++) { + node.children[i].height = 0; + node.children[i].depth = 0; + } + } // See smash for comment re: use of makeVList + + + node = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: node + }] + }, options); // For spacing, TeX treats \smash as a math group (same spacing as ord). + + return buildCommon.makeSpan(["mord"], [node], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var inner = buildMathML_buildExpression(ordargument(group.body), options); + var phantom = new mathMLTree.MathNode("mphantom", inner); + var node = new mathMLTree.MathNode("mpadded", [phantom]); + node.setAttribute("height", "0px"); + node.setAttribute("depth", "0px"); + return node; + } +}); +defineFunction({ + type: "vphantom", + names: ["\\vphantom"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: function handler(_ref3, args) { + var parser = _ref3.parser; + var body = args[0]; + return { + type: "vphantom", + mode: parser.mode, + body: body + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var inner = buildCommon.makeSpan(["inner"], [buildGroup(group.body, options.withPhantom())]); + var fix = buildCommon.makeSpan(["fix"], []); + return buildCommon.makeSpan(["mord", "rlap"], [inner, fix], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var inner = buildMathML_buildExpression(ordargument(group.body), options); + var phantom = new mathMLTree.MathNode("mphantom", inner); + var node = new mathMLTree.MathNode("mpadded", [phantom]); + node.setAttribute("width", "0px"); + return node; + } +}); + + + + + + + // Box manipulation + +defineFunction({ + type: "raisebox", + names: ["\\raisebox"], + props: { + numArgs: 2, + argTypes: ["size", "hbox"], + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + var amount = assertNodeType(args[0], "size").value; + var body = args[1]; + return { + type: "raisebox", + mode: parser.mode, + dy: amount, + body: body + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var body = buildGroup(group.body, options); + var dy = calculateSize(group.dy, options); + return buildCommon.makeVList({ + positionType: "shift", + positionData: -dy, + children: [{ + type: "elem", + elem: body + }] + }, options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mpadded", [buildMathML_buildGroup(group.body, options)]); + var dy = group.dy.number + group.dy.unit; + node.setAttribute("voffset", dy); + return node; + } +}); + + + + + +defineFunction({ + type: "rule", + names: ["\\rule"], + props: { + numArgs: 2, + numOptionalArgs: 1, + argTypes: ["size", "size", "size"] + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser; + var shift = optArgs[0]; + var width = assertNodeType(args[0], "size"); + var height = assertNodeType(args[1], "size"); + return { + type: "rule", + mode: parser.mode, + shift: shift && assertNodeType(shift, "size").value, + width: width.value, + height: height.value + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Make an empty span for the rule + var rule = buildCommon.makeSpan(["mord", "rule"], [], options); // Calculate the shift, width, and height of the rule, and account for units + + var width = calculateSize(group.width, options); + var height = calculateSize(group.height, options); + var shift = group.shift ? calculateSize(group.shift, options) : 0; // Style the rule to the right size + + rule.style.borderRightWidth = makeEm(width); + rule.style.borderTopWidth = makeEm(height); + rule.style.bottom = makeEm(shift); // Record the height and width + + rule.width = width; + rule.height = height + shift; + rule.depth = -shift; // Font size is the number large enough that the browser will + // reserve at least `absHeight` space above the baseline. + // The 1.125 factor was empirically determined + + rule.maxFontSize = height * 1.125 * options.sizeMultiplier; + return rule; + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var width = calculateSize(group.width, options); + var height = calculateSize(group.height, options); + var shift = group.shift ? calculateSize(group.shift, options) : 0; + var color = options.color && options.getColor() || "black"; + var rule = new mathMLTree.MathNode("mspace"); + rule.setAttribute("mathbackground", color); + rule.setAttribute("width", makeEm(width)); + rule.setAttribute("height", makeEm(height)); + var wrapper = new mathMLTree.MathNode("mpadded", [rule]); + + if (shift >= 0) { + wrapper.setAttribute("height", makeEm(shift)); + } else { + wrapper.setAttribute("height", makeEm(shift)); + wrapper.setAttribute("depth", makeEm(-shift)); + } + + wrapper.setAttribute("voffset", makeEm(shift)); + return wrapper; + } +}); + + + + + + +function sizingGroup(value, options, baseOptions) { + var inner = buildExpression(value, options, false); + var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; // Add size-resetting classes to the inner list and set maxFontSize + // manually. Handle nested size changes. + + for (var i = 0; i < inner.length; i++) { + var pos = inner[i].classes.indexOf("sizing"); + + if (pos < 0) { + Array.prototype.push.apply(inner[i].classes, options.sizingClasses(baseOptions)); + } else if (inner[i].classes[pos + 1] === "reset-size" + options.size) { + // This is a nested size change: e.g., inner[i] is the "b" in + // `\Huge a \small b`. Override the old size (the `reset-` class) + // but not the new size. + inner[i].classes[pos + 1] = "reset-size" + baseOptions.size; + } + + inner[i].height *= multiplier; + inner[i].depth *= multiplier; + } + + return buildCommon.makeFragment(inner); +} +var sizeFuncs = ["\\tiny", "\\sixptsize", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize", "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge"]; +var sizing_htmlBuilder = function htmlBuilder(group, options) { + // Handle sizing operators like \Huge. Real TeX doesn't actually allow + // these functions inside of math expressions, so we do some special + // handling. + var newOptions = options.havingSize(group.size); + return sizingGroup(group.body, newOptions, options); +}; +defineFunction({ + type: "sizing", + names: sizeFuncs, + props: { + numArgs: 0, + allowedInText: true + }, + handler: function handler(_ref, args) { + var breakOnTokenText = _ref.breakOnTokenText, + funcName = _ref.funcName, + parser = _ref.parser; + var body = parser.parseExpression(false, breakOnTokenText); + return { + type: "sizing", + mode: parser.mode, + // Figure out what size to use based on the list of functions above + size: sizeFuncs.indexOf(funcName) + 1, + body: body + }; + }, + htmlBuilder: sizing_htmlBuilder, + mathmlBuilder: function mathmlBuilder(group, options) { + var newOptions = options.havingSize(group.size); + var inner = buildMathML_buildExpression(group.body, newOptions); + var node = new mathMLTree.MathNode("mstyle", inner); // TODO(emily): This doesn't produce the correct size for nested size + // changes, because we don't keep state of what style we're currently + // in, so we can't reset the size to normal before changing it. Now + // that we're passing an options parameter we should be able to fix + // this. + + node.setAttribute("mathsize", makeEm(newOptions.sizeMultiplier)); + return node; + } +}); +// smash, with optional [tb], as in AMS + + + + + + +defineFunction({ + type: "smash", + names: ["\\smash"], + props: { + numArgs: 1, + numOptionalArgs: 1, + allowedInText: true + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser; + var smashHeight = false; + var smashDepth = false; + var tbArg = optArgs[0] && assertNodeType(optArgs[0], "ordgroup"); + + if (tbArg) { + // Optional [tb] argument is engaged. + // ref: amsmath: \renewcommand{\smash}[1][tb]{% + // def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}% + var letter = ""; + + for (var i = 0; i < tbArg.body.length; ++i) { + var node = tbArg.body[i]; // $FlowFixMe: Not every node type has a `text` property. + + letter = node.text; + + if (letter === "t") { + smashHeight = true; + } else if (letter === "b") { + smashDepth = true; + } else { + smashHeight = false; + smashDepth = false; + break; + } + } + } else { + smashHeight = true; + smashDepth = true; + } + + var body = args[0]; + return { + type: "smash", + mode: parser.mode, + body: body, + smashHeight: smashHeight, + smashDepth: smashDepth + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var node = buildCommon.makeSpan([], [buildGroup(group.body, options)]); + + if (!group.smashHeight && !group.smashDepth) { + return node; + } + + if (group.smashHeight) { + node.height = 0; // In order to influence makeVList, we have to reset the children. + + if (node.children) { + for (var i = 0; i < node.children.length; i++) { + node.children[i].height = 0; + } + } + } + + if (group.smashDepth) { + node.depth = 0; + + if (node.children) { + for (var _i = 0; _i < node.children.length; _i++) { + node.children[_i].depth = 0; + } + } + } // At this point, we've reset the TeX-like height and depth values. + // But the span still has an HTML line height. + // makeVList applies "display: table-cell", which prevents the browser + // from acting on that line height. So we'll call makeVList now. + + + var smashedNode = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: node + }] + }, options); // For spacing, TeX treats \hphantom as a math group (same spacing as ord). + + return buildCommon.makeSpan(["mord"], [smashedNode], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mpadded", [buildMathML_buildGroup(group.body, options)]); + + if (group.smashHeight) { + node.setAttribute("height", "0px"); + } + + if (group.smashDepth) { + node.setAttribute("depth", "0px"); + } + + return node; + } +}); + + + + + + + + +defineFunction({ + type: "sqrt", + names: ["\\sqrt"], + props: { + numArgs: 1, + numOptionalArgs: 1 + }, + handler: function handler(_ref, args, optArgs) { + var parser = _ref.parser; + var index = optArgs[0]; + var body = args[0]; + return { + type: "sqrt", + mode: parser.mode, + body: body, + index: index + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Square roots are handled in the TeXbook pg. 443, Rule 11. + // First, we do the same steps as in overline to build the inner group + // and line + var inner = buildGroup(group.body, options.havingCrampedStyle()); + + if (inner.height === 0) { + // Render a small surd. + inner.height = options.fontMetrics().xHeight; + } // Some groups can return document fragments. Handle those by wrapping + // them in a span. + + + inner = buildCommon.wrapFragment(inner, options); // Calculate the minimum size for the \surd delimiter + + var metrics = options.fontMetrics(); + var theta = metrics.defaultRuleThickness; + var phi = theta; + + if (options.style.id < src_Style.TEXT.id) { + phi = options.fontMetrics().xHeight; + } // Calculate the clearance between the body and line + + + var lineClearance = theta + phi / 4; + var minDelimiterHeight = inner.height + inner.depth + lineClearance + theta; // Create a sqrt SVG of the required minimum size + + var _delimiter$sqrtImage = delimiter.sqrtImage(minDelimiterHeight, options), + img = _delimiter$sqrtImage.span, + ruleWidth = _delimiter$sqrtImage.ruleWidth, + advanceWidth = _delimiter$sqrtImage.advanceWidth; + + var delimDepth = img.height - ruleWidth; // Adjust the clearance based on the delimiter size + + if (delimDepth > inner.height + inner.depth + lineClearance) { + lineClearance = (lineClearance + delimDepth - inner.height - inner.depth) / 2; + } // Shift the sqrt image + + + var imgShift = img.height - inner.height - lineClearance - ruleWidth; + inner.style.paddingLeft = makeEm(advanceWidth); // Overlay the image and the argument. + + var body = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: inner, + wrapperClasses: ["svg-align"] + }, { + type: "kern", + size: -(inner.height + imgShift) + }, { + type: "elem", + elem: img + }, { + type: "kern", + size: ruleWidth + }] + }, options); + + if (!group.index) { + return buildCommon.makeSpan(["mord", "sqrt"], [body], options); + } else { + // Handle the optional root index + // The index is always in scriptscript style + var newOptions = options.havingStyle(src_Style.SCRIPTSCRIPT); + var rootm = buildGroup(group.index, newOptions, options); // The amount the index is shifted by. This is taken from the TeX + // source, in the definition of `\r@@t`. + + var toShift = 0.6 * (body.height - body.depth); // Build a VList with the superscript shifted up correctly + + var rootVList = buildCommon.makeVList({ + positionType: "shift", + positionData: -toShift, + children: [{ + type: "elem", + elem: rootm + }] + }, options); // Add a class surrounding it so we can add on the appropriate + // kerning + + var rootVListWrap = buildCommon.makeSpan(["root"], [rootVList]); + return buildCommon.makeSpan(["mord", "sqrt"], [rootVListWrap, body], options); + } + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var body = group.body, + index = group.index; + return index ? new mathMLTree.MathNode("mroot", [buildMathML_buildGroup(body, options), buildMathML_buildGroup(index, options)]) : new mathMLTree.MathNode("msqrt", [buildMathML_buildGroup(body, options)]); + } +}); + + + + + +var styling_styleMap = { + "display": src_Style.DISPLAY, + "text": src_Style.TEXT, + "script": src_Style.SCRIPT, + "scriptscript": src_Style.SCRIPTSCRIPT +}; +defineFunction({ + type: "styling", + names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + handler: function handler(_ref, args) { + var breakOnTokenText = _ref.breakOnTokenText, + funcName = _ref.funcName, + parser = _ref.parser; + // parse out the implicit body + var body = parser.parseExpression(true, breakOnTokenText); // TODO: Refactor to avoid duplicating styleMap in multiple places (e.g. + // here and in buildHTML and de-dupe the enumeration of all the styles). + // $FlowFixMe: The names above exactly match the styles. + + var style = funcName.slice(1, funcName.length - 5); + return { + type: "styling", + mode: parser.mode, + // Figure out what style to use by pulling out the style from + // the function name + style: style, + body: body + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Style changes are handled in the TeXbook on pg. 442, Rule 3. + var newStyle = styling_styleMap[group.style]; + var newOptions = options.havingStyle(newStyle).withFont(''); + return sizingGroup(group.body, newOptions, options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + // Figure out what style we're changing to. + var newStyle = styling_styleMap[group.style]; + var newOptions = options.havingStyle(newStyle); + var inner = buildMathML_buildExpression(group.body, newOptions); + var node = new mathMLTree.MathNode("mstyle", inner); + var styleAttributes = { + "display": ["0", "true"], + "text": ["0", "false"], + "script": ["1", "false"], + "scriptscript": ["2", "false"] + }; + var attr = styleAttributes[group.style]; + node.setAttribute("scriptlevel", attr[0]); + node.setAttribute("displaystyle", attr[1]); + return node; + } +}); + + + + + + + + + + + + + + +/** + * Sometimes, groups perform special rules when they have superscripts or + * subscripts attached to them. This function lets the `supsub` group know that + * Sometimes, groups perform special rules when they have superscripts or + * its inner element should handle the superscripts and subscripts instead of + * handling them itself. + */ +var htmlBuilderDelegate = function htmlBuilderDelegate(group, options) { + var base = group.base; + + if (!base) { + return null; + } else if (base.type === "op") { + // Operators handle supsubs differently when they have limits + // (e.g. `\displaystyle\sum_2^3`) + var delegate = base.limits && (options.style.size === src_Style.DISPLAY.size || base.alwaysHandleSupSub); + return delegate ? op_htmlBuilder : null; + } else if (base.type === "operatorname") { + var _delegate = base.alwaysHandleSupSub && (options.style.size === src_Style.DISPLAY.size || base.limits); + + return _delegate ? operatorname_htmlBuilder : null; + } else if (base.type === "accent") { + return utils.isCharacterBox(base.base) ? htmlBuilder : null; + } else if (base.type === "horizBrace") { + var isSup = !group.sub; + return isSup === base.isOver ? horizBrace_htmlBuilder : null; + } else { + return null; + } +}; // Super scripts and subscripts, whose precise placement can depend on other +// functions that precede them. + + +defineFunctionBuilders({ + type: "supsub", + htmlBuilder: function htmlBuilder(group, options) { + // Superscript and subscripts are handled in the TeXbook on page + // 445-446, rules 18(a-f). + // Here is where we defer to the inner group if it should handle + // superscripts and subscripts itself. + var builderDelegate = htmlBuilderDelegate(group, options); + + if (builderDelegate) { + return builderDelegate(group, options); + } + + var valueBase = group.base, + valueSup = group.sup, + valueSub = group.sub; + var base = buildGroup(valueBase, options); + var supm; + var subm; + var metrics = options.fontMetrics(); // Rule 18a + + var supShift = 0; + var subShift = 0; + var isCharacterBox = valueBase && utils.isCharacterBox(valueBase); + + if (valueSup) { + var newOptions = options.havingStyle(options.style.sup()); + supm = buildGroup(valueSup, newOptions, options); + + if (!isCharacterBox) { + supShift = base.height - newOptions.fontMetrics().supDrop * newOptions.sizeMultiplier / options.sizeMultiplier; + } + } + + if (valueSub) { + var _newOptions = options.havingStyle(options.style.sub()); + + subm = buildGroup(valueSub, _newOptions, options); + + if (!isCharacterBox) { + subShift = base.depth + _newOptions.fontMetrics().subDrop * _newOptions.sizeMultiplier / options.sizeMultiplier; + } + } // Rule 18c + + + var minSupShift; + + if (options.style === src_Style.DISPLAY) { + minSupShift = metrics.sup1; + } else if (options.style.cramped) { + minSupShift = metrics.sup3; + } else { + minSupShift = metrics.sup2; + } // scriptspace is a font-size-independent size, so scale it + // appropriately for use as the marginRight. + + + var multiplier = options.sizeMultiplier; + var marginRight = makeEm(0.5 / metrics.ptPerEm / multiplier); + var marginLeft = null; + + if (subm) { + // Subscripts shouldn't be shifted by the base's italic correction. + // Account for that by shifting the subscript back the appropriate + // amount. Note we only do this when the base is a single symbol. + var isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint"); + + if (base instanceof SymbolNode || isOiint) { + // $FlowFixMe + marginLeft = makeEm(-base.italic); + } + } + + var supsub; + + if (supm && subm) { + supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight); + subShift = Math.max(subShift, metrics.sub2); + var ruleWidth = metrics.defaultRuleThickness; // Rule 18e + + var maxWidth = 4 * ruleWidth; + + if (supShift - supm.depth - (subm.height - subShift) < maxWidth) { + subShift = maxWidth - (supShift - supm.depth) + subm.height; + var psi = 0.8 * metrics.xHeight - (supShift - supm.depth); + + if (psi > 0) { + supShift += psi; + subShift -= psi; + } + } + + var vlistElem = [{ + type: "elem", + elem: subm, + shift: subShift, + marginRight: marginRight, + marginLeft: marginLeft + }, { + type: "elem", + elem: supm, + shift: -supShift, + marginRight: marginRight + }]; + supsub = buildCommon.makeVList({ + positionType: "individualShift", + children: vlistElem + }, options); + } else if (subm) { + // Rule 18b + subShift = Math.max(subShift, metrics.sub1, subm.height - 0.8 * metrics.xHeight); + var _vlistElem = [{ + type: "elem", + elem: subm, + marginLeft: marginLeft, + marginRight: marginRight + }]; + supsub = buildCommon.makeVList({ + positionType: "shift", + positionData: subShift, + children: _vlistElem + }, options); + } else if (supm) { + // Rule 18c, d + supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight); + supsub = buildCommon.makeVList({ + positionType: "shift", + positionData: -supShift, + children: [{ + type: "elem", + elem: supm, + marginRight: marginRight + }] + }, options); + } else { + throw new Error("supsub must have either sup or sub."); + } // Wrap the supsub vlist in a span.msupsub to reset text-align. + + + var mclass = getTypeOfDomTree(base, "right") || "mord"; + return buildCommon.makeSpan([mclass], [base, buildCommon.makeSpan(["msupsub"], [supsub])], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + // Is the inner group a relevant horizonal brace? + var isBrace = false; + var isOver; + var isSup; + + if (group.base && group.base.type === "horizBrace") { + isSup = !!group.sup; + + if (isSup === group.base.isOver) { + isBrace = true; + isOver = group.base.isOver; + } + } + + if (group.base && (group.base.type === "op" || group.base.type === "operatorname")) { + group.base.parentIsSupSub = true; + } + + var children = [buildMathML_buildGroup(group.base, options)]; + + if (group.sub) { + children.push(buildMathML_buildGroup(group.sub, options)); + } + + if (group.sup) { + children.push(buildMathML_buildGroup(group.sup, options)); + } + + var nodeType; + + if (isBrace) { + nodeType = isOver ? "mover" : "munder"; + } else if (!group.sub) { + var base = group.base; + + if (base && base.type === "op" && base.limits && (options.style === src_Style.DISPLAY || base.alwaysHandleSupSub)) { + nodeType = "mover"; + } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (base.limits || options.style === src_Style.DISPLAY)) { + nodeType = "mover"; + } else { + nodeType = "msup"; + } + } else if (!group.sup) { + var _base = group.base; + + if (_base && _base.type === "op" && _base.limits && (options.style === src_Style.DISPLAY || _base.alwaysHandleSupSub)) { + nodeType = "munder"; + } else if (_base && _base.type === "operatorname" && _base.alwaysHandleSupSub && (_base.limits || options.style === src_Style.DISPLAY)) { + nodeType = "munder"; + } else { + nodeType = "msub"; + } + } else { + var _base2 = group.base; + + if (_base2 && _base2.type === "op" && _base2.limits && options.style === src_Style.DISPLAY) { + nodeType = "munderover"; + } else if (_base2 && _base2.type === "operatorname" && _base2.alwaysHandleSupSub && (options.style === src_Style.DISPLAY || _base2.limits)) { + nodeType = "munderover"; + } else { + nodeType = "msubsup"; + } + } + + return new mathMLTree.MathNode(nodeType, children); + } +}); + + + + // Operator ParseNodes created in Parser.js from symbol Groups in src/symbols.js. + +defineFunctionBuilders({ + type: "atom", + htmlBuilder: function htmlBuilder(group, options) { + return buildCommon.mathsym(group.text, group.mode, options, ["m" + group.family]); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mo", [makeText(group.text, group.mode)]); + + if (group.family === "bin") { + var variant = getVariant(group, options); + + if (variant === "bold-italic") { + node.setAttribute("mathvariant", variant); + } + } else if (group.family === "punct") { + node.setAttribute("separator", "true"); + } else if (group.family === "open" || group.family === "close") { + // Delims built here should not stretch vertically. + // See delimsizing.js for stretchy delims. + node.setAttribute("stretchy", "false"); + } + + return node; + } +}); + + + + +// "mathord" and "textord" ParseNodes created in Parser.js from symbol Groups in +// src/symbols.js. +var defaultVariant = { + "mi": "italic", + "mn": "normal", + "mtext": "normal" +}; +defineFunctionBuilders({ + type: "mathord", + htmlBuilder: function htmlBuilder(group, options) { + return buildCommon.makeOrd(group, options, "mathord"); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mi", [makeText(group.text, group.mode, options)]); + var variant = getVariant(group, options) || "italic"; + + if (variant !== defaultVariant[node.type]) { + node.setAttribute("mathvariant", variant); + } + + return node; + } +}); +defineFunctionBuilders({ + type: "textord", + htmlBuilder: function htmlBuilder(group, options) { + return buildCommon.makeOrd(group, options, "textord"); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var text = makeText(group.text, group.mode, options); + var variant = getVariant(group, options) || "normal"; + var node; + + if (group.mode === 'text') { + node = new mathMLTree.MathNode("mtext", [text]); + } else if (/[0-9]/.test(group.text)) { + node = new mathMLTree.MathNode("mn", [text]); + } else if (group.text === "\\prime") { + node = new mathMLTree.MathNode("mo", [text]); + } else { + node = new mathMLTree.MathNode("mi", [text]); + } + + if (variant !== defaultVariant[node.type]) { + node.setAttribute("mathvariant", variant); + } + + return node; + } +}); + + + + // A map of CSS-based spacing functions to their CSS class. + +var cssSpace = { + "\\nobreak": "nobreak", + "\\allowbreak": "allowbreak" +}; // A lookup table to determine whether a spacing function/symbol should be +// treated like a regular space character. If a symbol or command is a key +// in this table, then it should be a regular space character. Furthermore, +// the associated value may have a `className` specifying an extra CSS class +// to add to the created `span`. + +var regularSpace = { + " ": {}, + "\\ ": {}, + "~": { + className: "nobreak" + }, + "\\space": {}, + "\\nobreakspace": { + className: "nobreak" + } +}; // ParseNode<"spacing"> created in Parser.js from the "spacing" symbol Groups in +// src/symbols.js. + +defineFunctionBuilders({ + type: "spacing", + htmlBuilder: function htmlBuilder(group, options) { + if (regularSpace.hasOwnProperty(group.text)) { + var className = regularSpace[group.text].className || ""; // Spaces are generated by adding an actual space. Each of these + // things has an entry in the symbols table, so these will be turned + // into appropriate outputs. + + if (group.mode === "text") { + var ord = buildCommon.makeOrd(group, options, "textord"); + ord.classes.push(className); + return ord; + } else { + return buildCommon.makeSpan(["mspace", className], [buildCommon.mathsym(group.text, group.mode, options)], options); + } + } else if (cssSpace.hasOwnProperty(group.text)) { + // Spaces based on just a CSS class. + return buildCommon.makeSpan(["mspace", cssSpace[group.text]], [], options); + } else { + throw new src_ParseError("Unknown type of space \"" + group.text + "\""); + } + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var node; + + if (regularSpace.hasOwnProperty(group.text)) { + node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("\xA0")]); + } else if (cssSpace.hasOwnProperty(group.text)) { + // CSS-based MathML spaces (\nobreak, \allowbreak) are ignored + return new mathMLTree.MathNode("mspace"); + } else { + throw new src_ParseError("Unknown type of space \"" + group.text + "\""); + } + + return node; + } +}); + + + + +var pad = function pad() { + var padNode = new mathMLTree.MathNode("mtd", []); + padNode.setAttribute("width", "50%"); + return padNode; +}; + +defineFunctionBuilders({ + type: "tag", + mathmlBuilder: function mathmlBuilder(group, options) { + var table = new mathMLTree.MathNode("mtable", [new mathMLTree.MathNode("mtr", [pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.body, options)]), pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.tag, options)])])]); + table.setAttribute("width", "100%"); + return table; // TODO: Left-aligned tags. + // Currently, the group and options passed here do not contain + // enough info to set tag alignment. `leqno` is in Settings but it is + // not passed to Options. On the HTML side, leqno is + // set by a CSS class applied in buildTree.js. That would have worked + // in MathML if browsers supported . Since they don't, we + // need to rewrite the way this function is called. + } +}); + + + + // Non-mathy text, possibly in a font + +var textFontFamilies = { + "\\text": undefined, + "\\textrm": "textrm", + "\\textsf": "textsf", + "\\texttt": "texttt", + "\\textnormal": "textrm" +}; +var textFontWeights = { + "\\textbf": "textbf", + "\\textmd": "textmd" +}; +var textFontShapes = { + "\\textit": "textit", + "\\textup": "textup" +}; + +var optionsWithFont = function optionsWithFont(group, options) { + var font = group.font; // Checks if the argument is a font family or a font style. + + if (!font) { + return options; + } else if (textFontFamilies[font]) { + return options.withTextFontFamily(textFontFamilies[font]); + } else if (textFontWeights[font]) { + return options.withTextFontWeight(textFontWeights[font]); + } else { + return options.withTextFontShape(textFontShapes[font]); + } +}; + +defineFunction({ + type: "text", + names: [// Font families + "\\text", "\\textrm", "\\textsf", "\\texttt", "\\textnormal", // Font weights + "\\textbf", "\\textmd", // Font Shapes + "\\textit", "\\textup"], + props: { + numArgs: 1, + argTypes: ["text"], + allowedInArgument: true, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser, + funcName = _ref.funcName; + var body = args[0]; + return { + type: "text", + mode: parser.mode, + body: ordargument(body), + font: funcName + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var newOptions = optionsWithFont(group, options); + var inner = buildExpression(group.body, newOptions, true); + return buildCommon.makeSpan(["mord", "text"], inner, newOptions); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var newOptions = optionsWithFont(group, options); + return buildExpressionRow(group.body, newOptions); + } +}); + + + + + +defineFunction({ + type: "underline", + names: ["\\underline"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + return { + type: "underline", + mode: parser.mode, + body: args[0] + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + // Underlines are handled in the TeXbook pg 443, Rule 10. + // Build the inner group. + var innerGroup = buildGroup(group.body, options); // Create the line to go below the body + + var line = buildCommon.makeLineSpan("underline-line", options); // Generate the vlist, with the appropriate kerns + + var defaultRuleThickness = options.fontMetrics().defaultRuleThickness; + var vlist = buildCommon.makeVList({ + positionType: "top", + positionData: innerGroup.height, + children: [{ + type: "kern", + size: defaultRuleThickness + }, { + type: "elem", + elem: line + }, { + type: "kern", + size: 3 * defaultRuleThickness + }, { + type: "elem", + elem: innerGroup + }] + }, options); + return buildCommon.makeSpan(["mord", "underline"], [vlist], options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203E")]); + operator.setAttribute("stretchy", "true"); + var node = new mathMLTree.MathNode("munder", [buildMathML_buildGroup(group.body, options), operator]); + node.setAttribute("accentunder", "true"); + return node; + } +}); + + + + + // \vcenter: Vertically center the argument group on the math axis. + +defineFunction({ + type: "vcenter", + names: ["\\vcenter"], + props: { + numArgs: 1, + argTypes: ["original"], + // In LaTeX, \vcenter can act only on a box. + allowedInText: false + }, + handler: function handler(_ref, args) { + var parser = _ref.parser; + return { + type: "vcenter", + mode: parser.mode, + body: args[0] + }; + }, + htmlBuilder: function htmlBuilder(group, options) { + var body = buildGroup(group.body, options); + var axisHeight = options.fontMetrics().axisHeight; + var dy = 0.5 * (body.height - axisHeight - (body.depth + axisHeight)); + return buildCommon.makeVList({ + positionType: "shift", + positionData: dy, + children: [{ + type: "elem", + elem: body + }] + }, options); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + // There is no way to do this in MathML. + // Write a class as a breadcrumb in case some post-processor wants + // to perform a vcenter adjustment. + return new mathMLTree.MathNode("mpadded", [buildMathML_buildGroup(group.body, options)], ["vcenter"]); + } +}); + + + + +defineFunction({ + type: "verb", + names: ["\\verb"], + props: { + numArgs: 0, + allowedInText: true + }, + handler: function handler(context, args, optArgs) { + // \verb and \verb* are dealt with directly in Parser.js. + // If we end up here, it's because of a failure to match the two delimiters + // in the regex in Lexer.js. LaTeX raises the following error when \verb is + // terminated by end of line (or file). + throw new src_ParseError("\\verb ended by end of line instead of matching delimiter"); + }, + htmlBuilder: function htmlBuilder(group, options) { + var text = makeVerb(group); + var body = []; // \verb enters text mode and therefore is sized like \textstyle + + var newOptions = options.havingStyle(options.style.text()); + + for (var i = 0; i < text.length; i++) { + var c = text[i]; + + if (c === '~') { + c = '\\textasciitilde'; + } + + body.push(buildCommon.makeSymbol(c, "Typewriter-Regular", group.mode, newOptions, ["mord", "texttt"])); + } + + return buildCommon.makeSpan(["mord", "text"].concat(newOptions.sizingClasses(options)), buildCommon.tryCombineChars(body), newOptions); + }, + mathmlBuilder: function mathmlBuilder(group, options) { + var text = new mathMLTree.TextNode(makeVerb(group)); + var node = new mathMLTree.MathNode("mtext", [text]); + node.setAttribute("mathvariant", "monospace"); + return node; + } +}); +/** + * Converts verb group into body string. + * + * \verb* replaces each space with an open box \u2423 + * \verb replaces each space with a no-break space \xA0 + */ + +var makeVerb = function makeVerb(group) { + return group.body.replace(/ /g, group.star ? "\u2423" : '\xA0'); +}; +/** Include this to ensure that all functions are defined. */ + +var functions = _functions; +/* harmony default export */ var src_functions = (functions); // TODO(kevinb): have functions return an object and call defineFunction with +/** + * Lexing or parsing positional information for error reporting. + * This object is immutable. + */ +var SourceLocation = /*#__PURE__*/function () { + // The + prefix indicates that these fields aren't writeable + // Lexer holding the input string. + // Start offset, zero-based inclusive. + // End offset, zero-based exclusive. + function SourceLocation(lexer, start, end) { + this.lexer = void 0; + this.start = void 0; + this.end = void 0; + this.lexer = lexer; + this.start = start; + this.end = end; + } + /** + * Merges two `SourceLocation`s from location providers, given they are + * provided in order of appearance. + * - Returns the first one's location if only the first is provided. + * - Returns a merged range of the first and the last if both are provided + * and their lexers match. + * - Otherwise, returns null. + */ + + + SourceLocation.range = function range(first, second) { + if (!second) { + return first && first.loc; + } else if (!first || !first.loc || !second.loc || first.loc.lexer !== second.loc.lexer) { + return null; + } else { + return new SourceLocation(first.loc.lexer, first.loc.start, second.loc.end); + } + }; + + return SourceLocation; +}(); + +/** + * Interface required to break circular dependency between Token, Lexer, and + * ParseError. + */ + +/** + * The resulting token returned from `lex`. + * + * It consists of the token text plus some position information. + * The position information is essentially a range in an input string, + * but instead of referencing the bare input string, we refer to the lexer. + * That way it is possible to attach extra metadata to the input string, + * like for example a file name or similar. + * + * The position information is optional, so it is OK to construct synthetic + * tokens if appropriate. Not providing available position information may + * lead to degraded error reporting, though. + */ +var Token = /*#__PURE__*/function () { + // don't expand the token + // used in \noexpand + function Token(text, // the text of this token + loc) { + this.text = void 0; + this.loc = void 0; + this.noexpand = void 0; + this.treatAsRelax = void 0; + this.text = text; + this.loc = loc; + } + /** + * Given a pair of tokens (this and endToken), compute a `Token` encompassing + * the whole input range enclosed by these two. + */ + + + var _proto = Token.prototype; + + _proto.range = function range(endToken, // last token of the range, inclusive + text // the text of the newly constructed token + ) { + return new Token(text, SourceLocation.range(this, endToken)); + }; + + return Token; +}(); +/** + * The Lexer class handles tokenizing the input in various ways. Since our + * parser expects us to be able to backtrack, the lexer allows lexing from any + * given starting point. + * + * Its main exposed function is the `lex` function, which takes a position to + * lex from and a type of token to lex. It defers to the appropriate `_innerLex` + * function. + * + * The various `_innerLex` functions perform the actual lexing of different + * kinds. + */ + + + + +/* The following tokenRegex + * - matches typical whitespace (but not NBSP etc.) using its first group + * - does not match any control character \x00-\x1f except whitespace + * - does not match a bare backslash + * - matches any ASCII character except those just mentioned + * - does not match the BMP private use area \uE000-\uF8FF + * - does not match bare surrogate code units + * - matches any BMP character except for those just described + * - matches any valid Unicode surrogate pair + * - matches a backslash followed by one or more whitespace characters + * - matches a backslash followed by one or more letters then whitespace + * - matches a backslash followed by any BMP character + * Capturing groups: + * [1] regular whitespace + * [2] backslash followed by whitespace + * [3] anything else, which may include: + * [4] left character of \verb* + * [5] left character of \verb + * [6] backslash followed by word, excluding any trailing whitespace + * Just because the Lexer matches something doesn't mean it's valid input: + * If there is no matching function or symbol definition, the Parser will + * still reject the input. + */ +var spaceRegexString = "[ \r\n\t]"; +var controlWordRegexString = "\\\\[a-zA-Z@]+"; +var controlSymbolRegexString = "\\\\[^\uD800-\uDFFF]"; +var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spaceRegexString + "*"; +var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*"; +var combiningDiacriticalMarkString = "[\u0300-\u036F]"; +var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$"); +var tokenRegexString = "(" + spaceRegexString + "+)|" + ( // whitespace +controlSpaceRegexString + "|") + // \whitespace +"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + ( // single codepoint +combiningDiacriticalMarkString + "*") + // ...plus accents +"|[\uD800-\uDBFF][\uDC00-\uDFFF]" + ( // surrogate pair +combiningDiacriticalMarkString + "*") + // ...plus accents +"|\\\\verb\\*([^]).*?\\4" + // \verb* +"|\\\\verb([^*a-zA-Z]).*?\\5" + ( // \verb unstarred +"|" + controlWordWhitespaceRegexString) + ( // \macroName + spaces +"|" + controlSymbolRegexString + ")"); // \\, \', etc. + +/** Main Lexer class */ + +var Lexer = /*#__PURE__*/function () { + // Category codes. The lexer only supports comment characters (14) for now. + // MacroExpander additionally distinguishes active (13). + function Lexer(input, settings) { + this.input = void 0; + this.settings = void 0; + this.tokenRegex = void 0; + this.catcodes = void 0; + // Separate accents from characters + this.input = input; + this.settings = settings; + this.tokenRegex = new RegExp(tokenRegexString, 'g'); + this.catcodes = { + "%": 14, + // comment character + "~": 13 // active character + + }; + } + + var _proto = Lexer.prototype; + + _proto.setCatcode = function setCatcode(char, code) { + this.catcodes[char] = code; + } + /** + * This function lexes a single token. + */ + ; + + _proto.lex = function lex() { + var input = this.input; + var pos = this.tokenRegex.lastIndex; + + if (pos === input.length) { + return new Token("EOF", new SourceLocation(this, pos, pos)); + } + + var match = this.tokenRegex.exec(input); + + if (match === null || match.index !== pos) { + throw new src_ParseError("Unexpected character: '" + input[pos] + "'", new Token(input[pos], new SourceLocation(this, pos, pos + 1))); + } + + var text = match[6] || match[3] || (match[2] ? "\\ " : " "); + + if (this.catcodes[text] === 14) { + // comment character + var nlIndex = input.indexOf('\n', this.tokenRegex.lastIndex); + + if (nlIndex === -1) { + this.tokenRegex.lastIndex = input.length; // EOF + + this.settings.reportNonstrict("commentAtEnd", "% comment has no terminating newline; LaTeX would " + "fail because of commenting the end of math mode (e.g. $)"); + } else { + this.tokenRegex.lastIndex = nlIndex + 1; + } + + return this.lex(); + } + + return new Token(text, new SourceLocation(this, pos, this.tokenRegex.lastIndex)); + }; + + return Lexer; +}(); +/** + * A `Namespace` refers to a space of nameable things like macros or lengths, + * which can be `set` either globally or local to a nested group, using an + * undo stack similar to how TeX implements this functionality. + * Performance-wise, `get` and local `set` take constant time, while global + * `set` takes time proportional to the depth of group nesting. + */ + + +var Namespace = /*#__PURE__*/function () { + /** + * Both arguments are optional. The first argument is an object of + * built-in mappings which never change. The second argument is an object + * of initial (global-level) mappings, which will constantly change + * according to any global/top-level `set`s done. + */ + function Namespace(builtins, globalMacros) { + if (builtins === void 0) { + builtins = {}; + } + + if (globalMacros === void 0) { + globalMacros = {}; + } + + this.current = void 0; + this.builtins = void 0; + this.undefStack = void 0; + this.current = globalMacros; + this.builtins = builtins; + this.undefStack = []; + } + /** + * Start a new nested group, affecting future local `set`s. + */ + + + var _proto = Namespace.prototype; + + _proto.beginGroup = function beginGroup() { + this.undefStack.push({}); + } + /** + * End current nested group, restoring values before the group began. + */ + ; + + _proto.endGroup = function endGroup() { + if (this.undefStack.length === 0) { + throw new src_ParseError("Unbalanced namespace destruction: attempt " + "to pop global namespace; please report this as a bug"); + } + + var undefs = this.undefStack.pop(); + + for (var undef in undefs) { + if (undefs.hasOwnProperty(undef)) { + if (undefs[undef] === undefined) { + delete this.current[undef]; + } else { + this.current[undef] = undefs[undef]; + } + } + } + } + /** + * Ends all currently nested groups (if any), restoring values before the + * groups began. Useful in case of an error in the middle of parsing. + */ + ; + + _proto.endGroups = function endGroups() { + while (this.undefStack.length > 0) { + this.endGroup(); + } + } + /** + * Detect whether `name` has a definition. Equivalent to + * `get(name) != null`. + */ + ; + + _proto.has = function has(name) { + return this.current.hasOwnProperty(name) || this.builtins.hasOwnProperty(name); + } + /** + * Get the current value of a name, or `undefined` if there is no value. + * + * Note: Do not use `if (namespace.get(...))` to detect whether a macro + * is defined, as the definition may be the empty string which evaluates + * to `false` in JavaScript. Use `if (namespace.get(...) != null)` or + * `if (namespace.has(...))`. + */ + ; + + _proto.get = function get(name) { + if (this.current.hasOwnProperty(name)) { + return this.current[name]; + } else { + return this.builtins[name]; + } + } + /** + * Set the current value of a name, and optionally set it globally too. + * Local set() sets the current value and (when appropriate) adds an undo + * operation to the undo stack. Global set() may change the undo + * operation at every level, so takes time linear in their number. + */ + ; + + _proto.set = function set(name, value, global) { + if (global === void 0) { + global = false; + } + + if (global) { + // Global set is equivalent to setting in all groups. Simulate this + // by destroying any undos currently scheduled for this name, + // and adding an undo with the *new* value (in case it later gets + // locally reset within this environment). + for (var i = 0; i < this.undefStack.length; i++) { + delete this.undefStack[i][name]; + } + + if (this.undefStack.length > 0) { + this.undefStack[this.undefStack.length - 1][name] = value; + } + } else { + // Undo this set at end of this group (possibly to `undefined`), + // unless an undo is already in place, in which case that older + // value is the correct one. + var top = this.undefStack[this.undefStack.length - 1]; + + if (top && !top.hasOwnProperty(name)) { + top[name] = this.current[name]; + } + } + + this.current[name] = value; + }; + + return Namespace; +}(); +/** + * Predefined macros for KaTeX. + * This can be used to define some commands in terms of others. + */ +// Export global macros object from defineMacro + +var macros = _macros; +/* harmony default export */ var src_macros = (macros); + + + + + + ////////////////////////////////////////////////////////////////////// +// macro tools + +defineMacro("\\noexpand", function (context) { + // The expansion is the token itself; but that token is interpreted + // as if its meaning were ‘\relax’ if it is a control sequence that + // would ordinarily be expanded by TeX’s expansion rules. + var t = context.popToken(); + + if (context.isExpandable(t.text)) { + t.noexpand = true; + t.treatAsRelax = true; + } + + return { + tokens: [t], + numArgs: 0 + }; +}); +defineMacro("\\expandafter", function (context) { + // TeX first reads the token that comes immediately after \expandafter, + // without expanding it; let’s call this token t. Then TeX reads the + // token that comes after t (and possibly more tokens, if that token + // has an argument), replacing it by its expansion. Finally TeX puts + // t back in front of that expansion. + var t = context.popToken(); + context.expandOnce(true); // expand only an expandable token + + return { + tokens: [t], + numArgs: 0 + }; +}); // LaTeX's \@firstoftwo{#1}{#2} expands to #1, skipping #2 +// TeX source: \long\def\@firstoftwo#1#2{#1} + +defineMacro("\\@firstoftwo", function (context) { + var args = context.consumeArgs(2); + return { + tokens: args[0], + numArgs: 0 + }; +}); // LaTeX's \@secondoftwo{#1}{#2} expands to #2, skipping #1 +// TeX source: \long\def\@secondoftwo#1#2{#2} + +defineMacro("\\@secondoftwo", function (context) { + var args = context.consumeArgs(2); + return { + tokens: args[1], + numArgs: 0 + }; +}); // LaTeX's \@ifnextchar{#1}{#2}{#3} looks ahead to the next (unexpanded) +// symbol that isn't a space, consuming any spaces but not consuming the +// first nonspace character. If that nonspace character matches #1, then +// the macro expands to #2; otherwise, it expands to #3. + +defineMacro("\\@ifnextchar", function (context) { + var args = context.consumeArgs(3); // symbol, if, else + + context.consumeSpaces(); + var nextToken = context.future(); + + if (args[0].length === 1 && args[0][0].text === nextToken.text) { + return { + tokens: args[1], + numArgs: 0 + }; + } else { + return { + tokens: args[2], + numArgs: 0 + }; + } +}); // LaTeX's \@ifstar{#1}{#2} looks ahead to the next (unexpanded) symbol. +// If it is `*`, then it consumes the symbol, and the macro expands to #1; +// otherwise, the macro expands to #2 (without consuming the symbol). +// TeX source: \def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}} + +defineMacro("\\@ifstar", "\\@ifnextchar *{\\@firstoftwo{#1}}"); // LaTeX's \TextOrMath{#1}{#2} expands to #1 in text mode, #2 in math mode + +defineMacro("\\TextOrMath", function (context) { + var args = context.consumeArgs(2); + + if (context.mode === 'text') { + return { + tokens: args[0], + numArgs: 0 + }; + } else { + return { + tokens: args[1], + numArgs: 0 + }; + } +}); // Lookup table for parsing numbers in base 8 through 16 + +var digitToNumber = { + "0": 0, + "1": 1, + "2": 2, + "3": 3, + "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "a": 10, + "A": 10, + "b": 11, + "B": 11, + "c": 12, + "C": 12, + "d": 13, + "D": 13, + "e": 14, + "E": 14, + "f": 15, + "F": 15 +}; // TeX \char makes a literal character (catcode 12) using the following forms: +// (see The TeXBook, p. 43) +// \char123 -- decimal +// \char'123 -- octal +// \char"123 -- hex +// \char`x -- character that can be written (i.e. isn't active) +// \char`\x -- character that cannot be written (e.g. %) +// These all refer to characters from the font, so we turn them into special +// calls to a function \@char dealt with in the Parser. + +defineMacro("\\char", function (context) { + var token = context.popToken(); + var base; + var number = ''; + + if (token.text === "'") { + base = 8; + token = context.popToken(); + } else if (token.text === '"') { + base = 16; + token = context.popToken(); + } else if (token.text === "`") { + token = context.popToken(); + + if (token.text[0] === "\\") { + number = token.text.charCodeAt(1); + } else if (token.text === "EOF") { + throw new src_ParseError("\\char` missing argument"); + } else { + number = token.text.charCodeAt(0); + } + } else { + base = 10; + } + + if (base) { + // Parse a number in the given base, starting with first `token`. + number = digitToNumber[token.text]; + + if (number == null || number >= base) { + throw new src_ParseError("Invalid base-" + base + " digit " + token.text); + } + + var digit; + + while ((digit = digitToNumber[context.future().text]) != null && digit < base) { + number *= base; + number += digit; + context.popToken(); + } + } + + return "\\@char{" + number + "}"; +}); // \newcommand{\macro}[args]{definition} +// \renewcommand{\macro}[args]{definition} +// TODO: Optional arguments: \newcommand{\macro}[args][default]{definition} + +var newcommand = function newcommand(context, existsOK, nonexistsOK) { + var arg = context.consumeArg().tokens; + + if (arg.length !== 1) { + throw new src_ParseError("\\newcommand's first argument must be a macro name"); + } + + var name = arg[0].text; + var exists = context.isDefined(name); + + if (exists && !existsOK) { + throw new src_ParseError("\\newcommand{" + name + "} attempting to redefine " + (name + "; use \\renewcommand")); + } + + if (!exists && !nonexistsOK) { + throw new src_ParseError("\\renewcommand{" + name + "} when command " + name + " " + "does not yet exist; use \\newcommand"); + } + + var numArgs = 0; + arg = context.consumeArg().tokens; + + if (arg.length === 1 && arg[0].text === "[") { + var argText = ''; + var token = context.expandNextToken(); + + while (token.text !== "]" && token.text !== "EOF") { + // TODO: Should properly expand arg, e.g., ignore {}s + argText += token.text; + token = context.expandNextToken(); + } + + if (!argText.match(/^\s*[0-9]+\s*$/)) { + throw new src_ParseError("Invalid number of arguments: " + argText); + } + + numArgs = parseInt(argText); + arg = context.consumeArg().tokens; + } // Final arg is the expansion of the macro + + + context.macros.set(name, { + tokens: arg, + numArgs: numArgs + }); + return ''; +}; + +defineMacro("\\newcommand", function (context) { + return newcommand(context, false, true); +}); +defineMacro("\\renewcommand", function (context) { + return newcommand(context, true, false); +}); +defineMacro("\\providecommand", function (context) { + return newcommand(context, true, true); +}); // terminal (console) tools + +defineMacro("\\message", function (context) { + var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console + + console.log(arg.reverse().map(function (token) { + return token.text; + }).join("")); + return ''; +}); +defineMacro("\\errmessage", function (context) { + var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console + + console.error(arg.reverse().map(function (token) { + return token.text; + }).join("")); + return ''; +}); +defineMacro("\\show", function (context) { + var tok = context.popToken(); + var name = tok.text; // eslint-disable-next-line no-console + + console.log(tok, context.macros.get(name), src_functions[name], src_symbols.math[name], src_symbols.text[name]); + return ''; +}); ////////////////////////////////////////////////////////////////////// +// Grouping +// \let\bgroup={ \let\egroup=} + +defineMacro("\\bgroup", "{"); +defineMacro("\\egroup", "}"); // Symbols from latex.ltx: +// \def~{\nobreakspace{}} +// \def\lq{`} +// \def\rq{'} +// \def \aa {\r a} +// \def \AA {\r A} + +defineMacro("~", "\\nobreakspace"); +defineMacro("\\lq", "`"); +defineMacro("\\rq", "'"); +defineMacro("\\aa", "\\r a"); +defineMacro("\\AA", "\\r A"); // Copyright (C) and registered (R) symbols. Use raw symbol in MathML. +// \DeclareTextCommandDefault{\textcopyright}{\textcircled{c}} +// \DeclareTextCommandDefault{\textregistered}{\textcircled{% +// \check@mathfonts\fontsize\sf@size\z@\math@fontsfalse\selectfont R}} +// \DeclareRobustCommand{\copyright}{% +// \ifmmode{\nfss@text{\textcopyright}}\else\textcopyright\fi} + +defineMacro("\\textcopyright", "\\html@mathml{\\textcircled{c}}{\\char`©}"); +defineMacro("\\copyright", "\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"); +defineMacro("\\textregistered", "\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}"); // Characters omitted from Unicode range 1D400–1D7FF + +defineMacro("\u212C", "\\mathscr{B}"); // script + +defineMacro("\u2130", "\\mathscr{E}"); +defineMacro("\u2131", "\\mathscr{F}"); +defineMacro("\u210B", "\\mathscr{H}"); +defineMacro("\u2110", "\\mathscr{I}"); +defineMacro("\u2112", "\\mathscr{L}"); +defineMacro("\u2133", "\\mathscr{M}"); +defineMacro("\u211B", "\\mathscr{R}"); +defineMacro("\u212D", "\\mathfrak{C}"); // Fraktur + +defineMacro("\u210C", "\\mathfrak{H}"); +defineMacro("\u2128", "\\mathfrak{Z}"); // Define \Bbbk with a macro that works in both HTML and MathML. + +defineMacro("\\Bbbk", "\\Bbb{k}"); // Unicode middle dot +// The KaTeX fonts do not contain U+00B7. Instead, \cdotp displays +// the dot at U+22C5 and gives it punct spacing. + +defineMacro("\xB7", "\\cdotp"); // \llap and \rlap render their contents in text mode + +defineMacro("\\llap", "\\mathllap{\\textrm{#1}}"); +defineMacro("\\rlap", "\\mathrlap{\\textrm{#1}}"); +defineMacro("\\clap", "\\mathclap{\\textrm{#1}}"); // \mathstrut from the TeXbook, p 360 + +defineMacro("\\mathstrut", "\\vphantom{(}"); // \underbar from TeXbook p 353 + +defineMacro("\\underbar", "\\underline{\\text{#1}}"); // \not is defined by base/fontmath.ltx via +// \DeclareMathSymbol{\not}{\mathrel}{symbols}{"36} +// It's thus treated like a \mathrel, but defined by a symbol that has zero +// width but extends to the right. We use \rlap to get that spacing. +// For MathML we write U+0338 here. buildMathML.js will then do the overlay. + +defineMacro("\\not", '\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'); // Negated symbols from base/fontmath.ltx: +// \def\neq{\not=} \let\ne=\neq +// \DeclareRobustCommand +// \notin{\mathrel{\m@th\mathpalette\c@ncel\in}} +// \def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}} + +defineMacro("\\neq", "\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`≠}}"); +defineMacro("\\ne", "\\neq"); +defineMacro("\u2260", "\\neq"); +defineMacro("\\notin", "\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}" + "{\\mathrel{\\char`∉}}"); +defineMacro("\u2209", "\\notin"); // Unicode stacked relations + +defineMacro("\u2258", "\\html@mathml{" + "\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}" + "}{\\mathrel{\\char`\u2258}}"); +defineMacro("\u2259", "\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"); +defineMacro("\u225A", "\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}"); +defineMacro("\u225B", "\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}" + "{\\mathrel{\\char`\u225B}}"); +defineMacro("\u225D", "\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}" + "{\\mathrel{\\char`\u225D}}"); +defineMacro("\u225E", "\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}" + "{\\mathrel{\\char`\u225E}}"); +defineMacro("\u225F", "\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}"); // Misc Unicode + +defineMacro("\u27C2", "\\perp"); +defineMacro("\u203C", "\\mathclose{!\\mkern-0.8mu!}"); +defineMacro("\u220C", "\\notni"); +defineMacro("\u231C", "\\ulcorner"); +defineMacro("\u231D", "\\urcorner"); +defineMacro("\u231E", "\\llcorner"); +defineMacro("\u231F", "\\lrcorner"); +defineMacro("\xA9", "\\copyright"); +defineMacro("\xAE", "\\textregistered"); +defineMacro("\uFE0F", "\\textregistered"); // The KaTeX fonts have corners at codepoints that don't match Unicode. +// For MathML purposes, use the Unicode code point. + +defineMacro("\\ulcorner", "\\html@mathml{\\@ulcorner}{\\mathop{\\char\"231c}}"); +defineMacro("\\urcorner", "\\html@mathml{\\@urcorner}{\\mathop{\\char\"231d}}"); +defineMacro("\\llcorner", "\\html@mathml{\\@llcorner}{\\mathop{\\char\"231e}}"); +defineMacro("\\lrcorner", "\\html@mathml{\\@lrcorner}{\\mathop{\\char\"231f}}"); ////////////////////////////////////////////////////////////////////// +// LaTeX_2ε +// \vdots{\vbox{\baselineskip4\p@ \lineskiplimit\z@ +// \kern6\p@\hbox{.}\hbox{.}\hbox{.}}} +// We'll call \varvdots, which gets a glyph from symbols.js. +// The zero-width rule gets us an equivalent to the vertical 6pt kern. + +defineMacro("\\vdots", "\\mathord{\\varvdots\\rule{0pt}{15pt}}"); +defineMacro("\u22EE", "\\vdots"); ////////////////////////////////////////////////////////////////////// +// amsmath.sty +// http://mirrors.concertpass.com/tex-archive/macros/latex/required/amsmath/amsmath.pdf +// Italic Greek capital letters. AMS defines these with \DeclareMathSymbol, +// but they are equivalent to \mathit{\Letter}. + +defineMacro("\\varGamma", "\\mathit{\\Gamma}"); +defineMacro("\\varDelta", "\\mathit{\\Delta}"); +defineMacro("\\varTheta", "\\mathit{\\Theta}"); +defineMacro("\\varLambda", "\\mathit{\\Lambda}"); +defineMacro("\\varXi", "\\mathit{\\Xi}"); +defineMacro("\\varPi", "\\mathit{\\Pi}"); +defineMacro("\\varSigma", "\\mathit{\\Sigma}"); +defineMacro("\\varUpsilon", "\\mathit{\\Upsilon}"); +defineMacro("\\varPhi", "\\mathit{\\Phi}"); +defineMacro("\\varPsi", "\\mathit{\\Psi}"); +defineMacro("\\varOmega", "\\mathit{\\Omega}"); //\newcommand{\substack}[1]{\subarray{c}#1\endsubarray} + +defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}"); // \renewcommand{\colon}{\nobreak\mskip2mu\mathpunct{}\nonscript +// \mkern-\thinmuskip{:}\mskip6muplus1mu\relax} + +defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" + "\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu"); // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} + +defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}"); // \def\iff{\DOTSB\;\Longleftrightarrow\;} +// \def\implies{\DOTSB\;\Longrightarrow\;} +// \def\impliedby{\DOTSB\;\Longleftarrow\;} + +defineMacro("\\iff", "\\DOTSB\\;\\Longleftrightarrow\\;"); +defineMacro("\\implies", "\\DOTSB\\;\\Longrightarrow\\;"); +defineMacro("\\impliedby", "\\DOTSB\\;\\Longleftarrow\\;"); // AMSMath's automatic \dots, based on \mdots@@ macro. + +var dotsByToken = { + ',': '\\dotsc', + '\\not': '\\dotsb', + // \keybin@ checks for the following: + '+': '\\dotsb', + '=': '\\dotsb', + '<': '\\dotsb', + '>': '\\dotsb', + '-': '\\dotsb', + '*': '\\dotsb', + ':': '\\dotsb', + // Symbols whose definition starts with \DOTSB: + '\\DOTSB': '\\dotsb', + '\\coprod': '\\dotsb', + '\\bigvee': '\\dotsb', + '\\bigwedge': '\\dotsb', + '\\biguplus': '\\dotsb', + '\\bigcap': '\\dotsb', + '\\bigcup': '\\dotsb', + '\\prod': '\\dotsb', + '\\sum': '\\dotsb', + '\\bigotimes': '\\dotsb', + '\\bigoplus': '\\dotsb', + '\\bigodot': '\\dotsb', + '\\bigsqcup': '\\dotsb', + '\\And': '\\dotsb', + '\\longrightarrow': '\\dotsb', + '\\Longrightarrow': '\\dotsb', + '\\longleftarrow': '\\dotsb', + '\\Longleftarrow': '\\dotsb', + '\\longleftrightarrow': '\\dotsb', + '\\Longleftrightarrow': '\\dotsb', + '\\mapsto': '\\dotsb', + '\\longmapsto': '\\dotsb', + '\\hookrightarrow': '\\dotsb', + '\\doteq': '\\dotsb', + // Symbols whose definition starts with \mathbin: + '\\mathbin': '\\dotsb', + // Symbols whose definition starts with \mathrel: + '\\mathrel': '\\dotsb', + '\\relbar': '\\dotsb', + '\\Relbar': '\\dotsb', + '\\xrightarrow': '\\dotsb', + '\\xleftarrow': '\\dotsb', + // Symbols whose definition starts with \DOTSI: + '\\DOTSI': '\\dotsi', + '\\int': '\\dotsi', + '\\oint': '\\dotsi', + '\\iint': '\\dotsi', + '\\iiint': '\\dotsi', + '\\iiiint': '\\dotsi', + '\\idotsint': '\\dotsi', + // Symbols whose definition starts with \DOTSX: + '\\DOTSX': '\\dotsx' +}; +defineMacro("\\dots", function (context) { + // TODO: If used in text mode, should expand to \textellipsis. + // However, in KaTeX, \textellipsis and \ldots behave the same + // (in text mode), and it's unlikely we'd see any of the math commands + // that affect the behavior of \dots when in text mode. So fine for now + // (until we support \ifmmode ... \else ... \fi). + var thedots = '\\dotso'; + var next = context.expandAfterFuture().text; + + if (next in dotsByToken) { + thedots = dotsByToken[next]; + } else if (next.substr(0, 4) === '\\not') { + thedots = '\\dotsb'; + } else if (next in src_symbols.math) { + if (utils.contains(['bin', 'rel'], src_symbols.math[next].group)) { + thedots = '\\dotsb'; + } + } + + return thedots; +}); +var spaceAfterDots = { + // \rightdelim@ checks for the following: + ')': true, + ']': true, + '\\rbrack': true, + '\\}': true, + '\\rbrace': true, + '\\rangle': true, + '\\rceil': true, + '\\rfloor': true, + '\\rgroup': true, + '\\rmoustache': true, + '\\right': true, + '\\bigr': true, + '\\biggr': true, + '\\Bigr': true, + '\\Biggr': true, + // \extra@ also tests for the following: + '$': true, + // \extrap@ checks for the following: + ';': true, + '.': true, + ',': true +}; +defineMacro("\\dotso", function (context) { + var next = context.future().text; + + if (next in spaceAfterDots) { + return "\\ldots\\,"; + } else { + return "\\ldots"; + } +}); +defineMacro("\\dotsc", function (context) { + var next = context.future().text; // \dotsc uses \extra@ but not \extrap@, instead specially checking for + // ';' and '.', but doesn't check for ','. + + if (next in spaceAfterDots && next !== ',') { + return "\\ldots\\,"; + } else { + return "\\ldots"; + } +}); +defineMacro("\\cdots", function (context) { + var next = context.future().text; + + if (next in spaceAfterDots) { + return "\\@cdots\\,"; + } else { + return "\\@cdots"; + } +}); +defineMacro("\\dotsb", "\\cdots"); +defineMacro("\\dotsm", "\\cdots"); +defineMacro("\\dotsi", "\\!\\cdots"); // amsmath doesn't actually define \dotsx, but \dots followed by a macro +// starting with \DOTSX implies \dotso, and then \extra@ detects this case +// and forces the added `\,`. + +defineMacro("\\dotsx", "\\ldots\\,"); // \let\DOTSI\relax +// \let\DOTSB\relax +// \let\DOTSX\relax + +defineMacro("\\DOTSI", "\\relax"); +defineMacro("\\DOTSB", "\\relax"); +defineMacro("\\DOTSX", "\\relax"); // Spacing, based on amsmath.sty's override of LaTeX defaults +// \DeclareRobustCommand{\tmspace}[3]{% +// \ifmmode\mskip#1#2\else\kern#1#3\fi\relax} + +defineMacro("\\tmspace", "\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"); // \renewcommand{\,}{\tmspace+\thinmuskip{.1667em}} +// TODO: math mode should use \thinmuskip + +defineMacro("\\,", "\\tmspace+{3mu}{.1667em}"); // \let\thinspace\, + +defineMacro("\\thinspace", "\\,"); // \def\>{\mskip\medmuskip} +// \renewcommand{\:}{\tmspace+\medmuskip{.2222em}} +// TODO: \> and math mode of \: should use \medmuskip = 4mu plus 2mu minus 4mu + +defineMacro("\\>", "\\mskip{4mu}"); +defineMacro("\\:", "\\tmspace+{4mu}{.2222em}"); // \let\medspace\: + +defineMacro("\\medspace", "\\:"); // \renewcommand{\;}{\tmspace+\thickmuskip{.2777em}} +// TODO: math mode should use \thickmuskip = 5mu plus 5mu + +defineMacro("\\;", "\\tmspace+{5mu}{.2777em}"); // \let\thickspace\; + +defineMacro("\\thickspace", "\\;"); // \renewcommand{\!}{\tmspace-\thinmuskip{.1667em}} +// TODO: math mode should use \thinmuskip + +defineMacro("\\!", "\\tmspace-{3mu}{.1667em}"); // \let\negthinspace\! + +defineMacro("\\negthinspace", "\\!"); // \newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}} +// TODO: math mode should use \medmuskip + +defineMacro("\\negmedspace", "\\tmspace-{4mu}{.2222em}"); // \newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}} +// TODO: math mode should use \thickmuskip + +defineMacro("\\negthickspace", "\\tmspace-{5mu}{.277em}"); // \def\enspace{\kern.5em } + +defineMacro("\\enspace", "\\kern.5em "); // \def\enskip{\hskip.5em\relax} + +defineMacro("\\enskip", "\\hskip.5em\\relax"); // \def\quad{\hskip1em\relax} + +defineMacro("\\quad", "\\hskip1em\\relax"); // \def\qquad{\hskip2em\relax} + +defineMacro("\\qquad", "\\hskip2em\\relax"); // \tag@in@display form of \tag + +defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren"); +defineMacro("\\tag@paren", "\\tag@literal{({#1})}"); +defineMacro("\\tag@literal", function (context) { + if (context.macros.get("\\df@tag")) { + throw new src_ParseError("Multiple \\tag"); + } + + return "\\gdef\\df@tag{\\text{#1}}"; +}); // \renewcommand{\bmod}{\nonscript\mskip-\medmuskip\mkern5mu\mathbin +// {\operator@font mod}\penalty900 +// \mkern5mu\nonscript\mskip-\medmuskip} +// \newcommand{\pod}[1]{\allowbreak +// \if@display\mkern18mu\else\mkern8mu\fi(#1)} +// \renewcommand{\pmod}[1]{\pod{{\operator@font mod}\mkern6mu#1}} +// \newcommand{\mod}[1]{\allowbreak\if@display\mkern18mu +// \else\mkern12mu\fi{\operator@font mod}\,\,#1} +// TODO: math mode should use \medmuskip = 4mu plus 2mu minus 4mu + +defineMacro("\\bmod", "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}" + "\\mathbin{\\rm mod}" + "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"); +defineMacro("\\pod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"); +defineMacro("\\pmod", "\\pod{{\\rm mod}\\mkern6mu#1}"); +defineMacro("\\mod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}" + "{\\rm mod}\\,\\,#1"); // \pmb -- A simulation of bold. +// The version in ambsy.sty works by typesetting three copies of the argument +// with small offsets. We use two copies. We omit the vertical offset because +// of rendering problems that makeVList encounters in Safari. + +defineMacro("\\pmb", "\\html@mathml{" + "\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}" + "{\\mathbf{#1}}"); ////////////////////////////////////////////////////////////////////// +// LaTeX source2e +// \expandafter\let\expandafter\@normalcr +// \csname\expandafter\@gobble\string\\ \endcsname +// \DeclareRobustCommand\newline{\@normalcr\relax} + +defineMacro("\\newline", "\\\\\\relax"); // \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@} +// TODO: Doesn't normally work in math mode because \@ fails. KaTeX doesn't +// support \@ yet, so that's omitted, and we add \text so that the result +// doesn't look funny in math mode. + +defineMacro("\\TeX", "\\textrm{\\html@mathml{" + "T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX" + "}{TeX}}"); // \DeclareRobustCommand{\LaTeX}{L\kern-.36em% +// {\sbox\z@ T% +// \vbox to\ht\z@{\hbox{\check@mathfonts +// \fontsize\sf@size\z@ +// \math@fontsfalse\selectfont +// A}% +// \vss}% +// }% +// \kern-.15em% +// \TeX} +// This code aligns the top of the A with the T (from the perspective of TeX's +// boxes, though visually the A appears to extend above slightly). +// We compute the corresponding \raisebox when A is rendered in \normalsize +// \scriptstyle, which has a scale factor of 0.7 (see Options.js). + +var latexRaiseA = makeEm(fontMetricsData["Main-Regular"]["T".charCodeAt(0)][1] - 0.7 * fontMetricsData["Main-Regular"]["A".charCodeAt(0)][1]); +defineMacro("\\LaTeX", "\\textrm{\\html@mathml{" + ("L\\kern-.36em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{LaTeX}}"); // New KaTeX logo based on tweaking LaTeX logo + +defineMacro("\\KaTeX", "\\textrm{\\html@mathml{" + ("K\\kern-.17em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{KaTeX}}"); // \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace} +// \def\@hspace#1{\hskip #1\relax} +// \def\@hspacer#1{\vrule \@width\z@\nobreak +// \hskip #1\hskip \z@skip} + +defineMacro("\\hspace", "\\@ifstar\\@hspacer\\@hspace"); +defineMacro("\\@hspace", "\\hskip #1\\relax"); +defineMacro("\\@hspacer", "\\rule{0pt}{0pt}\\hskip #1\\relax"); ////////////////////////////////////////////////////////////////////// +// mathtools.sty +//\providecommand\ordinarycolon{:} + +defineMacro("\\ordinarycolon", ":"); //\def\vcentcolon{\mathrel{\mathop\ordinarycolon}} +//TODO(edemaine): Not yet centered. Fix via \raisebox or #726 + +defineMacro("\\vcentcolon", "\\mathrel{\\mathop\\ordinarycolon}"); // \providecommand*\dblcolon{\vcentcolon\mathrel{\mkern-.9mu}\vcentcolon} + +defineMacro("\\dblcolon", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}" + "{\\mathop{\\char\"2237}}"); // \providecommand*\coloneqq{\vcentcolon\mathrel{\mkern-1.2mu}=} + +defineMacro("\\coloneqq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2254}}"); // ≔ +// \providecommand*\Coloneqq{\dblcolon\mathrel{\mkern-1.2mu}=} + +defineMacro("\\Coloneqq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2237\\char\"3d}}"); // \providecommand*\coloneq{\vcentcolon\mathrel{\mkern-1.2mu}\mathrel{-}} + +defineMacro("\\coloneq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"3a\\char\"2212}}"); // \providecommand*\Coloneq{\dblcolon\mathrel{\mkern-1.2mu}\mathrel{-}} + +defineMacro("\\Coloneq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"2237\\char\"2212}}"); // \providecommand*\eqqcolon{=\mathrel{\mkern-1.2mu}\vcentcolon} + +defineMacro("\\eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2255}}"); // ≕ +// \providecommand*\Eqqcolon{=\mathrel{\mkern-1.2mu}\dblcolon} + +defineMacro("\\Eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"3d\\char\"2237}}"); // \providecommand*\eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\vcentcolon} + +defineMacro("\\eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2239}}"); // \providecommand*\Eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\dblcolon} + +defineMacro("\\Eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"2212\\char\"2237}}"); // \providecommand*\colonapprox{\vcentcolon\mathrel{\mkern-1.2mu}\approx} + +defineMacro("\\colonapprox", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"3a\\char\"2248}}"); // \providecommand*\Colonapprox{\dblcolon\mathrel{\mkern-1.2mu}\approx} + +defineMacro("\\Colonapprox", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"2237\\char\"2248}}"); // \providecommand*\colonsim{\vcentcolon\mathrel{\mkern-1.2mu}\sim} + +defineMacro("\\colonsim", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"3a\\char\"223c}}"); // \providecommand*\Colonsim{\dblcolon\mathrel{\mkern-1.2mu}\sim} + +defineMacro("\\Colonsim", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"2237\\char\"223c}}"); // Some Unicode characters are implemented with macros to mathtools functions. + +defineMacro("\u2237", "\\dblcolon"); // :: + +defineMacro("\u2239", "\\eqcolon"); // -: + +defineMacro("\u2254", "\\coloneqq"); // := + +defineMacro("\u2255", "\\eqqcolon"); // =: + +defineMacro("\u2A74", "\\Coloneqq"); // ::= +////////////////////////////////////////////////////////////////////// +// colonequals.sty +// Alternate names for mathtools's macros: + +defineMacro("\\ratio", "\\vcentcolon"); +defineMacro("\\coloncolon", "\\dblcolon"); +defineMacro("\\colonequals", "\\coloneqq"); +defineMacro("\\coloncolonequals", "\\Coloneqq"); +defineMacro("\\equalscolon", "\\eqqcolon"); +defineMacro("\\equalscoloncolon", "\\Eqqcolon"); +defineMacro("\\colonminus", "\\coloneq"); +defineMacro("\\coloncolonminus", "\\Coloneq"); +defineMacro("\\minuscolon", "\\eqcolon"); +defineMacro("\\minuscoloncolon", "\\Eqcolon"); // \colonapprox name is same in mathtools and colonequals. + +defineMacro("\\coloncolonapprox", "\\Colonapprox"); // \colonsim name is same in mathtools and colonequals. + +defineMacro("\\coloncolonsim", "\\Colonsim"); // Additional macros, implemented by analogy with mathtools definitions: + +defineMacro("\\simcolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"); +defineMacro("\\simcoloncolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"); +defineMacro("\\approxcolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"); +defineMacro("\\approxcoloncolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"); // Present in newtxmath, pxfonts and txfonts + +defineMacro("\\notni", "\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}"); +defineMacro("\\limsup", "\\DOTSB\\operatorname*{lim\\,sup}"); +defineMacro("\\liminf", "\\DOTSB\\operatorname*{lim\\,inf}"); ////////////////////////////////////////////////////////////////////// +// From amsopn.sty + +defineMacro("\\injlim", "\\DOTSB\\operatorname*{inj\\,lim}"); +defineMacro("\\projlim", "\\DOTSB\\operatorname*{proj\\,lim}"); +defineMacro("\\varlimsup", "\\DOTSB\\operatorname*{\\overline{lim}}"); +defineMacro("\\varliminf", "\\DOTSB\\operatorname*{\\underline{lim}}"); +defineMacro("\\varinjlim", "\\DOTSB\\operatorname*{\\underrightarrow{lim}}"); +defineMacro("\\varprojlim", "\\DOTSB\\operatorname*{\\underleftarrow{lim}}"); ////////////////////////////////////////////////////////////////////// +// MathML alternates for KaTeX glyphs in the Unicode private area + +defineMacro("\\gvertneqq", "\\html@mathml{\\@gvertneqq}{\u2269}"); +defineMacro("\\lvertneqq", "\\html@mathml{\\@lvertneqq}{\u2268}"); +defineMacro("\\ngeqq", "\\html@mathml{\\@ngeqq}{\u2271}"); +defineMacro("\\ngeqslant", "\\html@mathml{\\@ngeqslant}{\u2271}"); +defineMacro("\\nleqq", "\\html@mathml{\\@nleqq}{\u2270}"); +defineMacro("\\nleqslant", "\\html@mathml{\\@nleqslant}{\u2270}"); +defineMacro("\\nshortmid", "\\html@mathml{\\@nshortmid}{∤}"); +defineMacro("\\nshortparallel", "\\html@mathml{\\@nshortparallel}{∦}"); +defineMacro("\\nsubseteqq", "\\html@mathml{\\@nsubseteqq}{\u2288}"); +defineMacro("\\nsupseteqq", "\\html@mathml{\\@nsupseteqq}{\u2289}"); +defineMacro("\\varsubsetneq", "\\html@mathml{\\@varsubsetneq}{⊊}"); +defineMacro("\\varsubsetneqq", "\\html@mathml{\\@varsubsetneqq}{⫋}"); +defineMacro("\\varsupsetneq", "\\html@mathml{\\@varsupsetneq}{⊋}"); +defineMacro("\\varsupsetneqq", "\\html@mathml{\\@varsupsetneqq}{⫌}"); +defineMacro("\\imath", "\\html@mathml{\\@imath}{\u0131}"); +defineMacro("\\jmath", "\\html@mathml{\\@jmath}{\u0237}"); ////////////////////////////////////////////////////////////////////// +// stmaryrd and semantic +// The stmaryrd and semantic packages render the next four items by calling a +// glyph. Those glyphs do not exist in the KaTeX fonts. Hence the macros. + +defineMacro("\\llbracket", "\\html@mathml{" + "\\mathopen{[\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u27E6}}"); +defineMacro("\\rrbracket", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu]}}" + "{\\mathclose{\\char`\u27E7}}"); +defineMacro("\u27E6", "\\llbracket"); // blackboard bold [ + +defineMacro("\u27E7", "\\rrbracket"); // blackboard bold ] + +defineMacro("\\lBrace", "\\html@mathml{" + "\\mathopen{\\{\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u2983}}"); +defineMacro("\\rBrace", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu\\}}}" + "{\\mathclose{\\char`\u2984}}"); +defineMacro("\u2983", "\\lBrace"); // blackboard bold { + +defineMacro("\u2984", "\\rBrace"); // blackboard bold } +// TODO: Create variable sized versions of the last two items. I believe that +// will require new font glyphs. +// The stmaryrd function `\minuso` provides a "Plimsoll" symbol that +// superimposes the characters \circ and \mathminus. Used in chemistry. + +defineMacro("\\minuso", "\\mathbin{\\html@mathml{" + "{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}" + "{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}" + "{\\char`⦵}}"); +defineMacro("⦵", "\\minuso"); ////////////////////////////////////////////////////////////////////// +// texvc.sty +// The texvc package contains macros available in mediawiki pages. +// We omit the functions deprecated at +// https://en.wikipedia.org/wiki/Help:Displaying_a_formula#Deprecated_syntax +// We also omit texvc's \O, which conflicts with \text{\O} + +defineMacro("\\darr", "\\downarrow"); +defineMacro("\\dArr", "\\Downarrow"); +defineMacro("\\Darr", "\\Downarrow"); +defineMacro("\\lang", "\\langle"); +defineMacro("\\rang", "\\rangle"); +defineMacro("\\uarr", "\\uparrow"); +defineMacro("\\uArr", "\\Uparrow"); +defineMacro("\\Uarr", "\\Uparrow"); +defineMacro("\\N", "\\mathbb{N}"); +defineMacro("\\R", "\\mathbb{R}"); +defineMacro("\\Z", "\\mathbb{Z}"); +defineMacro("\\alef", "\\aleph"); +defineMacro("\\alefsym", "\\aleph"); +defineMacro("\\Alpha", "\\mathrm{A}"); +defineMacro("\\Beta", "\\mathrm{B}"); +defineMacro("\\bull", "\\bullet"); +defineMacro("\\Chi", "\\mathrm{X}"); +defineMacro("\\clubs", "\\clubsuit"); +defineMacro("\\cnums", "\\mathbb{C}"); +defineMacro("\\Complex", "\\mathbb{C}"); +defineMacro("\\Dagger", "\\ddagger"); +defineMacro("\\diamonds", "\\diamondsuit"); +defineMacro("\\empty", "\\emptyset"); +defineMacro("\\Epsilon", "\\mathrm{E}"); +defineMacro("\\Eta", "\\mathrm{H}"); +defineMacro("\\exist", "\\exists"); +defineMacro("\\harr", "\\leftrightarrow"); +defineMacro("\\hArr", "\\Leftrightarrow"); +defineMacro("\\Harr", "\\Leftrightarrow"); +defineMacro("\\hearts", "\\heartsuit"); +defineMacro("\\image", "\\Im"); +defineMacro("\\infin", "\\infty"); +defineMacro("\\Iota", "\\mathrm{I}"); +defineMacro("\\isin", "\\in"); +defineMacro("\\Kappa", "\\mathrm{K}"); +defineMacro("\\larr", "\\leftarrow"); +defineMacro("\\lArr", "\\Leftarrow"); +defineMacro("\\Larr", "\\Leftarrow"); +defineMacro("\\lrarr", "\\leftrightarrow"); +defineMacro("\\lrArr", "\\Leftrightarrow"); +defineMacro("\\Lrarr", "\\Leftrightarrow"); +defineMacro("\\Mu", "\\mathrm{M}"); +defineMacro("\\natnums", "\\mathbb{N}"); +defineMacro("\\Nu", "\\mathrm{N}"); +defineMacro("\\Omicron", "\\mathrm{O}"); +defineMacro("\\plusmn", "\\pm"); +defineMacro("\\rarr", "\\rightarrow"); +defineMacro("\\rArr", "\\Rightarrow"); +defineMacro("\\Rarr", "\\Rightarrow"); +defineMacro("\\real", "\\Re"); +defineMacro("\\reals", "\\mathbb{R}"); +defineMacro("\\Reals", "\\mathbb{R}"); +defineMacro("\\Rho", "\\mathrm{P}"); +defineMacro("\\sdot", "\\cdot"); +defineMacro("\\sect", "\\S"); +defineMacro("\\spades", "\\spadesuit"); +defineMacro("\\sub", "\\subset"); +defineMacro("\\sube", "\\subseteq"); +defineMacro("\\supe", "\\supseteq"); +defineMacro("\\Tau", "\\mathrm{T}"); +defineMacro("\\thetasym", "\\vartheta"); // TODO: defineMacro("\\varcoppa", "\\\mbox{\\coppa}"); + +defineMacro("\\weierp", "\\wp"); +defineMacro("\\Zeta", "\\mathrm{Z}"); ////////////////////////////////////////////////////////////////////// +// statmath.sty +// https://ctan.math.illinois.edu/macros/latex/contrib/statmath/statmath.pdf + +defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}"); +defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}"); +defineMacro("\\plim", "\\DOTSB\\mathop{\\operatorname{plim}}\\limits"); ////////////////////////////////////////////////////////////////////// +// braket.sty +// http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf + +defineMacro("\\bra", "\\mathinner{\\langle{#1}|}"); +defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}"); +defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}"); +defineMacro("\\Bra", "\\left\\langle#1\\right|"); +defineMacro("\\Ket", "\\left|#1\\right\\rangle"); ////////////////////////////////////////////////////////////////////// +// actuarialangle.dtx + +defineMacro("\\angln", "{\\angl n}"); // Custom Khan Academy colors, should be moved to an optional package + +defineMacro("\\blue", "\\textcolor{##6495ed}{#1}"); +defineMacro("\\orange", "\\textcolor{##ffa500}{#1}"); +defineMacro("\\pink", "\\textcolor{##ff00af}{#1}"); +defineMacro("\\red", "\\textcolor{##df0030}{#1}"); +defineMacro("\\green", "\\textcolor{##28ae7b}{#1}"); +defineMacro("\\gray", "\\textcolor{gray}{#1}"); +defineMacro("\\purple", "\\textcolor{##9d38bd}{#1}"); +defineMacro("\\blueA", "\\textcolor{##ccfaff}{#1}"); +defineMacro("\\blueB", "\\textcolor{##80f6ff}{#1}"); +defineMacro("\\blueC", "\\textcolor{##63d9ea}{#1}"); +defineMacro("\\blueD", "\\textcolor{##11accd}{#1}"); +defineMacro("\\blueE", "\\textcolor{##0c7f99}{#1}"); +defineMacro("\\tealA", "\\textcolor{##94fff5}{#1}"); +defineMacro("\\tealB", "\\textcolor{##26edd5}{#1}"); +defineMacro("\\tealC", "\\textcolor{##01d1c1}{#1}"); +defineMacro("\\tealD", "\\textcolor{##01a995}{#1}"); +defineMacro("\\tealE", "\\textcolor{##208170}{#1}"); +defineMacro("\\greenA", "\\textcolor{##b6ffb0}{#1}"); +defineMacro("\\greenB", "\\textcolor{##8af281}{#1}"); +defineMacro("\\greenC", "\\textcolor{##74cf70}{#1}"); +defineMacro("\\greenD", "\\textcolor{##1fab54}{#1}"); +defineMacro("\\greenE", "\\textcolor{##0d923f}{#1}"); +defineMacro("\\goldA", "\\textcolor{##ffd0a9}{#1}"); +defineMacro("\\goldB", "\\textcolor{##ffbb71}{#1}"); +defineMacro("\\goldC", "\\textcolor{##ff9c39}{#1}"); +defineMacro("\\goldD", "\\textcolor{##e07d10}{#1}"); +defineMacro("\\goldE", "\\textcolor{##a75a05}{#1}"); +defineMacro("\\redA", "\\textcolor{##fca9a9}{#1}"); +defineMacro("\\redB", "\\textcolor{##ff8482}{#1}"); +defineMacro("\\redC", "\\textcolor{##f9685d}{#1}"); +defineMacro("\\redD", "\\textcolor{##e84d39}{#1}"); +defineMacro("\\redE", "\\textcolor{##bc2612}{#1}"); +defineMacro("\\maroonA", "\\textcolor{##ffbde0}{#1}"); +defineMacro("\\maroonB", "\\textcolor{##ff92c6}{#1}"); +defineMacro("\\maroonC", "\\textcolor{##ed5fa6}{#1}"); +defineMacro("\\maroonD", "\\textcolor{##ca337c}{#1}"); +defineMacro("\\maroonE", "\\textcolor{##9e034e}{#1}"); +defineMacro("\\purpleA", "\\textcolor{##ddd7ff}{#1}"); +defineMacro("\\purpleB", "\\textcolor{##c6b9fc}{#1}"); +defineMacro("\\purpleC", "\\textcolor{##aa87ff}{#1}"); +defineMacro("\\purpleD", "\\textcolor{##7854ab}{#1}"); +defineMacro("\\purpleE", "\\textcolor{##543b78}{#1}"); +defineMacro("\\mintA", "\\textcolor{##f5f9e8}{#1}"); +defineMacro("\\mintB", "\\textcolor{##edf2df}{#1}"); +defineMacro("\\mintC", "\\textcolor{##e0e5cc}{#1}"); +defineMacro("\\grayA", "\\textcolor{##f6f7f7}{#1}"); +defineMacro("\\grayB", "\\textcolor{##f0f1f2}{#1}"); +defineMacro("\\grayC", "\\textcolor{##e3e5e6}{#1}"); +defineMacro("\\grayD", "\\textcolor{##d6d8da}{#1}"); +defineMacro("\\grayE", "\\textcolor{##babec2}{#1}"); +defineMacro("\\grayF", "\\textcolor{##888d93}{#1}"); +defineMacro("\\grayG", "\\textcolor{##626569}{#1}"); +defineMacro("\\grayH", "\\textcolor{##3b3e40}{#1}"); +defineMacro("\\grayI", "\\textcolor{##21242c}{#1}"); +defineMacro("\\kaBlue", "\\textcolor{##314453}{#1}"); +defineMacro("\\kaGreen", "\\textcolor{##71B307}{#1}"); +/** + * This file contains the “gullet” where macros are expanded + * until only non-macro tokens remain. + */ + + + + + + + +// List of commands that act like macros but aren't defined as a macro, +// function, or symbol. Used in `isDefined`. +var implicitCommands = { + "\\relax": true, + // MacroExpander.js + "^": true, + // Parser.js + "_": true, + // Parser.js + "\\limits": true, + // Parser.js + "\\nolimits": true // Parser.js + +}; + +var MacroExpander = /*#__PURE__*/function () { + function MacroExpander(input, settings, mode) { + this.settings = void 0; + this.expansionCount = void 0; + this.lexer = void 0; + this.macros = void 0; + this.stack = void 0; + this.mode = void 0; + this.settings = settings; + this.expansionCount = 0; + this.feed(input); // Make new global namespace + + this.macros = new Namespace(src_macros, settings.macros); + this.mode = mode; + this.stack = []; // contains tokens in REVERSE order + } + /** + * Feed a new input string to the same MacroExpander + * (with existing macros etc.). + */ + + + var _proto = MacroExpander.prototype; + + _proto.feed = function feed(input) { + this.lexer = new Lexer(input, this.settings); + } + /** + * Switches between "text" and "math" modes. + */ + ; + + _proto.switchMode = function switchMode(newMode) { + this.mode = newMode; + } + /** + * Start a new group nesting within all namespaces. + */ + ; + + _proto.beginGroup = function beginGroup() { + this.macros.beginGroup(); + } + /** + * End current group nesting within all namespaces. + */ + ; + + _proto.endGroup = function endGroup() { + this.macros.endGroup(); + } + /** + * Ends all currently nested groups (if any), restoring values before the + * groups began. Useful in case of an error in the middle of parsing. + */ + ; + + _proto.endGroups = function endGroups() { + this.macros.endGroups(); + } + /** + * Returns the topmost token on the stack, without expanding it. + * Similar in behavior to TeX's `\futurelet`. + */ + ; + + _proto.future = function future() { + if (this.stack.length === 0) { + this.pushToken(this.lexer.lex()); + } + + return this.stack[this.stack.length - 1]; + } + /** + * Remove and return the next unexpanded token. + */ + ; + + _proto.popToken = function popToken() { + this.future(); // ensure non-empty stack + + return this.stack.pop(); + } + /** + * Add a given token to the token stack. In particular, this get be used + * to put back a token returned from one of the other methods. + */ + ; + + _proto.pushToken = function pushToken(token) { + this.stack.push(token); + } + /** + * Append an array of tokens to the token stack. + */ + ; + + _proto.pushTokens = function pushTokens(tokens) { + var _this$stack; + + (_this$stack = this.stack).push.apply(_this$stack, tokens); + } + /** + * Find an macro argument without expanding tokens and append the array of + * tokens to the token stack. Uses Token as a container for the result. + */ + ; + + _proto.scanArgument = function scanArgument(isOptional) { + var start; + var end; + var tokens; + + if (isOptional) { + this.consumeSpaces(); // \@ifnextchar gobbles any space following it + + if (this.future().text !== "[") { + return null; + } + + start = this.popToken(); // don't include [ in tokens + + var _this$consumeArg = this.consumeArg(["]"]); + + tokens = _this$consumeArg.tokens; + end = _this$consumeArg.end; + } else { + var _this$consumeArg2 = this.consumeArg(); + + tokens = _this$consumeArg2.tokens; + start = _this$consumeArg2.start; + end = _this$consumeArg2.end; + } // indicate the end of an argument + + + this.pushToken(new Token("EOF", end.loc)); + this.pushTokens(tokens); + return start.range(end, ""); + } + /** + * Consume all following space tokens, without expansion. + */ + ; + + _proto.consumeSpaces = function consumeSpaces() { + for (;;) { + var token = this.future(); + + if (token.text === " ") { + this.stack.pop(); + } else { + break; + } + } + } + /** + * Consume an argument from the token stream, and return the resulting array + * of tokens and start/end token. + */ + ; + + _proto.consumeArg = function consumeArg(delims) { + // The argument for a delimited parameter is the shortest (possibly + // empty) sequence of tokens with properly nested {...} groups that is + // followed ... by this particular list of non-parameter tokens. + // The argument for an undelimited parameter is the next nonblank + // token, unless that token is ‘{’, when the argument will be the + // entire {...} group that follows. + var tokens = []; + var isDelimited = delims && delims.length > 0; + + if (!isDelimited) { + // Ignore spaces between arguments. As the TeXbook says: + // "After you have said ‘\def\row#1#2{...}’, you are allowed to + // put spaces between the arguments (e.g., ‘\row x n’), because + // TeX doesn’t use single spaces as undelimited arguments." + this.consumeSpaces(); + } + + var start = this.future(); + var tok; + var depth = 0; + var match = 0; + + do { + tok = this.popToken(); + tokens.push(tok); + + if (tok.text === "{") { + ++depth; + } else if (tok.text === "}") { + --depth; + + if (depth === -1) { + throw new src_ParseError("Extra }", tok); + } + } else if (tok.text === "EOF") { + throw new src_ParseError("Unexpected end of input in a macro argument" + ", expected '" + (delims && isDelimited ? delims[match] : "}") + "'", tok); + } + + if (delims && isDelimited) { + if ((depth === 0 || depth === 1 && delims[match] === "{") && tok.text === delims[match]) { + ++match; + + if (match === delims.length) { + // don't include delims in tokens + tokens.splice(-match, match); + break; + } + } else { + match = 0; + } + } + } while (depth !== 0 || isDelimited); // If the argument found ... has the form ‘{}’, + // ... the outermost braces enclosing the argument are removed + + + if (start.text === "{" && tokens[tokens.length - 1].text === "}") { + tokens.pop(); + tokens.shift(); + } + + tokens.reverse(); // to fit in with stack order + + return { + tokens: tokens, + start: start, + end: tok + }; + } + /** + * Consume the specified number of (delimited) arguments from the token + * stream and return the resulting array of arguments. + */ + ; + + _proto.consumeArgs = function consumeArgs(numArgs, delimiters) { + if (delimiters) { + if (delimiters.length !== numArgs + 1) { + throw new src_ParseError("The length of delimiters doesn't match the number of args!"); + } + + var delims = delimiters[0]; + + for (var i = 0; i < delims.length; i++) { + var tok = this.popToken(); + + if (delims[i] !== tok.text) { + throw new src_ParseError("Use of the macro doesn't match its definition", tok); + } + } + } + + var args = []; + + for (var _i = 0; _i < numArgs; _i++) { + args.push(this.consumeArg(delimiters && delimiters[_i + 1]).tokens); + } + + return args; + } + /** + * Expand the next token only once if possible. + * + * If the token is expanded, the resulting tokens will be pushed onto + * the stack in reverse order and will be returned as an array, + * also in reverse order. + * + * If not, the next token will be returned without removing it + * from the stack. This case can be detected by a `Token` return value + * instead of an `Array` return value. + * + * In either case, the next token will be on the top of the stack, + * or the stack will be empty. + * + * Used to implement `expandAfterFuture` and `expandNextToken`. + * + * If expandableOnly, only expandable tokens are expanded and + * an undefined control sequence results in an error. + */ + ; + + _proto.expandOnce = function expandOnce(expandableOnly) { + var topToken = this.popToken(); + var name = topToken.text; + var expansion = !topToken.noexpand ? this._getExpansion(name) : null; + + if (expansion == null || expandableOnly && expansion.unexpandable) { + if (expandableOnly && expansion == null && name[0] === "\\" && !this.isDefined(name)) { + throw new src_ParseError("Undefined control sequence: " + name); + } + + this.pushToken(topToken); + return topToken; + } + + this.expansionCount++; + + if (this.expansionCount > this.settings.maxExpand) { + throw new src_ParseError("Too many expansions: infinite loop or " + "need to increase maxExpand setting"); + } + + var tokens = expansion.tokens; + var args = this.consumeArgs(expansion.numArgs, expansion.delimiters); + + if (expansion.numArgs) { + // paste arguments in place of the placeholders + tokens = tokens.slice(); // make a shallow copy + + for (var i = tokens.length - 1; i >= 0; --i) { + var tok = tokens[i]; + + if (tok.text === "#") { + if (i === 0) { + throw new src_ParseError("Incomplete placeholder at end of macro body", tok); + } + + tok = tokens[--i]; // next token on stack + + if (tok.text === "#") { + // ## → # + tokens.splice(i + 1, 1); // drop first # + } else if (/^[1-9]$/.test(tok.text)) { + var _tokens; + + // replace the placeholder with the indicated argument + (_tokens = tokens).splice.apply(_tokens, [i, 2].concat(args[+tok.text - 1])); + } else { + throw new src_ParseError("Not a valid argument number", tok); + } + } + } + } // Concatenate expansion onto top of stack. + + + this.pushTokens(tokens); + return tokens; + } + /** + * Expand the next token only once (if possible), and return the resulting + * top token on the stack (without removing anything from the stack). + * Similar in behavior to TeX's `\expandafter\futurelet`. + * Equivalent to expandOnce() followed by future(). + */ + ; + + _proto.expandAfterFuture = function expandAfterFuture() { + this.expandOnce(); + return this.future(); + } + /** + * Recursively expand first token, then return first non-expandable token. + */ + ; + + _proto.expandNextToken = function expandNextToken() { + for (;;) { + var expanded = this.expandOnce(); // expandOnce returns Token if and only if it's fully expanded. + + if (expanded instanceof Token) { + // \relax stops the expansion, but shouldn't get returned (a + // null return value couldn't get implemented as a function). + // the token after \noexpand is interpreted as if its meaning + // were ‘\relax’ + if (expanded.text === "\\relax" || expanded.treatAsRelax) { + this.stack.pop(); + } else { + return this.stack.pop(); // === expanded + } + } + } // Flow unable to figure out that this pathway is impossible. + // https://github.com/facebook/flow/issues/4808 + + + throw new Error(); // eslint-disable-line no-unreachable + } + /** + * Fully expand the given macro name and return the resulting list of + * tokens, or return `undefined` if no such macro is defined. + */ + ; + + _proto.expandMacro = function expandMacro(name) { + return this.macros.has(name) ? this.expandTokens([new Token(name)]) : undefined; + } + /** + * Fully expand the given token stream and return the resulting list of tokens + */ + ; + + _proto.expandTokens = function expandTokens(tokens) { + var output = []; + var oldStackLength = this.stack.length; + this.pushTokens(tokens); + + while (this.stack.length > oldStackLength) { + var expanded = this.expandOnce(true); // expand only expandable tokens + // expandOnce returns Token if and only if it's fully expanded. + + if (expanded instanceof Token) { + if (expanded.treatAsRelax) { + // the expansion of \noexpand is the token itself + expanded.noexpand = false; + expanded.treatAsRelax = false; + } + + output.push(this.stack.pop()); + } + } + + return output; + } + /** + * Fully expand the given macro name and return the result as a string, + * or return `undefined` if no such macro is defined. + */ + ; + + _proto.expandMacroAsText = function expandMacroAsText(name) { + var tokens = this.expandMacro(name); + + if (tokens) { + return tokens.map(function (token) { + return token.text; + }).join(""); + } else { + return tokens; + } + } + /** + * Returns the expanded macro as a reversed array of tokens and a macro + * argument count. Or returns `null` if no such macro. + */ + ; + + _proto._getExpansion = function _getExpansion(name) { + var definition = this.macros.get(name); + + if (definition == null) { + // mainly checking for undefined here + return definition; + } // If a single character has an associated catcode other than 13 + // (active character), then don't expand it. + + + if (name.length === 1) { + var catcode = this.lexer.catcodes[name]; + + if (catcode != null && catcode !== 13) { + return; + } + } + + var expansion = typeof definition === "function" ? definition(this) : definition; + + if (typeof expansion === "string") { + var numArgs = 0; + + if (expansion.indexOf("#") !== -1) { + var stripped = expansion.replace(/##/g, ""); + + while (stripped.indexOf("#" + (numArgs + 1)) !== -1) { + ++numArgs; + } + } + + var bodyLexer = new Lexer(expansion, this.settings); + var tokens = []; + var tok = bodyLexer.lex(); + + while (tok.text !== "EOF") { + tokens.push(tok); + tok = bodyLexer.lex(); + } + + tokens.reverse(); // to fit in with stack using push and pop + + var expanded = { + tokens: tokens, + numArgs: numArgs + }; + return expanded; + } + + return expansion; + } + /** + * Determine whether a command is currently "defined" (has some + * functionality), meaning that it's a macro (in the current group), + * a function, a symbol, or one of the special commands listed in + * `implicitCommands`. + */ + ; + + _proto.isDefined = function isDefined(name) { + return this.macros.has(name) || src_functions.hasOwnProperty(name) || src_symbols.math.hasOwnProperty(name) || src_symbols.text.hasOwnProperty(name) || implicitCommands.hasOwnProperty(name); + } + /** + * Determine whether a command is expandable. + */ + ; + + _proto.isExpandable = function isExpandable(name) { + var macro = this.macros.get(name); + return macro != null ? typeof macro === "string" || typeof macro === "function" || !macro.unexpandable : src_functions.hasOwnProperty(name) && !src_functions[name].primitive; + }; + + return MacroExpander; +}(); +/* eslint no-constant-condition:0 */ + + + + + + + + + + // Pre-evaluate both modules as unicodeSymbols require String.normalize() + +var unicodeAccents = { + "́": { + "text": "\\'", + "math": "\\acute" + }, + "̀": { + "text": "\\`", + "math": "\\grave" + }, + "̈": { + "text": "\\\"", + "math": "\\ddot" + }, + "̃": { + "text": "\\~", + "math": "\\tilde" + }, + "̄": { + "text": "\\=", + "math": "\\bar" + }, + "̆": { + "text": "\\u", + "math": "\\breve" + }, + "̌": { + "text": "\\v", + "math": "\\check" + }, + "̂": { + "text": "\\^", + "math": "\\hat" + }, + "̇": { + "text": "\\.", + "math": "\\dot" + }, + "̊": { + "text": "\\r", + "math": "\\mathring" + }, + "̋": { + "text": "\\H" + }, + "̧": { + "text": "\\c" + } +}; +var unicodeSymbols = { + "á": "á", + "à": "à", + "ä": "ä", + "ǟ": "ǟ", + "ã": "ã", + "ā": "ā", + "ă": "ă", + "ắ": "ắ", + "ằ": "ằ", + "ẵ": "ẵ", + "ǎ": "ǎ", + "â": "â", + "ấ": "ấ", + "ầ": "ầ", + "ẫ": "ẫ", + "ȧ": "ȧ", + "ǡ": "ǡ", + "å": "å", + "ǻ": "ǻ", + "ḃ": "ḃ", + "ć": "ć", + "ḉ": "ḉ", + "č": "č", + "ĉ": "ĉ", + "ċ": "ċ", + "ç": "ç", + "ď": "ď", + "ḋ": "ḋ", + "ḑ": "ḑ", + "é": "é", + "è": "è", + "ë": "ë", + "ẽ": "ẽ", + "ē": "ē", + "ḗ": "ḗ", + "ḕ": "ḕ", + "ĕ": "ĕ", + "ḝ": "ḝ", + "ě": "ě", + "ê": "ê", + "ế": "ế", + "ề": "ề", + "ễ": "ễ", + "ė": "ė", + "ȩ": "ȩ", + "ḟ": "ḟ", + "ǵ": "ǵ", + "ḡ": "ḡ", + "ğ": "ğ", + "ǧ": "ǧ", + "ĝ": "ĝ", + "ġ": "ġ", + "ģ": "ģ", + "ḧ": "ḧ", + "ȟ": "ȟ", + "ĥ": "ĥ", + "ḣ": "ḣ", + "ḩ": "ḩ", + "í": "í", + "ì": "ì", + "ï": "ï", + "ḯ": "ḯ", + "ĩ": "ĩ", + "ī": "ī", + "ĭ": "ĭ", + "ǐ": "ǐ", + "î": "î", + "ǰ": "ǰ", + "ĵ": "ĵ", + "ḱ": "ḱ", + "ǩ": "ǩ", + "ķ": "ķ", + "ĺ": "ĺ", + "ľ": "ľ", + "ļ": "ļ", + "ḿ": "ḿ", + "ṁ": "ṁ", + "ń": "ń", + "ǹ": "ǹ", + "ñ": "ñ", + "ň": "ň", + "ṅ": "ṅ", + "ņ": "ņ", + "ó": "ó", + "ò": "ò", + "ö": "ö", + "ȫ": "ȫ", + "õ": "õ", + "ṍ": "ṍ", + "ṏ": "ṏ", + "ȭ": "ȭ", + "ō": "ō", + "ṓ": "ṓ", + "ṑ": "ṑ", + "ŏ": "ŏ", + "ǒ": "ǒ", + "ô": "ô", + "ố": "ố", + "ồ": "ồ", + "ỗ": "ỗ", + "ȯ": "ȯ", + "ȱ": "ȱ", + "ő": "ő", + "ṕ": "ṕ", + "ṗ": "ṗ", + "ŕ": "ŕ", + "ř": "ř", + "ṙ": "ṙ", + "ŗ": "ŗ", + "ś": "ś", + "ṥ": "ṥ", + "š": "š", + "ṧ": "ṧ", + "ŝ": "ŝ", + "ṡ": "ṡ", + "ş": "ş", + "ẗ": "ẗ", + "ť": "ť", + "ṫ": "ṫ", + "ţ": "ţ", + "ú": "ú", + "ù": "ù", + "ü": "ü", + "ǘ": "ǘ", + "ǜ": "ǜ", + "ǖ": "ǖ", + "ǚ": "ǚ", + "ũ": "ũ", + "ṹ": "ṹ", + "ū": "ū", + "ṻ": "ṻ", + "ŭ": "ŭ", + "ǔ": "ǔ", + "û": "û", + "ů": "ů", + "ű": "ű", + "ṽ": "ṽ", + "ẃ": "ẃ", + "ẁ": "ẁ", + "ẅ": "ẅ", + "ŵ": "ŵ", + "ẇ": "ẇ", + "ẘ": "ẘ", + "ẍ": "ẍ", + "ẋ": "ẋ", + "ý": "ý", + "ỳ": "ỳ", + "ÿ": "ÿ", + "ỹ": "ỹ", + "ȳ": "ȳ", + "ŷ": "ŷ", + "ẏ": "ẏ", + "ẙ": "ẙ", + "ź": "ź", + "ž": "ž", + "ẑ": "ẑ", + "ż": "ż", + "Á": "Á", + "À": "À", + "Ä": "Ä", + "Ǟ": "Ǟ", + "Ã": "Ã", + "Ā": "Ā", + "Ă": "Ă", + "Ắ": "Ắ", + "Ằ": "Ằ", + "Ẵ": "Ẵ", + "Ǎ": "Ǎ", + "Â": "Â", + "Ấ": "Ấ", + "Ầ": "Ầ", + "Ẫ": "Ẫ", + "Ȧ": "Ȧ", + "Ǡ": "Ǡ", + "Å": "Å", + "Ǻ": "Ǻ", + "Ḃ": "Ḃ", + "Ć": "Ć", + "Ḉ": "Ḉ", + "Č": "Č", + "Ĉ": "Ĉ", + "Ċ": "Ċ", + "Ç": "Ç", + "Ď": "Ď", + "Ḋ": "Ḋ", + "Ḑ": "Ḑ", + "É": "É", + "È": "È", + "Ë": "Ë", + "Ẽ": "Ẽ", + "Ē": "Ē", + "Ḗ": "Ḗ", + "Ḕ": "Ḕ", + "Ĕ": "Ĕ", + "Ḝ": "Ḝ", + "Ě": "Ě", + "Ê": "Ê", + "Ế": "Ế", + "Ề": "Ề", + "Ễ": "Ễ", + "Ė": "Ė", + "Ȩ": "Ȩ", + "Ḟ": "Ḟ", + "Ǵ": "Ǵ", + "Ḡ": "Ḡ", + "Ğ": "Ğ", + "Ǧ": "Ǧ", + "Ĝ": "Ĝ", + "Ġ": "Ġ", + "Ģ": "Ģ", + "Ḧ": "Ḧ", + "Ȟ": "Ȟ", + "Ĥ": "Ĥ", + "Ḣ": "Ḣ", + "Ḩ": "Ḩ", + "Í": "Í", + "Ì": "Ì", + "Ï": "Ï", + "Ḯ": "Ḯ", + "Ĩ": "Ĩ", + "Ī": "Ī", + "Ĭ": "Ĭ", + "Ǐ": "Ǐ", + "Î": "Î", + "İ": "İ", + "Ĵ": "Ĵ", + "Ḱ": "Ḱ", + "Ǩ": "Ǩ", + "Ķ": "Ķ", + "Ĺ": "Ĺ", + "Ľ": "Ľ", + "Ļ": "Ļ", + "Ḿ": "Ḿ", + "Ṁ": "Ṁ", + "Ń": "Ń", + "Ǹ": "Ǹ", + "Ñ": "Ñ", + "Ň": "Ň", + "Ṅ": "Ṅ", + "Ņ": "Ņ", + "Ó": "Ó", + "Ò": "Ò", + "Ö": "Ö", + "Ȫ": "Ȫ", + "Õ": "Õ", + "Ṍ": "Ṍ", + "Ṏ": "Ṏ", + "Ȭ": "Ȭ", + "Ō": "Ō", + "Ṓ": "Ṓ", + "Ṑ": "Ṑ", + "Ŏ": "Ŏ", + "Ǒ": "Ǒ", + "Ô": "Ô", + "Ố": "Ố", + "Ồ": "Ồ", + "Ỗ": "Ỗ", + "Ȯ": "Ȯ", + "Ȱ": "Ȱ", + "Ő": "Ő", + "Ṕ": "Ṕ", + "Ṗ": "Ṗ", + "Ŕ": "Ŕ", + "Ř": "Ř", + "Ṙ": "Ṙ", + "Ŗ": "Ŗ", + "Ś": "Ś", + "Ṥ": "Ṥ", + "Š": "Š", + "Ṧ": "Ṧ", + "Ŝ": "Ŝ", + "Ṡ": "Ṡ", + "Ş": "Ş", + "Ť": "Ť", + "Ṫ": "Ṫ", + "Ţ": "Ţ", + "Ú": "Ú", + "Ù": "Ù", + "Ü": "Ü", + "Ǘ": "Ǘ", + "Ǜ": "Ǜ", + "Ǖ": "Ǖ", + "Ǚ": "Ǚ", + "Ũ": "Ũ", + "Ṹ": "Ṹ", + "Ū": "Ū", + "Ṻ": "Ṻ", + "Ŭ": "Ŭ", + "Ǔ": "Ǔ", + "Û": "Û", + "Ů": "Ů", + "Ű": "Ű", + "Ṽ": "Ṽ", + "Ẃ": "Ẃ", + "Ẁ": "Ẁ", + "Ẅ": "Ẅ", + "Ŵ": "Ŵ", + "Ẇ": "Ẇ", + "Ẍ": "Ẍ", + "Ẋ": "Ẋ", + "Ý": "Ý", + "Ỳ": "Ỳ", + "Ÿ": "Ÿ", + "Ỹ": "Ỹ", + "Ȳ": "Ȳ", + "Ŷ": "Ŷ", + "Ẏ": "Ẏ", + "Ź": "Ź", + "Ž": "Ž", + "Ẑ": "Ẑ", + "Ż": "Ż", + "ά": "ά", + "ὰ": "ὰ", + "ᾱ": "ᾱ", + "ᾰ": "ᾰ", + "έ": "έ", + "ὲ": "ὲ", + "ή": "ή", + "ὴ": "ὴ", + "ί": "ί", + "ὶ": "ὶ", + "ϊ": "ϊ", + "ΐ": "ΐ", + "ῒ": "ῒ", + "ῑ": "ῑ", + "ῐ": "ῐ", + "ό": "ό", + "ὸ": "ὸ", + "ύ": "ύ", + "ὺ": "ὺ", + "ϋ": "ϋ", + "ΰ": "ΰ", + "ῢ": "ῢ", + "ῡ": "ῡ", + "ῠ": "ῠ", + "ώ": "ώ", + "ὼ": "ὼ", + "Ύ": "Ύ", + "Ὺ": "Ὺ", + "Ϋ": "Ϋ", + "Ῡ": "Ῡ", + "Ῠ": "Ῠ", + "Ώ": "Ώ", + "Ὼ": "Ὼ" +}; + +/** + * This file contains the parser used to parse out a TeX expression from the + * input. Since TeX isn't context-free, standard parsers don't work particularly + * well. + * + * The strategy of this parser is as such: + * + * The main functions (the `.parse...` ones) take a position in the current + * parse string to parse tokens from. The lexer (found in Lexer.js, stored at + * this.gullet.lexer) also supports pulling out tokens at arbitrary places. When + * individual tokens are needed at a position, the lexer is called to pull out a + * token, which is then used. + * + * The parser has a property called "mode" indicating the mode that + * the parser is currently in. Currently it has to be one of "math" or + * "text", which denotes whether the current environment is a math-y + * one or a text-y one (e.g. inside \text). Currently, this serves to + * limit the functions which can be used in text mode. + * + * The main functions then return an object which contains the useful data that + * was parsed at its given point, and a new position at the end of the parsed + * data. The main functions can call each other and continue the parsing by + * using the returned position as a new starting point. + * + * There are also extra `.handle...` functions, which pull out some reused + * functionality into self-contained functions. + * + * The functions return ParseNodes. + */ +var Parser = /*#__PURE__*/function () { + function Parser(input, settings) { + this.mode = void 0; + this.gullet = void 0; + this.settings = void 0; + this.leftrightDepth = void 0; + this.nextToken = void 0; + // Start in math mode + this.mode = "math"; // Create a new macro expander (gullet) and (indirectly via that) also a + // new lexer (mouth) for this parser (stomach, in the language of TeX) + + this.gullet = new MacroExpander(input, settings, this.mode); // Store the settings for use in parsing + + this.settings = settings; // Count leftright depth (for \middle errors) + + this.leftrightDepth = 0; + } + /** + * Checks a result to make sure it has the right type, and throws an + * appropriate error otherwise. + */ + + + var _proto = Parser.prototype; + + _proto.expect = function expect(text, consume) { + if (consume === void 0) { + consume = true; + } + + if (this.fetch().text !== text) { + throw new src_ParseError("Expected '" + text + "', got '" + this.fetch().text + "'", this.fetch()); + } + + if (consume) { + this.consume(); + } + } + /** + * Discards the current lookahead token, considering it consumed. + */ + ; + + _proto.consume = function consume() { + this.nextToken = null; + } + /** + * Return the current lookahead token, or if there isn't one (at the + * beginning, or if the previous lookahead token was consume()d), + * fetch the next token as the new lookahead token and return it. + */ + ; + + _proto.fetch = function fetch() { + if (this.nextToken == null) { + this.nextToken = this.gullet.expandNextToken(); + } + + return this.nextToken; + } + /** + * Switches between "text" and "math" modes. + */ + ; + + _proto.switchMode = function switchMode(newMode) { + this.mode = newMode; + this.gullet.switchMode(newMode); + } + /** + * Main parsing function, which parses an entire input. + */ + ; + + _proto.parse = function parse() { + if (!this.settings.globalGroup) { + // Create a group namespace for the math expression. + // (LaTeX creates a new group for every $...$, $$...$$, \[...\].) + this.gullet.beginGroup(); + } // Use old \color behavior (same as LaTeX's \textcolor) if requested. + // We do this within the group for the math expression, so it doesn't + // pollute settings.macros. + + + if (this.settings.colorIsTextColor) { + this.gullet.macros.set("\\color", "\\textcolor"); + } + + try { + // Try to parse the input + var parse = this.parseExpression(false); // If we succeeded, make sure there's an EOF at the end + + this.expect("EOF"); // End the group namespace for the expression + + if (!this.settings.globalGroup) { + this.gullet.endGroup(); + } + + return parse; // Close any leftover groups in case of a parse error. + } finally { + this.gullet.endGroups(); + } + }; + + /** + * Parses an "expression", which is a list of atoms. + * + * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This + * happens when functions have higher precendence han infix + * nodes in implicit parses. + * + * `breakOnTokenText`: The text of the token that the expression should end + * with, or `null` if something else should end the + * expression. + */ + _proto.parseExpression = function parseExpression(breakOnInfix, breakOnTokenText) { + var body = []; // Keep adding atoms to the body until we can't parse any more atoms (either + // we reached the end, a }, or a \right) + + while (true) { + // Ignore spaces in math mode + if (this.mode === "math") { + this.consumeSpaces(); + } + + var lex = this.fetch(); + + if (Parser.endOfExpression.indexOf(lex.text) !== -1) { + break; + } + + if (breakOnTokenText && lex.text === breakOnTokenText) { + break; + } + + if (breakOnInfix && src_functions[lex.text] && src_functions[lex.text].infix) { + break; + } + + var atom = this.parseAtom(breakOnTokenText); + + if (!atom) { + break; + } else if (atom.type === "internal") { + continue; + } + + body.push(atom); + } + + if (this.mode === "text") { + this.formLigatures(body); + } + + return this.handleInfixNodes(body); + } + /** + * Rewrites infix operators such as \over with corresponding commands such + * as \frac. + * + * There can only be one infix operator per group. If there's more than one + * then the expression is ambiguous. This can be resolved by adding {}. + */ + ; + + _proto.handleInfixNodes = function handleInfixNodes(body) { + var overIndex = -1; + var funcName; + + for (var i = 0; i < body.length; i++) { + if (body[i].type === "infix") { + if (overIndex !== -1) { + throw new src_ParseError("only one infix operator per group", body[i].token); + } + + overIndex = i; + funcName = body[i].replaceWith; + } + } + + if (overIndex !== -1 && funcName) { + var numerNode; + var denomNode; + var numerBody = body.slice(0, overIndex); + var denomBody = body.slice(overIndex + 1); + + if (numerBody.length === 1 && numerBody[0].type === "ordgroup") { + numerNode = numerBody[0]; + } else { + numerNode = { + type: "ordgroup", + mode: this.mode, + body: numerBody + }; + } + + if (denomBody.length === 1 && denomBody[0].type === "ordgroup") { + denomNode = denomBody[0]; + } else { + denomNode = { + type: "ordgroup", + mode: this.mode, + body: denomBody + }; + } + + var node; + + if (funcName === "\\\\abovefrac") { + node = this.callFunction(funcName, [numerNode, body[overIndex], denomNode], []); + } else { + node = this.callFunction(funcName, [numerNode, denomNode], []); + } + + return [node]; + } else { + return body; + } + } + /** + * Handle a subscript or superscript with nice errors. + */ + ; + + _proto.handleSupSubscript = function handleSupSubscript(name // For error reporting. + ) { + var symbolToken = this.fetch(); + var symbol = symbolToken.text; + this.consume(); + this.consumeSpaces(); // ignore spaces before sup/subscript argument + + var group = this.parseGroup(name); + + if (!group) { + throw new src_ParseError("Expected group after '" + symbol + "'", symbolToken); + } + + return group; + } + /** + * Converts the textual input of an unsupported command into a text node + * contained within a color node whose color is determined by errorColor + */ + ; + + _proto.formatUnsupportedCmd = function formatUnsupportedCmd(text) { + var textordArray = []; + + for (var i = 0; i < text.length; i++) { + textordArray.push({ + type: "textord", + mode: "text", + text: text[i] + }); + } + + var textNode = { + type: "text", + mode: this.mode, + body: textordArray + }; + var colorNode = { + type: "color", + mode: this.mode, + color: this.settings.errorColor, + body: [textNode] + }; + return colorNode; + } + /** + * Parses a group with optional super/subscripts. + */ + ; + + _proto.parseAtom = function parseAtom(breakOnTokenText) { + // The body of an atom is an implicit group, so that things like + // \left(x\right)^2 work correctly. + var base = this.parseGroup("atom", breakOnTokenText); // In text mode, we don't have superscripts or subscripts + + if (this.mode === "text") { + return base; + } // Note that base may be empty (i.e. null) at this point. + + + var superscript; + var subscript; + + while (true) { + // Guaranteed in math mode, so eat any spaces first. + this.consumeSpaces(); // Lex the first token + + var lex = this.fetch(); + + if (lex.text === "\\limits" || lex.text === "\\nolimits") { + // We got a limit control + if (base && base.type === "op") { + var limits = lex.text === "\\limits"; + base.limits = limits; + base.alwaysHandleSupSub = true; + } else if (base && base.type === "operatorname") { + if (base.alwaysHandleSupSub) { + base.limits = lex.text === "\\limits"; + } + } else { + throw new src_ParseError("Limit controls must follow a math operator", lex); + } + + this.consume(); + } else if (lex.text === "^") { + // We got a superscript start + if (superscript) { + throw new src_ParseError("Double superscript", lex); + } + + superscript = this.handleSupSubscript("superscript"); + } else if (lex.text === "_") { + // We got a subscript start + if (subscript) { + throw new src_ParseError("Double subscript", lex); + } + + subscript = this.handleSupSubscript("subscript"); + } else if (lex.text === "'") { + // We got a prime + if (superscript) { + throw new src_ParseError("Double superscript", lex); + } + + var prime = { + type: "textord", + mode: this.mode, + text: "\\prime" + }; // Many primes can be grouped together, so we handle this here + + var primes = [prime]; + this.consume(); // Keep lexing tokens until we get something that's not a prime + + while (this.fetch().text === "'") { + // For each one, add another prime to the list + primes.push(prime); + this.consume(); + } // If there's a superscript following the primes, combine that + // superscript in with the primes. + + + if (this.fetch().text === "^") { + primes.push(this.handleSupSubscript("superscript")); + } // Put everything into an ordgroup as the superscript + + + superscript = { + type: "ordgroup", + mode: this.mode, + body: primes + }; + } else { + // If it wasn't ^, _, or ', stop parsing super/subscripts + break; + } + } // Base must be set if superscript or subscript are set per logic above, + // but need to check here for type check to pass. + + + if (superscript || subscript) { + // If we got either a superscript or subscript, create a supsub + return { + type: "supsub", + mode: this.mode, + base: base, + sup: superscript, + sub: subscript + }; + } else { + // Otherwise return the original body + return base; + } + } + /** + * Parses an entire function, including its base and all of its arguments. + */ + ; + + _proto.parseFunction = function parseFunction(breakOnTokenText, name // For determining its context + ) { + var token = this.fetch(); + var func = token.text; + var funcData = src_functions[func]; + + if (!funcData) { + return null; + } + + this.consume(); // consume command token + + if (name && name !== "atom" && !funcData.allowedInArgument) { + throw new src_ParseError("Got function '" + func + "' with no arguments" + (name ? " as " + name : ""), token); + } else if (this.mode === "text" && !funcData.allowedInText) { + throw new src_ParseError("Can't use function '" + func + "' in text mode", token); + } else if (this.mode === "math" && funcData.allowedInMath === false) { + throw new src_ParseError("Can't use function '" + func + "' in math mode", token); + } + + var _this$parseArguments = this.parseArguments(func, funcData), + args = _this$parseArguments.args, + optArgs = _this$parseArguments.optArgs; + + return this.callFunction(func, args, optArgs, token, breakOnTokenText); + } + /** + * Call a function handler with a suitable context and arguments. + */ + ; + + _proto.callFunction = function callFunction(name, args, optArgs, token, breakOnTokenText) { + var context = { + funcName: name, + parser: this, + token: token, + breakOnTokenText: breakOnTokenText + }; + var func = src_functions[name]; + + if (func && func.handler) { + return func.handler(context, args, optArgs); + } else { + throw new src_ParseError("No function handler for " + name); + } + } + /** + * Parses the arguments of a function or environment + */ + ; + + _proto.parseArguments = function parseArguments(func, // Should look like "\name" or "\begin{name}". + funcData) { + var totalArgs = funcData.numArgs + funcData.numOptionalArgs; + + if (totalArgs === 0) { + return { + args: [], + optArgs: [] + }; + } + + var args = []; + var optArgs = []; + + for (var i = 0; i < totalArgs; i++) { + var argType = funcData.argTypes && funcData.argTypes[i]; + var isOptional = i < funcData.numOptionalArgs; + + if (funcData.primitive && argType == null || // \sqrt expands into primitive if optional argument doesn't exist + funcData.type === "sqrt" && i === 1 && optArgs[0] == null) { + argType = "primitive"; + } + + var arg = this.parseGroupOfType("argument to '" + func + "'", argType, isOptional); + + if (isOptional) { + optArgs.push(arg); + } else if (arg != null) { + args.push(arg); + } else { + // should be unreachable + throw new src_ParseError("Null argument, please report this as a bug"); + } + } + + return { + args: args, + optArgs: optArgs + }; + } + /** + * Parses a group when the mode is changing. + */ + ; + + _proto.parseGroupOfType = function parseGroupOfType(name, type, optional) { + switch (type) { + case "color": + return this.parseColorGroup(optional); + + case "size": + return this.parseSizeGroup(optional); + + case "url": + return this.parseUrlGroup(optional); + + case "math": + case "text": + return this.parseArgumentGroup(optional, type); + + case "hbox": + { + // hbox argument type wraps the argument in the equivalent of + // \hbox, which is like \text but switching to \textstyle size. + var group = this.parseArgumentGroup(optional, "text"); + return group != null ? { + type: "styling", + mode: group.mode, + body: [group], + style: "text" // simulate \textstyle + + } : null; + } + + case "raw": + { + var token = this.parseStringGroup("raw", optional); + return token != null ? { + type: "raw", + mode: "text", + string: token.text + } : null; + } + + case "primitive": + { + if (optional) { + throw new src_ParseError("A primitive argument cannot be optional"); + } + + var _group = this.parseGroup(name); + + if (_group == null) { + throw new src_ParseError("Expected group as " + name, this.fetch()); + } + + return _group; + } + + case "original": + case null: + case undefined: + return this.parseArgumentGroup(optional); + + default: + throw new src_ParseError("Unknown group type as " + name, this.fetch()); + } + } + /** + * Discard any space tokens, fetching the next non-space token. + */ + ; + + _proto.consumeSpaces = function consumeSpaces() { + while (this.fetch().text === " ") { + this.consume(); + } + } + /** + * Parses a group, essentially returning the string formed by the + * brace-enclosed tokens plus some position information. + */ + ; + + _proto.parseStringGroup = function parseStringGroup(modeName, // Used to describe the mode in error messages. + optional) { + var argToken = this.gullet.scanArgument(optional); + + if (argToken == null) { + return null; + } + + var str = ""; + var nextToken; + + while ((nextToken = this.fetch()).text !== "EOF") { + str += nextToken.text; + this.consume(); + } + + this.consume(); // consume the end of the argument + + argToken.text = str; + return argToken; + } + /** + * Parses a regex-delimited group: the largest sequence of tokens + * whose concatenated strings match `regex`. Returns the string + * formed by the tokens plus some position information. + */ + ; + + _proto.parseRegexGroup = function parseRegexGroup(regex, modeName // Used to describe the mode in error messages. + ) { + var firstToken = this.fetch(); + var lastToken = firstToken; + var str = ""; + var nextToken; + + while ((nextToken = this.fetch()).text !== "EOF" && regex.test(str + nextToken.text)) { + lastToken = nextToken; + str += lastToken.text; + this.consume(); + } + + if (str === "") { + throw new src_ParseError("Invalid " + modeName + ": '" + firstToken.text + "'", firstToken); + } + + return firstToken.range(lastToken, str); + } + /** + * Parses a color description. + */ + ; + + _proto.parseColorGroup = function parseColorGroup(optional) { + var res = this.parseStringGroup("color", optional); + + if (res == null) { + return null; + } + + var match = /^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(res.text); + + if (!match) { + throw new src_ParseError("Invalid color: '" + res.text + "'", res); + } + + var color = match[0]; + + if (/^[0-9a-f]{6}$/i.test(color)) { + // We allow a 6-digit HTML color spec without a leading "#". + // This follows the xcolor package's HTML color model. + // Predefined color names are all missed by this RegEx pattern. + color = "#" + color; + } + + return { + type: "color-token", + mode: this.mode, + color: color + }; + } + /** + * Parses a size specification, consisting of magnitude and unit. + */ + ; + + _proto.parseSizeGroup = function parseSizeGroup(optional) { + var res; + var isBlank = false; // don't expand before parseStringGroup + + this.gullet.consumeSpaces(); + + if (!optional && this.gullet.future().text !== "{") { + res = this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/, "size"); + } else { + res = this.parseStringGroup("size", optional); + } + + if (!res) { + return null; + } + + if (!optional && res.text.length === 0) { + // Because we've tested for what is !optional, this block won't + // affect \kern, \hspace, etc. It will capture the mandatory arguments + // to \genfrac and \above. + res.text = "0pt"; // Enable \above{} + + isBlank = true; // This is here specifically for \genfrac + } + + var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(res.text); + + if (!match) { + throw new src_ParseError("Invalid size: '" + res.text + "'", res); + } + + var data = { + number: +(match[1] + match[2]), + // sign + magnitude, cast to number + unit: match[3] + }; + + if (!validUnit(data)) { + throw new src_ParseError("Invalid unit: '" + data.unit + "'", res); + } + + return { + type: "size", + mode: this.mode, + value: data, + isBlank: isBlank + }; + } + /** + * Parses an URL, checking escaped letters and allowed protocols, + * and setting the catcode of % as an active character (as in \hyperref). + */ + ; + + _proto.parseUrlGroup = function parseUrlGroup(optional) { + this.gullet.lexer.setCatcode("%", 13); // active character + + this.gullet.lexer.setCatcode("~", 12); // other character + + var res = this.parseStringGroup("url", optional); + this.gullet.lexer.setCatcode("%", 14); // comment character + + this.gullet.lexer.setCatcode("~", 13); // active character + + if (res == null) { + return null; + } // hyperref package allows backslashes alone in href, but doesn't + // generate valid links in such cases; we interpret this as + // "undefined" behaviour, and keep them as-is. Some browser will + // replace backslashes with forward slashes. + + + var url = res.text.replace(/\\([#$%&~_^{}])/g, '$1'); + return { + type: "url", + mode: this.mode, + url: url + }; + } + /** + * Parses an argument with the mode specified. + */ + ; + + _proto.parseArgumentGroup = function parseArgumentGroup(optional, mode) { + var argToken = this.gullet.scanArgument(optional); + + if (argToken == null) { + return null; + } + + var outerMode = this.mode; + + if (mode) { + // Switch to specified mode + this.switchMode(mode); + } + + this.gullet.beginGroup(); + var expression = this.parseExpression(false, "EOF"); // TODO: find an alternative way to denote the end + + this.expect("EOF"); // expect the end of the argument + + this.gullet.endGroup(); + var result = { + type: "ordgroup", + mode: this.mode, + loc: argToken.loc, + body: expression + }; + + if (mode) { + // Switch mode back + this.switchMode(outerMode); + } + + return result; + } + /** + * Parses an ordinary group, which is either a single nucleus (like "x") + * or an expression in braces (like "{x+y}") or an implicit group, a group + * that starts at the current position, and ends right before a higher explicit + * group ends, or at EOF. + */ + ; + + _proto.parseGroup = function parseGroup(name, // For error reporting. + breakOnTokenText) { + var firstToken = this.fetch(); + var text = firstToken.text; + var result; // Try to parse an open brace or \begingroup + + if (text === "{" || text === "\\begingroup") { + this.consume(); + var groupEnd = text === "{" ? "}" : "\\endgroup"; + this.gullet.beginGroup(); // If we get a brace, parse an expression + + var expression = this.parseExpression(false, groupEnd); + var lastToken = this.fetch(); + this.expect(groupEnd); // Check that we got a matching closing brace + + this.gullet.endGroup(); + result = { + type: "ordgroup", + mode: this.mode, + loc: SourceLocation.range(firstToken, lastToken), + body: expression, + // A group formed by \begingroup...\endgroup is a semi-simple group + // which doesn't affect spacing in math mode, i.e., is transparent. + // https://tex.stackexchange.com/questions/1930/when-should-one- + // use-begingroup-instead-of-bgroup + semisimple: text === "\\begingroup" || undefined + }; + } else { + // If there exists a function with this name, parse the function. + // Otherwise, just return a nucleus + result = this.parseFunction(breakOnTokenText, name) || this.parseSymbol(); + + if (result == null && text[0] === "\\" && !implicitCommands.hasOwnProperty(text)) { + if (this.settings.throwOnError) { + throw new src_ParseError("Undefined control sequence: " + text, firstToken); + } + + result = this.formatUnsupportedCmd(text); + this.consume(); + } + } + + return result; + } + /** + * Form ligature-like combinations of characters for text mode. + * This includes inputs like "--", "---", "``" and "''". + * The result will simply replace multiple textord nodes with a single + * character in each value by a single textord node having multiple + * characters in its value. The representation is still ASCII source. + * The group will be modified in place. + */ + ; + + _proto.formLigatures = function formLigatures(group) { + var n = group.length - 1; + + for (var i = 0; i < n; ++i) { + var a = group[i]; // $FlowFixMe: Not every node type has a `text` property. + + var v = a.text; + + if (v === "-" && group[i + 1].text === "-") { + if (i + 1 < n && group[i + 2].text === "-") { + group.splice(i, 3, { + type: "textord", + mode: "text", + loc: SourceLocation.range(a, group[i + 2]), + text: "---" + }); + n -= 2; + } else { + group.splice(i, 2, { + type: "textord", + mode: "text", + loc: SourceLocation.range(a, group[i + 1]), + text: "--" + }); + n -= 1; + } + } + + if ((v === "'" || v === "`") && group[i + 1].text === v) { + group.splice(i, 2, { + type: "textord", + mode: "text", + loc: SourceLocation.range(a, group[i + 1]), + text: v + v + }); + n -= 1; + } + } + } + /** + * Parse a single symbol out of the string. Here, we handle single character + * symbols and special functions like \verb. + */ + ; + + _proto.parseSymbol = function parseSymbol() { + var nucleus = this.fetch(); + var text = nucleus.text; + + if (/^\\verb[^a-zA-Z]/.test(text)) { + this.consume(); + var arg = text.slice(5); + var star = arg.charAt(0) === "*"; + + if (star) { + arg = arg.slice(1); + } // Lexer's tokenRegex is constructed to always have matching + // first/last characters. + + + if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) { + throw new src_ParseError("\\verb assertion failed --\n please report what input caused this bug"); + } + + arg = arg.slice(1, -1); // remove first and last char + + return { + type: "verb", + mode: "text", + body: arg, + star: star + }; + } // At this point, we should have a symbol, possibly with accents. + // First expand any accented base symbol according to unicodeSymbols. + + + if (unicodeSymbols.hasOwnProperty(text[0]) && !src_symbols[this.mode][text[0]]) { + // This behavior is not strict (XeTeX-compatible) in math mode. + if (this.settings.strict && this.mode === "math") { + this.settings.reportNonstrict("unicodeTextInMathMode", "Accented Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus); + } + + text = unicodeSymbols[text[0]] + text.substr(1); + } // Strip off any combining characters + + + var match = combiningDiacriticalMarksEndRegex.exec(text); + + if (match) { + text = text.substring(0, match.index); + + if (text === 'i') { + text = "\u0131"; // dotless i, in math and text mode + } else if (text === 'j') { + text = "\u0237"; // dotless j, in math and text mode + } + } // Recognize base symbol + + + var symbol; + + if (src_symbols[this.mode][text]) { + if (this.settings.strict && this.mode === 'math' && extraLatin.indexOf(text) >= 0) { + this.settings.reportNonstrict("unicodeTextInMathMode", "Latin-1/Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus); + } + + var group = src_symbols[this.mode][text].group; + var loc = SourceLocation.range(nucleus); + var s; + + if (ATOMS.hasOwnProperty(group)) { + // $FlowFixMe + var family = group; + s = { + type: "atom", + mode: this.mode, + family: family, + loc: loc, + text: text + }; + } else { + // $FlowFixMe + s = { + type: group, + mode: this.mode, + loc: loc, + text: text + }; + } // $FlowFixMe + + + symbol = s; + } else if (text.charCodeAt(0) >= 0x80) { + // no symbol for e.g. ^ + if (this.settings.strict) { + if (!supportedCodepoint(text.charCodeAt(0))) { + this.settings.reportNonstrict("unknownSymbol", "Unrecognized Unicode character \"" + text[0] + "\"" + (" (" + text.charCodeAt(0) + ")"), nucleus); + } else if (this.mode === "math") { + this.settings.reportNonstrict("unicodeTextInMathMode", "Unicode text character \"" + text[0] + "\" used in math mode", nucleus); + } + } // All nonmathematical Unicode characters are rendered as if they + // are in text mode (wrapped in \text) because that's what it + // takes to render them in LaTeX. Setting `mode: this.mode` is + // another natural choice (the user requested math mode), but + // this makes it more difficult for getCharacterMetrics() to + // distinguish Unicode characters without metrics and those for + // which we want to simulate the letter M. + + + symbol = { + type: "textord", + mode: "text", + loc: SourceLocation.range(nucleus), + text: text + }; + } else { + return null; // EOF, ^, _, {, }, etc. + } + + this.consume(); // Transform combining characters into accents + + if (match) { + for (var i = 0; i < match[0].length; i++) { + var accent = match[0][i]; + + if (!unicodeAccents[accent]) { + throw new src_ParseError("Unknown accent ' " + accent + "'", nucleus); + } + + var command = unicodeAccents[accent][this.mode] || unicodeAccents[accent].text; + + if (!command) { + throw new src_ParseError("Accent " + accent + " unsupported in " + this.mode + " mode", nucleus); + } + + symbol = { + type: "accent", + mode: this.mode, + loc: SourceLocation.range(nucleus), + label: command, + isStretchy: false, + isShifty: true, + // $FlowFixMe + base: symbol + }; + } + } // $FlowFixMe + + + return symbol; + }; + + return Parser; +}(); + +Parser.endOfExpression = ["}", "\\endgroup", "\\end", "\\right", "&"]; +/** + * Provides a single function for parsing an expression using a Parser + * TODO(emily): Remove this + */ + + + +/** + * Parses an expression using a Parser, then returns the parsed result. + */ +var parseTree = function parseTree(toParse, settings) { + if (!(typeof toParse === 'string' || toParse instanceof String)) { + throw new TypeError('KaTeX can only parse string typed expression'); + } + + var parser = new Parser(toParse, settings); // Blank out any \df@tag to avoid spurious "Duplicate \tag" errors + + delete parser.gullet.macros.current["\\df@tag"]; + var tree = parser.parse(); // Prevent a color definition from persisting between calls to katex.render(). + + delete parser.gullet.macros.current["\\current@color"]; + delete parser.gullet.macros.current["\\color"]; // If the input used \tag, it will set the \df@tag macro to the tag. + // In this case, we separately parse the tag and wrap the tree. + + if (parser.gullet.macros.get("\\df@tag")) { + if (!settings.displayMode) { + throw new src_ParseError("\\tag works only in display equations"); + } + + parser.gullet.feed("\\df@tag"); + tree = [{ + type: "tag", + mode: "text", + body: tree, + tag: parser.parse() + }]; + } + + return tree; +}; + +/* harmony default export */ var src_parseTree = (parseTree); +/* eslint no-console:0 */ + +/** + * This is the main entry point for KaTeX. Here, we expose functions for + * rendering expressions either to DOM nodes or to markup strings. + * + * We also expose the ParseError class to check if errors thrown from KaTeX are + * errors in the expression, or errors in javascript handling. + */ + + + + + + + + + + +/** + * Parse and build an expression, and place that expression in the DOM node + * given. + */ +var render = function render(expression, baseNode, options) { + baseNode.textContent = ""; + var node = renderToDomTree(expression, options).toNode(); + baseNode.appendChild(node); +}; // KaTeX's styles don't work properly in quirks mode. Print out an error, and +// disable rendering. + + +if (typeof document !== "undefined") { + if (document.compatMode !== "CSS1Compat") { + typeof console !== "undefined" && console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your " + "website has a suitable doctype."); + + render = function render() { + throw new src_ParseError("KaTeX doesn't work in quirks mode."); + }; + } +} +/** + * Parse and build an expression, and return the markup for that. + */ + + +var renderToString = function renderToString(expression, options) { + var markup = renderToDomTree(expression, options).toMarkup(); + return markup; +}; +/** + * Parse an expression and return the parse tree. + */ + + +var generateParseTree = function generateParseTree(expression, options) { + var settings = new Settings(options); + return src_parseTree(expression, settings); +}; +/** + * If the given error is a KaTeX ParseError and options.throwOnError is false, + * renders the invalid LaTeX as a span with hover title giving the KaTeX + * error message. Otherwise, simply throws the error. + */ + + +var renderError = function renderError(error, expression, options) { + if (options.throwOnError || !(error instanceof src_ParseError)) { + throw error; + } + + var node = buildCommon.makeSpan(["katex-error"], [new SymbolNode(expression)]); + node.setAttribute("title", error.toString()); + node.setAttribute("style", "color:" + options.errorColor); + return node; +}; +/** + * Generates and returns the katex build tree. This is used for advanced + * use cases (like rendering to custom output). + */ + + +var renderToDomTree = function renderToDomTree(expression, options) { + var settings = new Settings(options); + + try { + var tree = src_parseTree(expression, settings); + return buildTree(tree, expression, settings); + } catch (error) { + return renderError(error, expression, settings); + } +}; +/** + * Generates and returns the katex build tree, with just HTML (no MathML). + * This is used for advanced use cases (like rendering to custom output). + */ + + +var renderToHTMLTree = function renderToHTMLTree(expression, options) { + var settings = new Settings(options); + + try { + var tree = src_parseTree(expression, settings); + return buildHTMLTree(tree, expression, settings); + } catch (error) { + return renderError(error, expression, settings); + } +}; + +/* harmony default export */ var katex = ({ + /** + * Current KaTeX version + */ + version: "0.13.24", + + /** + * Renders the given LaTeX into an HTML+MathML combination, and adds + * it as a child to the specified DOM node. + */ + render: render, + + /** + * Renders the given LaTeX into an HTML+MathML combination string, + * for sending to the client. + */ + renderToString: renderToString, + + /** + * KaTeX error, usually during parsing. + */ + ParseError: src_ParseError, + + /** + * Parses the given LaTeX into KaTeX's internal parse tree structure, + * without rendering to HTML or MathML. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __parse: generateParseTree, + + /** + * Renders the given LaTeX into an HTML+MathML internal DOM tree + * representation, without flattening that representation to a string. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __renderToDomTree: renderToDomTree, + + /** + * Renders the given LaTeX into an HTML internal DOM tree representation, + * without MathML and without flattening that representation to a string. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __renderToHTMLTree: renderToHTMLTree, + + /** + * extends internal font metrics object with a new object + * each key in the new object represents a font name + */ + __setFontMetrics: setFontMetrics, + + /** + * adds a new symbol to builtin symbols table + */ + __defineSymbol: defineSymbol, + + /** + * adds a new macro to builtin macro list + */ + __defineMacro: defineMacro, + + /** + * Expose the dom tree node types, which can be useful for type checking nodes. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __domTree: { + Span: Span, + Anchor: Anchor, + SymbolNode: SymbolNode, + SvgNode: SvgNode, + PathNode: PathNode, + LineNode: LineNode + } +}); +/** + * This is the webpack entry point for KaTeX. As ECMAScript, flow[1] and jest[2] + * doesn't support CSS modules natively, a separate entry point is used and + * it is not flowtyped. + * + * [1] https://gist.github.com/lambdahands/d19e0da96285b749f0ef + * [2] https://facebook.github.io/jest/docs/en/webpack.html + */ + + +/* harmony default export */ var katex_webpack = (katex); +__webpack_exports__ = __webpack_exports__["default"]; +/******/ return __webpack_exports__; +/******/ })() +; +}); +}); + +/*! markmap-lib v0.11.6 | MIT License */ + +var browser = createCommonjsModule(function (module, exports) { +(function (global, factory) { +factory(exports, katex) ; +}(commonjsGlobal, (function (exports, require$$0) { +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e['default'] : e; } + +var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); + +function _extends$1() { + _extends$1 = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends$1.apply(this, arguments); +} + +/*! markmap-common v0.1.5 | MIT License */ +class Hook { + constructor() { + this.listeners = []; + } + + tap(fn) { + this.listeners.push(fn); + return () => this.revoke(fn); + } + + revoke(fn) { + const i = this.listeners.indexOf(fn); + if (i >= 0) this.listeners.splice(i, 1); + } + + revokeAll() { + this.listeners.splice(0); + } + + call(...args) { + for (const fn of this.listeners) { + fn(...args); + } + } + +} + +function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); +} + +function escapeHtml$1(html) { + return html.replace(/[&<"]/g, m => ({ + '&': '&', + '<': '<', + '"': '"' + })[m]); +} + +function escapeScript(content) { + return content.replace(/<(\/script>)/g, '\\x3c$2'); +} + +function htmlOpen(tagName, attrs) { + const attrStr = attrs ? Object.entries(attrs).map(([key, value]) => { + if (value == null || value === false) return; + key = ` ${escapeHtml$1(key)}`; + if (value === true) return key; + return `${key}="${escapeHtml$1(value)}"`; + }).filter(Boolean).join('') : ''; + return `<${tagName}${attrStr}>`; +} + +function htmlClose(tagName) { + return ``; +} + +function wrapHtml(tagName, content, attrs) { + if (content == null) return htmlOpen(tagName, attrs); + return htmlOpen(tagName, attrs) + (content || '') + htmlClose(tagName); +} + +function buildCode(fn, args) { + const params = args.map(arg => { + if (typeof arg === 'function') return arg.toString(); + return JSON.stringify(arg != null ? arg : null); + }).join(','); + return `(${fn.toString()})(${params})`; +} + +function persistJS(items, context) { + return items.map(item => { + if (item.type === 'script') return wrapHtml('script', '', item.data); + + if (item.type === 'iife') { + const { + fn, + getParams + } = item.data; + return wrapHtml('script', escapeScript(buildCode(fn, (getParams == null ? void 0 : getParams(context)) || []))); + } + + return ''; + }); +} + +function persistCSS(items) { + return items.map(item => { + if (item.type === 'stylesheet') { + return wrapHtml('link', null, _extends({ + rel: 'stylesheet' + }, item.data)); + } + /* else if (item.type === 'style') */ + + + return wrapHtml('style', item.data); + }); +} + +Math.random().toString(36).slice(2, 8); + +function wrapFunction(fn, { + before, + after +}) { + return function wrapped(...args) { + const ctx = { + args + }; + + try { + if (before) before(ctx); + } catch (_unused) {// ignore + } + + ctx.result = fn(...args); + + try { + if (after) after(ctx); + } catch (_unused2) {// ignore + } + + return ctx.result; + }; +} + +function memoize(fn) { + const cache = {}; + return function memoized(...args) { + const key = `${args[0]}`; + let data = cache[key]; + + if (!data) { + data = { + value: fn(...args) + }; + cache[key] = data; + } + + return data.value; + }; +} + +function createElement(tagName, props, attrs) { + const el = document.createElement(tagName); + + if (props) { + Object.entries(props).forEach(([key, value]) => { + el[key] = value; + }); + } + + if (attrs) { + Object.entries(attrs).forEach(([key, value]) => { + el.setAttribute(key, value); + }); + } + + return el; +} + +const memoizedPreloadJS = memoize(url => { + document.head.append(createElement('link', { + rel: 'preload', + as: 'script', + href: url + })); +}); + +function loadJSItem(item, context) { + if (item.type === 'script') { + return new Promise((resolve, reject) => { + var _item$data; + + document.head.append(createElement('script', _extends({}, item.data, { + onload: resolve, + onerror: reject + }))); // Run inline script synchronously + + if (!((_item$data = item.data) != null && _item$data.src)) resolve(); + }); + } + + if (item.type === 'iife') { + const { + fn, + getParams + } = item.data; + fn(...((getParams == null ? void 0 : getParams(context)) || [])); + } +} + +async function loadJS(items, context) { + const needPreload = items.filter(item => { + var _item$data2; + + return item.type === 'script' && ((_item$data2 = item.data) == null ? void 0 : _item$data2.src); + }); + if (needPreload.length > 1) needPreload.forEach(item => memoizedPreloadJS(item.data.src)); + context = _extends({ + getMarkmap: () => window.markmap + }, context); + + for (const item of items) { + await loadJSItem(item, context); + } +} + +const template = "\n\n\n\n\n\nMarkmap\n\n\n\n\n\n\n\n\n"; +const BASE_JS = [`https://cdn.jsdelivr.net/npm/d3@${"6.6.0"}`, `https://cdn.jsdelivr.net/npm/markmap-view@${"0.2.6"}`].map(src => ({ + type: 'script', + data: { + src + } +})); +function fillTemplate(data, assets, extra) { + if (typeof extra === 'function') { + extra = { + getOptions: extra + }; + } + + extra = _extends$1({ + baseJs: BASE_JS + }, extra); + const { + scripts, + styles + } = assets; + const cssList = [...(styles ? persistCSS(styles) : [])]; + const context = { + getMarkmap: () => window.markmap, + getOptions: extra.getOptions, + data + }; + const jsList = [...persistJS(extra.baseJs), ...persistJS([...(scripts || []), { + type: 'iife', + data: { + fn: (getMarkmap, getOptions, data) => { + const { + Markmap + } = getMarkmap(); + window.mm = Markmap.create('svg#mindmap', getOptions == null ? void 0 : getOptions(), data); + }, + getParams: ({ + getMarkmap, + getOptions, + data + }) => { + return [getMarkmap, getOptions, data]; + } + } + }], context)]; + const html = template.replace('', () => cssList.join('')).replace('', () => jsList.join('')); + return html; +} + +// List of valid entities +// +// Generate with ./support/entities.js script +// + +/*eslint quotes:0*/ +var entities = { + "Aacute": "\xC1", + "aacute": "\xE1", + "Abreve": "\u0102", + "abreve": "\u0103", + "ac": "\u223E", + "acd": "\u223F", + "acE": "\u223E\u0333", + "Acirc": "\xC2", + "acirc": "\xE2", + "acute": "\xB4", + "Acy": "\u0410", + "acy": "\u0430", + "AElig": "\xC6", + "aelig": "\xE6", + "af": "\u2061", + "Afr": "\uD835\uDD04", + "afr": "\uD835\uDD1E", + "Agrave": "\xC0", + "agrave": "\xE0", + "alefsym": "\u2135", + "aleph": "\u2135", + "Alpha": "\u0391", + "alpha": "\u03B1", + "Amacr": "\u0100", + "amacr": "\u0101", + "amalg": "\u2A3F", + "AMP": "&", + "amp": "&", + "And": "\u2A53", + "and": "\u2227", + "andand": "\u2A55", + "andd": "\u2A5C", + "andslope": "\u2A58", + "andv": "\u2A5A", + "ang": "\u2220", + "ange": "\u29A4", + "angle": "\u2220", + "angmsd": "\u2221", + "angmsdaa": "\u29A8", + "angmsdab": "\u29A9", + "angmsdac": "\u29AA", + "angmsdad": "\u29AB", + "angmsdae": "\u29AC", + "angmsdaf": "\u29AD", + "angmsdag": "\u29AE", + "angmsdah": "\u29AF", + "angrt": "\u221F", + "angrtvb": "\u22BE", + "angrtvbd": "\u299D", + "angsph": "\u2222", + "angst": "\xC5", + "angzarr": "\u237C", + "Aogon": "\u0104", + "aogon": "\u0105", + "Aopf": "\uD835\uDD38", + "aopf": "\uD835\uDD52", + "ap": "\u2248", + "apacir": "\u2A6F", + "apE": "\u2A70", + "ape": "\u224A", + "apid": "\u224B", + "apos": "'", + "ApplyFunction": "\u2061", + "approx": "\u2248", + "approxeq": "\u224A", + "Aring": "\xC5", + "aring": "\xE5", + "Ascr": "\uD835\uDC9C", + "ascr": "\uD835\uDCB6", + "Assign": "\u2254", + "ast": "*", + "asymp": "\u2248", + "asympeq": "\u224D", + "Atilde": "\xC3", + "atilde": "\xE3", + "Auml": "\xC4", + "auml": "\xE4", + "awconint": "\u2233", + "awint": "\u2A11", + "backcong": "\u224C", + "backepsilon": "\u03F6", + "backprime": "\u2035", + "backsim": "\u223D", + "backsimeq": "\u22CD", + "Backslash": "\u2216", + "Barv": "\u2AE7", + "barvee": "\u22BD", + "Barwed": "\u2306", + "barwed": "\u2305", + "barwedge": "\u2305", + "bbrk": "\u23B5", + "bbrktbrk": "\u23B6", + "bcong": "\u224C", + "Bcy": "\u0411", + "bcy": "\u0431", + "bdquo": "\u201E", + "becaus": "\u2235", + "Because": "\u2235", + "because": "\u2235", + "bemptyv": "\u29B0", + "bepsi": "\u03F6", + "bernou": "\u212C", + "Bernoullis": "\u212C", + "Beta": "\u0392", + "beta": "\u03B2", + "beth": "\u2136", + "between": "\u226C", + "Bfr": "\uD835\uDD05", + "bfr": "\uD835\uDD1F", + "bigcap": "\u22C2", + "bigcirc": "\u25EF", + "bigcup": "\u22C3", + "bigodot": "\u2A00", + "bigoplus": "\u2A01", + "bigotimes": "\u2A02", + "bigsqcup": "\u2A06", + "bigstar": "\u2605", + "bigtriangledown": "\u25BD", + "bigtriangleup": "\u25B3", + "biguplus": "\u2A04", + "bigvee": "\u22C1", + "bigwedge": "\u22C0", + "bkarow": "\u290D", + "blacklozenge": "\u29EB", + "blacksquare": "\u25AA", + "blacktriangle": "\u25B4", + "blacktriangledown": "\u25BE", + "blacktriangleleft": "\u25C2", + "blacktriangleright": "\u25B8", + "blank": "\u2423", + "blk12": "\u2592", + "blk14": "\u2591", + "blk34": "\u2593", + "block": "\u2588", + "bne": "=\u20E5", + "bnequiv": "\u2261\u20E5", + "bNot": "\u2AED", + "bnot": "\u2310", + "Bopf": "\uD835\uDD39", + "bopf": "\uD835\uDD53", + "bot": "\u22A5", + "bottom": "\u22A5", + "bowtie": "\u22C8", + "boxbox": "\u29C9", + "boxDL": "\u2557", + "boxDl": "\u2556", + "boxdL": "\u2555", + "boxdl": "\u2510", + "boxDR": "\u2554", + "boxDr": "\u2553", + "boxdR": "\u2552", + "boxdr": "\u250C", + "boxH": "\u2550", + "boxh": "\u2500", + "boxHD": "\u2566", + "boxHd": "\u2564", + "boxhD": "\u2565", + "boxhd": "\u252C", + "boxHU": "\u2569", + "boxHu": "\u2567", + "boxhU": "\u2568", + "boxhu": "\u2534", + "boxminus": "\u229F", + "boxplus": "\u229E", + "boxtimes": "\u22A0", + "boxUL": "\u255D", + "boxUl": "\u255C", + "boxuL": "\u255B", + "boxul": "\u2518", + "boxUR": "\u255A", + "boxUr": "\u2559", + "boxuR": "\u2558", + "boxur": "\u2514", + "boxV": "\u2551", + "boxv": "\u2502", + "boxVH": "\u256C", + "boxVh": "\u256B", + "boxvH": "\u256A", + "boxvh": "\u253C", + "boxVL": "\u2563", + "boxVl": "\u2562", + "boxvL": "\u2561", + "boxvl": "\u2524", + "boxVR": "\u2560", + "boxVr": "\u255F", + "boxvR": "\u255E", + "boxvr": "\u251C", + "bprime": "\u2035", + "Breve": "\u02D8", + "breve": "\u02D8", + "brvbar": "\xA6", + "Bscr": "\u212C", + "bscr": "\uD835\uDCB7", + "bsemi": "\u204F", + "bsim": "\u223D", + "bsime": "\u22CD", + "bsol": "\\", + "bsolb": "\u29C5", + "bsolhsub": "\u27C8", + "bull": "\u2022", + "bullet": "\u2022", + "bump": "\u224E", + "bumpE": "\u2AAE", + "bumpe": "\u224F", + "Bumpeq": "\u224E", + "bumpeq": "\u224F", + "Cacute": "\u0106", + "cacute": "\u0107", + "Cap": "\u22D2", + "cap": "\u2229", + "capand": "\u2A44", + "capbrcup": "\u2A49", + "capcap": "\u2A4B", + "capcup": "\u2A47", + "capdot": "\u2A40", + "CapitalDifferentialD": "\u2145", + "caps": "\u2229\uFE00", + "caret": "\u2041", + "caron": "\u02C7", + "Cayleys": "\u212D", + "ccaps": "\u2A4D", + "Ccaron": "\u010C", + "ccaron": "\u010D", + "Ccedil": "\xC7", + "ccedil": "\xE7", + "Ccirc": "\u0108", + "ccirc": "\u0109", + "Cconint": "\u2230", + "ccups": "\u2A4C", + "ccupssm": "\u2A50", + "Cdot": "\u010A", + "cdot": "\u010B", + "cedil": "\xB8", + "Cedilla": "\xB8", + "cemptyv": "\u29B2", + "cent": "\xA2", + "CenterDot": "\xB7", + "centerdot": "\xB7", + "Cfr": "\u212D", + "cfr": "\uD835\uDD20", + "CHcy": "\u0427", + "chcy": "\u0447", + "check": "\u2713", + "checkmark": "\u2713", + "Chi": "\u03A7", + "chi": "\u03C7", + "cir": "\u25CB", + "circ": "\u02C6", + "circeq": "\u2257", + "circlearrowleft": "\u21BA", + "circlearrowright": "\u21BB", + "circledast": "\u229B", + "circledcirc": "\u229A", + "circleddash": "\u229D", + "CircleDot": "\u2299", + "circledR": "\xAE", + "circledS": "\u24C8", + "CircleMinus": "\u2296", + "CirclePlus": "\u2295", + "CircleTimes": "\u2297", + "cirE": "\u29C3", + "cire": "\u2257", + "cirfnint": "\u2A10", + "cirmid": "\u2AEF", + "cirscir": "\u29C2", + "ClockwiseContourIntegral": "\u2232", + "CloseCurlyDoubleQuote": "\u201D", + "CloseCurlyQuote": "\u2019", + "clubs": "\u2663", + "clubsuit": "\u2663", + "Colon": "\u2237", + "colon": ":", + "Colone": "\u2A74", + "colone": "\u2254", + "coloneq": "\u2254", + "comma": ",", + "commat": "@", + "comp": "\u2201", + "compfn": "\u2218", + "complement": "\u2201", + "complexes": "\u2102", + "cong": "\u2245", + "congdot": "\u2A6D", + "Congruent": "\u2261", + "Conint": "\u222F", + "conint": "\u222E", + "ContourIntegral": "\u222E", + "Copf": "\u2102", + "copf": "\uD835\uDD54", + "coprod": "\u2210", + "Coproduct": "\u2210", + "COPY": "\xA9", + "copy": "\xA9", + "copysr": "\u2117", + "CounterClockwiseContourIntegral": "\u2233", + "crarr": "\u21B5", + "Cross": "\u2A2F", + "cross": "\u2717", + "Cscr": "\uD835\uDC9E", + "cscr": "\uD835\uDCB8", + "csub": "\u2ACF", + "csube": "\u2AD1", + "csup": "\u2AD0", + "csupe": "\u2AD2", + "ctdot": "\u22EF", + "cudarrl": "\u2938", + "cudarrr": "\u2935", + "cuepr": "\u22DE", + "cuesc": "\u22DF", + "cularr": "\u21B6", + "cularrp": "\u293D", + "Cup": "\u22D3", + "cup": "\u222A", + "cupbrcap": "\u2A48", + "CupCap": "\u224D", + "cupcap": "\u2A46", + "cupcup": "\u2A4A", + "cupdot": "\u228D", + "cupor": "\u2A45", + "cups": "\u222A\uFE00", + "curarr": "\u21B7", + "curarrm": "\u293C", + "curlyeqprec": "\u22DE", + "curlyeqsucc": "\u22DF", + "curlyvee": "\u22CE", + "curlywedge": "\u22CF", + "curren": "\xA4", + "curvearrowleft": "\u21B6", + "curvearrowright": "\u21B7", + "cuvee": "\u22CE", + "cuwed": "\u22CF", + "cwconint": "\u2232", + "cwint": "\u2231", + "cylcty": "\u232D", + "Dagger": "\u2021", + "dagger": "\u2020", + "daleth": "\u2138", + "Darr": "\u21A1", + "dArr": "\u21D3", + "darr": "\u2193", + "dash": "\u2010", + "Dashv": "\u2AE4", + "dashv": "\u22A3", + "dbkarow": "\u290F", + "dblac": "\u02DD", + "Dcaron": "\u010E", + "dcaron": "\u010F", + "Dcy": "\u0414", + "dcy": "\u0434", + "DD": "\u2145", + "dd": "\u2146", + "ddagger": "\u2021", + "ddarr": "\u21CA", + "DDotrahd": "\u2911", + "ddotseq": "\u2A77", + "deg": "\xB0", + "Del": "\u2207", + "Delta": "\u0394", + "delta": "\u03B4", + "demptyv": "\u29B1", + "dfisht": "\u297F", + "Dfr": "\uD835\uDD07", + "dfr": "\uD835\uDD21", + "dHar": "\u2965", + "dharl": "\u21C3", + "dharr": "\u21C2", + "DiacriticalAcute": "\xB4", + "DiacriticalDot": "\u02D9", + "DiacriticalDoubleAcute": "\u02DD", + "DiacriticalGrave": "`", + "DiacriticalTilde": "\u02DC", + "diam": "\u22C4", + "Diamond": "\u22C4", + "diamond": "\u22C4", + "diamondsuit": "\u2666", + "diams": "\u2666", + "die": "\xA8", + "DifferentialD": "\u2146", + "digamma": "\u03DD", + "disin": "\u22F2", + "div": "\xF7", + "divide": "\xF7", + "divideontimes": "\u22C7", + "divonx": "\u22C7", + "DJcy": "\u0402", + "djcy": "\u0452", + "dlcorn": "\u231E", + "dlcrop": "\u230D", + "dollar": "$", + "Dopf": "\uD835\uDD3B", + "dopf": "\uD835\uDD55", + "Dot": "\xA8", + "dot": "\u02D9", + "DotDot": "\u20DC", + "doteq": "\u2250", + "doteqdot": "\u2251", + "DotEqual": "\u2250", + "dotminus": "\u2238", + "dotplus": "\u2214", + "dotsquare": "\u22A1", + "doublebarwedge": "\u2306", + "DoubleContourIntegral": "\u222F", + "DoubleDot": "\xA8", + "DoubleDownArrow": "\u21D3", + "DoubleLeftArrow": "\u21D0", + "DoubleLeftRightArrow": "\u21D4", + "DoubleLeftTee": "\u2AE4", + "DoubleLongLeftArrow": "\u27F8", + "DoubleLongLeftRightArrow": "\u27FA", + "DoubleLongRightArrow": "\u27F9", + "DoubleRightArrow": "\u21D2", + "DoubleRightTee": "\u22A8", + "DoubleUpArrow": "\u21D1", + "DoubleUpDownArrow": "\u21D5", + "DoubleVerticalBar": "\u2225", + "DownArrow": "\u2193", + "Downarrow": "\u21D3", + "downarrow": "\u2193", + "DownArrowBar": "\u2913", + "DownArrowUpArrow": "\u21F5", + "DownBreve": "\u0311", + "downdownarrows": "\u21CA", + "downharpoonleft": "\u21C3", + "downharpoonright": "\u21C2", + "DownLeftRightVector": "\u2950", + "DownLeftTeeVector": "\u295E", + "DownLeftVector": "\u21BD", + "DownLeftVectorBar": "\u2956", + "DownRightTeeVector": "\u295F", + "DownRightVector": "\u21C1", + "DownRightVectorBar": "\u2957", + "DownTee": "\u22A4", + "DownTeeArrow": "\u21A7", + "drbkarow": "\u2910", + "drcorn": "\u231F", + "drcrop": "\u230C", + "Dscr": "\uD835\uDC9F", + "dscr": "\uD835\uDCB9", + "DScy": "\u0405", + "dscy": "\u0455", + "dsol": "\u29F6", + "Dstrok": "\u0110", + "dstrok": "\u0111", + "dtdot": "\u22F1", + "dtri": "\u25BF", + "dtrif": "\u25BE", + "duarr": "\u21F5", + "duhar": "\u296F", + "dwangle": "\u29A6", + "DZcy": "\u040F", + "dzcy": "\u045F", + "dzigrarr": "\u27FF", + "Eacute": "\xC9", + "eacute": "\xE9", + "easter": "\u2A6E", + "Ecaron": "\u011A", + "ecaron": "\u011B", + "ecir": "\u2256", + "Ecirc": "\xCA", + "ecirc": "\xEA", + "ecolon": "\u2255", + "Ecy": "\u042D", + "ecy": "\u044D", + "eDDot": "\u2A77", + "Edot": "\u0116", + "eDot": "\u2251", + "edot": "\u0117", + "ee": "\u2147", + "efDot": "\u2252", + "Efr": "\uD835\uDD08", + "efr": "\uD835\uDD22", + "eg": "\u2A9A", + "Egrave": "\xC8", + "egrave": "\xE8", + "egs": "\u2A96", + "egsdot": "\u2A98", + "el": "\u2A99", + "Element": "\u2208", + "elinters": "\u23E7", + "ell": "\u2113", + "els": "\u2A95", + "elsdot": "\u2A97", + "Emacr": "\u0112", + "emacr": "\u0113", + "empty": "\u2205", + "emptyset": "\u2205", + "EmptySmallSquare": "\u25FB", + "emptyv": "\u2205", + "EmptyVerySmallSquare": "\u25AB", + "emsp": "\u2003", + "emsp13": "\u2004", + "emsp14": "\u2005", + "ENG": "\u014A", + "eng": "\u014B", + "ensp": "\u2002", + "Eogon": "\u0118", + "eogon": "\u0119", + "Eopf": "\uD835\uDD3C", + "eopf": "\uD835\uDD56", + "epar": "\u22D5", + "eparsl": "\u29E3", + "eplus": "\u2A71", + "epsi": "\u03B5", + "Epsilon": "\u0395", + "epsilon": "\u03B5", + "epsiv": "\u03F5", + "eqcirc": "\u2256", + "eqcolon": "\u2255", + "eqsim": "\u2242", + "eqslantgtr": "\u2A96", + "eqslantless": "\u2A95", + "Equal": "\u2A75", + "equals": "=", + "EqualTilde": "\u2242", + "equest": "\u225F", + "Equilibrium": "\u21CC", + "equiv": "\u2261", + "equivDD": "\u2A78", + "eqvparsl": "\u29E5", + "erarr": "\u2971", + "erDot": "\u2253", + "Escr": "\u2130", + "escr": "\u212F", + "esdot": "\u2250", + "Esim": "\u2A73", + "esim": "\u2242", + "Eta": "\u0397", + "eta": "\u03B7", + "ETH": "\xD0", + "eth": "\xF0", + "Euml": "\xCB", + "euml": "\xEB", + "euro": "\u20AC", + "excl": "!", + "exist": "\u2203", + "Exists": "\u2203", + "expectation": "\u2130", + "ExponentialE": "\u2147", + "exponentiale": "\u2147", + "fallingdotseq": "\u2252", + "Fcy": "\u0424", + "fcy": "\u0444", + "female": "\u2640", + "ffilig": "\uFB03", + "fflig": "\uFB00", + "ffllig": "\uFB04", + "Ffr": "\uD835\uDD09", + "ffr": "\uD835\uDD23", + "filig": "\uFB01", + "FilledSmallSquare": "\u25FC", + "FilledVerySmallSquare": "\u25AA", + "fjlig": "fj", + "flat": "\u266D", + "fllig": "\uFB02", + "fltns": "\u25B1", + "fnof": "\u0192", + "Fopf": "\uD835\uDD3D", + "fopf": "\uD835\uDD57", + "ForAll": "\u2200", + "forall": "\u2200", + "fork": "\u22D4", + "forkv": "\u2AD9", + "Fouriertrf": "\u2131", + "fpartint": "\u2A0D", + "frac12": "\xBD", + "frac13": "\u2153", + "frac14": "\xBC", + "frac15": "\u2155", + "frac16": "\u2159", + "frac18": "\u215B", + "frac23": "\u2154", + "frac25": "\u2156", + "frac34": "\xBE", + "frac35": "\u2157", + "frac38": "\u215C", + "frac45": "\u2158", + "frac56": "\u215A", + "frac58": "\u215D", + "frac78": "\u215E", + "frasl": "\u2044", + "frown": "\u2322", + "Fscr": "\u2131", + "fscr": "\uD835\uDCBB", + "gacute": "\u01F5", + "Gamma": "\u0393", + "gamma": "\u03B3", + "Gammad": "\u03DC", + "gammad": "\u03DD", + "gap": "\u2A86", + "Gbreve": "\u011E", + "gbreve": "\u011F", + "Gcedil": "\u0122", + "Gcirc": "\u011C", + "gcirc": "\u011D", + "Gcy": "\u0413", + "gcy": "\u0433", + "Gdot": "\u0120", + "gdot": "\u0121", + "gE": "\u2267", + "ge": "\u2265", + "gEl": "\u2A8C", + "gel": "\u22DB", + "geq": "\u2265", + "geqq": "\u2267", + "geqslant": "\u2A7E", + "ges": "\u2A7E", + "gescc": "\u2AA9", + "gesdot": "\u2A80", + "gesdoto": "\u2A82", + "gesdotol": "\u2A84", + "gesl": "\u22DB\uFE00", + "gesles": "\u2A94", + "Gfr": "\uD835\uDD0A", + "gfr": "\uD835\uDD24", + "Gg": "\u22D9", + "gg": "\u226B", + "ggg": "\u22D9", + "gimel": "\u2137", + "GJcy": "\u0403", + "gjcy": "\u0453", + "gl": "\u2277", + "gla": "\u2AA5", + "glE": "\u2A92", + "glj": "\u2AA4", + "gnap": "\u2A8A", + "gnapprox": "\u2A8A", + "gnE": "\u2269", + "gne": "\u2A88", + "gneq": "\u2A88", + "gneqq": "\u2269", + "gnsim": "\u22E7", + "Gopf": "\uD835\uDD3E", + "gopf": "\uD835\uDD58", + "grave": "`", + "GreaterEqual": "\u2265", + "GreaterEqualLess": "\u22DB", + "GreaterFullEqual": "\u2267", + "GreaterGreater": "\u2AA2", + "GreaterLess": "\u2277", + "GreaterSlantEqual": "\u2A7E", + "GreaterTilde": "\u2273", + "Gscr": "\uD835\uDCA2", + "gscr": "\u210A", + "gsim": "\u2273", + "gsime": "\u2A8E", + "gsiml": "\u2A90", + "GT": ">", + "Gt": "\u226B", + "gt": ">", + "gtcc": "\u2AA7", + "gtcir": "\u2A7A", + "gtdot": "\u22D7", + "gtlPar": "\u2995", + "gtquest": "\u2A7C", + "gtrapprox": "\u2A86", + "gtrarr": "\u2978", + "gtrdot": "\u22D7", + "gtreqless": "\u22DB", + "gtreqqless": "\u2A8C", + "gtrless": "\u2277", + "gtrsim": "\u2273", + "gvertneqq": "\u2269\uFE00", + "gvnE": "\u2269\uFE00", + "Hacek": "\u02C7", + "hairsp": "\u200A", + "half": "\xBD", + "hamilt": "\u210B", + "HARDcy": "\u042A", + "hardcy": "\u044A", + "hArr": "\u21D4", + "harr": "\u2194", + "harrcir": "\u2948", + "harrw": "\u21AD", + "Hat": "^", + "hbar": "\u210F", + "Hcirc": "\u0124", + "hcirc": "\u0125", + "hearts": "\u2665", + "heartsuit": "\u2665", + "hellip": "\u2026", + "hercon": "\u22B9", + "Hfr": "\u210C", + "hfr": "\uD835\uDD25", + "HilbertSpace": "\u210B", + "hksearow": "\u2925", + "hkswarow": "\u2926", + "hoarr": "\u21FF", + "homtht": "\u223B", + "hookleftarrow": "\u21A9", + "hookrightarrow": "\u21AA", + "Hopf": "\u210D", + "hopf": "\uD835\uDD59", + "horbar": "\u2015", + "HorizontalLine": "\u2500", + "Hscr": "\u210B", + "hscr": "\uD835\uDCBD", + "hslash": "\u210F", + "Hstrok": "\u0126", + "hstrok": "\u0127", + "HumpDownHump": "\u224E", + "HumpEqual": "\u224F", + "hybull": "\u2043", + "hyphen": "\u2010", + "Iacute": "\xCD", + "iacute": "\xED", + "ic": "\u2063", + "Icirc": "\xCE", + "icirc": "\xEE", + "Icy": "\u0418", + "icy": "\u0438", + "Idot": "\u0130", + "IEcy": "\u0415", + "iecy": "\u0435", + "iexcl": "\xA1", + "iff": "\u21D4", + "Ifr": "\u2111", + "ifr": "\uD835\uDD26", + "Igrave": "\xCC", + "igrave": "\xEC", + "ii": "\u2148", + "iiiint": "\u2A0C", + "iiint": "\u222D", + "iinfin": "\u29DC", + "iiota": "\u2129", + "IJlig": "\u0132", + "ijlig": "\u0133", + "Im": "\u2111", + "Imacr": "\u012A", + "imacr": "\u012B", + "image": "\u2111", + "ImaginaryI": "\u2148", + "imagline": "\u2110", + "imagpart": "\u2111", + "imath": "\u0131", + "imof": "\u22B7", + "imped": "\u01B5", + "Implies": "\u21D2", + "in": "\u2208", + "incare": "\u2105", + "infin": "\u221E", + "infintie": "\u29DD", + "inodot": "\u0131", + "Int": "\u222C", + "int": "\u222B", + "intcal": "\u22BA", + "integers": "\u2124", + "Integral": "\u222B", + "intercal": "\u22BA", + "Intersection": "\u22C2", + "intlarhk": "\u2A17", + "intprod": "\u2A3C", + "InvisibleComma": "\u2063", + "InvisibleTimes": "\u2062", + "IOcy": "\u0401", + "iocy": "\u0451", + "Iogon": "\u012E", + "iogon": "\u012F", + "Iopf": "\uD835\uDD40", + "iopf": "\uD835\uDD5A", + "Iota": "\u0399", + "iota": "\u03B9", + "iprod": "\u2A3C", + "iquest": "\xBF", + "Iscr": "\u2110", + "iscr": "\uD835\uDCBE", + "isin": "\u2208", + "isindot": "\u22F5", + "isinE": "\u22F9", + "isins": "\u22F4", + "isinsv": "\u22F3", + "isinv": "\u2208", + "it": "\u2062", + "Itilde": "\u0128", + "itilde": "\u0129", + "Iukcy": "\u0406", + "iukcy": "\u0456", + "Iuml": "\xCF", + "iuml": "\xEF", + "Jcirc": "\u0134", + "jcirc": "\u0135", + "Jcy": "\u0419", + "jcy": "\u0439", + "Jfr": "\uD835\uDD0D", + "jfr": "\uD835\uDD27", + "jmath": "\u0237", + "Jopf": "\uD835\uDD41", + "jopf": "\uD835\uDD5B", + "Jscr": "\uD835\uDCA5", + "jscr": "\uD835\uDCBF", + "Jsercy": "\u0408", + "jsercy": "\u0458", + "Jukcy": "\u0404", + "jukcy": "\u0454", + "Kappa": "\u039A", + "kappa": "\u03BA", + "kappav": "\u03F0", + "Kcedil": "\u0136", + "kcedil": "\u0137", + "Kcy": "\u041A", + "kcy": "\u043A", + "Kfr": "\uD835\uDD0E", + "kfr": "\uD835\uDD28", + "kgreen": "\u0138", + "KHcy": "\u0425", + "khcy": "\u0445", + "KJcy": "\u040C", + "kjcy": "\u045C", + "Kopf": "\uD835\uDD42", + "kopf": "\uD835\uDD5C", + "Kscr": "\uD835\uDCA6", + "kscr": "\uD835\uDCC0", + "lAarr": "\u21DA", + "Lacute": "\u0139", + "lacute": "\u013A", + "laemptyv": "\u29B4", + "lagran": "\u2112", + "Lambda": "\u039B", + "lambda": "\u03BB", + "Lang": "\u27EA", + "lang": "\u27E8", + "langd": "\u2991", + "langle": "\u27E8", + "lap": "\u2A85", + "Laplacetrf": "\u2112", + "laquo": "\xAB", + "Larr": "\u219E", + "lArr": "\u21D0", + "larr": "\u2190", + "larrb": "\u21E4", + "larrbfs": "\u291F", + "larrfs": "\u291D", + "larrhk": "\u21A9", + "larrlp": "\u21AB", + "larrpl": "\u2939", + "larrsim": "\u2973", + "larrtl": "\u21A2", + "lat": "\u2AAB", + "lAtail": "\u291B", + "latail": "\u2919", + "late": "\u2AAD", + "lates": "\u2AAD\uFE00", + "lBarr": "\u290E", + "lbarr": "\u290C", + "lbbrk": "\u2772", + "lbrace": "{", + "lbrack": "[", + "lbrke": "\u298B", + "lbrksld": "\u298F", + "lbrkslu": "\u298D", + "Lcaron": "\u013D", + "lcaron": "\u013E", + "Lcedil": "\u013B", + "lcedil": "\u013C", + "lceil": "\u2308", + "lcub": "{", + "Lcy": "\u041B", + "lcy": "\u043B", + "ldca": "\u2936", + "ldquo": "\u201C", + "ldquor": "\u201E", + "ldrdhar": "\u2967", + "ldrushar": "\u294B", + "ldsh": "\u21B2", + "lE": "\u2266", + "le": "\u2264", + "LeftAngleBracket": "\u27E8", + "LeftArrow": "\u2190", + "Leftarrow": "\u21D0", + "leftarrow": "\u2190", + "LeftArrowBar": "\u21E4", + "LeftArrowRightArrow": "\u21C6", + "leftarrowtail": "\u21A2", + "LeftCeiling": "\u2308", + "LeftDoubleBracket": "\u27E6", + "LeftDownTeeVector": "\u2961", + "LeftDownVector": "\u21C3", + "LeftDownVectorBar": "\u2959", + "LeftFloor": "\u230A", + "leftharpoondown": "\u21BD", + "leftharpoonup": "\u21BC", + "leftleftarrows": "\u21C7", + "LeftRightArrow": "\u2194", + "Leftrightarrow": "\u21D4", + "leftrightarrow": "\u2194", + "leftrightarrows": "\u21C6", + "leftrightharpoons": "\u21CB", + "leftrightsquigarrow": "\u21AD", + "LeftRightVector": "\u294E", + "LeftTee": "\u22A3", + "LeftTeeArrow": "\u21A4", + "LeftTeeVector": "\u295A", + "leftthreetimes": "\u22CB", + "LeftTriangle": "\u22B2", + "LeftTriangleBar": "\u29CF", + "LeftTriangleEqual": "\u22B4", + "LeftUpDownVector": "\u2951", + "LeftUpTeeVector": "\u2960", + "LeftUpVector": "\u21BF", + "LeftUpVectorBar": "\u2958", + "LeftVector": "\u21BC", + "LeftVectorBar": "\u2952", + "lEg": "\u2A8B", + "leg": "\u22DA", + "leq": "\u2264", + "leqq": "\u2266", + "leqslant": "\u2A7D", + "les": "\u2A7D", + "lescc": "\u2AA8", + "lesdot": "\u2A7F", + "lesdoto": "\u2A81", + "lesdotor": "\u2A83", + "lesg": "\u22DA\uFE00", + "lesges": "\u2A93", + "lessapprox": "\u2A85", + "lessdot": "\u22D6", + "lesseqgtr": "\u22DA", + "lesseqqgtr": "\u2A8B", + "LessEqualGreater": "\u22DA", + "LessFullEqual": "\u2266", + "LessGreater": "\u2276", + "lessgtr": "\u2276", + "LessLess": "\u2AA1", + "lesssim": "\u2272", + "LessSlantEqual": "\u2A7D", + "LessTilde": "\u2272", + "lfisht": "\u297C", + "lfloor": "\u230A", + "Lfr": "\uD835\uDD0F", + "lfr": "\uD835\uDD29", + "lg": "\u2276", + "lgE": "\u2A91", + "lHar": "\u2962", + "lhard": "\u21BD", + "lharu": "\u21BC", + "lharul": "\u296A", + "lhblk": "\u2584", + "LJcy": "\u0409", + "ljcy": "\u0459", + "Ll": "\u22D8", + "ll": "\u226A", + "llarr": "\u21C7", + "llcorner": "\u231E", + "Lleftarrow": "\u21DA", + "llhard": "\u296B", + "lltri": "\u25FA", + "Lmidot": "\u013F", + "lmidot": "\u0140", + "lmoust": "\u23B0", + "lmoustache": "\u23B0", + "lnap": "\u2A89", + "lnapprox": "\u2A89", + "lnE": "\u2268", + "lne": "\u2A87", + "lneq": "\u2A87", + "lneqq": "\u2268", + "lnsim": "\u22E6", + "loang": "\u27EC", + "loarr": "\u21FD", + "lobrk": "\u27E6", + "LongLeftArrow": "\u27F5", + "Longleftarrow": "\u27F8", + "longleftarrow": "\u27F5", + "LongLeftRightArrow": "\u27F7", + "Longleftrightarrow": "\u27FA", + "longleftrightarrow": "\u27F7", + "longmapsto": "\u27FC", + "LongRightArrow": "\u27F6", + "Longrightarrow": "\u27F9", + "longrightarrow": "\u27F6", + "looparrowleft": "\u21AB", + "looparrowright": "\u21AC", + "lopar": "\u2985", + "Lopf": "\uD835\uDD43", + "lopf": "\uD835\uDD5D", + "loplus": "\u2A2D", + "lotimes": "\u2A34", + "lowast": "\u2217", + "lowbar": "_", + "LowerLeftArrow": "\u2199", + "LowerRightArrow": "\u2198", + "loz": "\u25CA", + "lozenge": "\u25CA", + "lozf": "\u29EB", + "lpar": "(", + "lparlt": "\u2993", + "lrarr": "\u21C6", + "lrcorner": "\u231F", + "lrhar": "\u21CB", + "lrhard": "\u296D", + "lrm": "\u200E", + "lrtri": "\u22BF", + "lsaquo": "\u2039", + "Lscr": "\u2112", + "lscr": "\uD835\uDCC1", + "Lsh": "\u21B0", + "lsh": "\u21B0", + "lsim": "\u2272", + "lsime": "\u2A8D", + "lsimg": "\u2A8F", + "lsqb": "[", + "lsquo": "\u2018", + "lsquor": "\u201A", + "Lstrok": "\u0141", + "lstrok": "\u0142", + "LT": "<", + "Lt": "\u226A", + "lt": "<", + "ltcc": "\u2AA6", + "ltcir": "\u2A79", + "ltdot": "\u22D6", + "lthree": "\u22CB", + "ltimes": "\u22C9", + "ltlarr": "\u2976", + "ltquest": "\u2A7B", + "ltri": "\u25C3", + "ltrie": "\u22B4", + "ltrif": "\u25C2", + "ltrPar": "\u2996", + "lurdshar": "\u294A", + "luruhar": "\u2966", + "lvertneqq": "\u2268\uFE00", + "lvnE": "\u2268\uFE00", + "macr": "\xAF", + "male": "\u2642", + "malt": "\u2720", + "maltese": "\u2720", + "Map": "\u2905", + "map": "\u21A6", + "mapsto": "\u21A6", + "mapstodown": "\u21A7", + "mapstoleft": "\u21A4", + "mapstoup": "\u21A5", + "marker": "\u25AE", + "mcomma": "\u2A29", + "Mcy": "\u041C", + "mcy": "\u043C", + "mdash": "\u2014", + "mDDot": "\u223A", + "measuredangle": "\u2221", + "MediumSpace": "\u205F", + "Mellintrf": "\u2133", + "Mfr": "\uD835\uDD10", + "mfr": "\uD835\uDD2A", + "mho": "\u2127", + "micro": "\xB5", + "mid": "\u2223", + "midast": "*", + "midcir": "\u2AF0", + "middot": "\xB7", + "minus": "\u2212", + "minusb": "\u229F", + "minusd": "\u2238", + "minusdu": "\u2A2A", + "MinusPlus": "\u2213", + "mlcp": "\u2ADB", + "mldr": "\u2026", + "mnplus": "\u2213", + "models": "\u22A7", + "Mopf": "\uD835\uDD44", + "mopf": "\uD835\uDD5E", + "mp": "\u2213", + "Mscr": "\u2133", + "mscr": "\uD835\uDCC2", + "mstpos": "\u223E", + "Mu": "\u039C", + "mu": "\u03BC", + "multimap": "\u22B8", + "mumap": "\u22B8", + "nabla": "\u2207", + "Nacute": "\u0143", + "nacute": "\u0144", + "nang": "\u2220\u20D2", + "nap": "\u2249", + "napE": "\u2A70\u0338", + "napid": "\u224B\u0338", + "napos": "\u0149", + "napprox": "\u2249", + "natur": "\u266E", + "natural": "\u266E", + "naturals": "\u2115", + "nbsp": "\xA0", + "nbump": "\u224E\u0338", + "nbumpe": "\u224F\u0338", + "ncap": "\u2A43", + "Ncaron": "\u0147", + "ncaron": "\u0148", + "Ncedil": "\u0145", + "ncedil": "\u0146", + "ncong": "\u2247", + "ncongdot": "\u2A6D\u0338", + "ncup": "\u2A42", + "Ncy": "\u041D", + "ncy": "\u043D", + "ndash": "\u2013", + "ne": "\u2260", + "nearhk": "\u2924", + "neArr": "\u21D7", + "nearr": "\u2197", + "nearrow": "\u2197", + "nedot": "\u2250\u0338", + "NegativeMediumSpace": "\u200B", + "NegativeThickSpace": "\u200B", + "NegativeThinSpace": "\u200B", + "NegativeVeryThinSpace": "\u200B", + "nequiv": "\u2262", + "nesear": "\u2928", + "nesim": "\u2242\u0338", + "NestedGreaterGreater": "\u226B", + "NestedLessLess": "\u226A", + "NewLine": "\n", + "nexist": "\u2204", + "nexists": "\u2204", + "Nfr": "\uD835\uDD11", + "nfr": "\uD835\uDD2B", + "ngE": "\u2267\u0338", + "nge": "\u2271", + "ngeq": "\u2271", + "ngeqq": "\u2267\u0338", + "ngeqslant": "\u2A7E\u0338", + "nges": "\u2A7E\u0338", + "nGg": "\u22D9\u0338", + "ngsim": "\u2275", + "nGt": "\u226B\u20D2", + "ngt": "\u226F", + "ngtr": "\u226F", + "nGtv": "\u226B\u0338", + "nhArr": "\u21CE", + "nharr": "\u21AE", + "nhpar": "\u2AF2", + "ni": "\u220B", + "nis": "\u22FC", + "nisd": "\u22FA", + "niv": "\u220B", + "NJcy": "\u040A", + "njcy": "\u045A", + "nlArr": "\u21CD", + "nlarr": "\u219A", + "nldr": "\u2025", + "nlE": "\u2266\u0338", + "nle": "\u2270", + "nLeftarrow": "\u21CD", + "nleftarrow": "\u219A", + "nLeftrightarrow": "\u21CE", + "nleftrightarrow": "\u21AE", + "nleq": "\u2270", + "nleqq": "\u2266\u0338", + "nleqslant": "\u2A7D\u0338", + "nles": "\u2A7D\u0338", + "nless": "\u226E", + "nLl": "\u22D8\u0338", + "nlsim": "\u2274", + "nLt": "\u226A\u20D2", + "nlt": "\u226E", + "nltri": "\u22EA", + "nltrie": "\u22EC", + "nLtv": "\u226A\u0338", + "nmid": "\u2224", + "NoBreak": "\u2060", + "NonBreakingSpace": "\xA0", + "Nopf": "\u2115", + "nopf": "\uD835\uDD5F", + "Not": "\u2AEC", + "not": "\xAC", + "NotCongruent": "\u2262", + "NotCupCap": "\u226D", + "NotDoubleVerticalBar": "\u2226", + "NotElement": "\u2209", + "NotEqual": "\u2260", + "NotEqualTilde": "\u2242\u0338", + "NotExists": "\u2204", + "NotGreater": "\u226F", + "NotGreaterEqual": "\u2271", + "NotGreaterFullEqual": "\u2267\u0338", + "NotGreaterGreater": "\u226B\u0338", + "NotGreaterLess": "\u2279", + "NotGreaterSlantEqual": "\u2A7E\u0338", + "NotGreaterTilde": "\u2275", + "NotHumpDownHump": "\u224E\u0338", + "NotHumpEqual": "\u224F\u0338", + "notin": "\u2209", + "notindot": "\u22F5\u0338", + "notinE": "\u22F9\u0338", + "notinva": "\u2209", + "notinvb": "\u22F7", + "notinvc": "\u22F6", + "NotLeftTriangle": "\u22EA", + "NotLeftTriangleBar": "\u29CF\u0338", + "NotLeftTriangleEqual": "\u22EC", + "NotLess": "\u226E", + "NotLessEqual": "\u2270", + "NotLessGreater": "\u2278", + "NotLessLess": "\u226A\u0338", + "NotLessSlantEqual": "\u2A7D\u0338", + "NotLessTilde": "\u2274", + "NotNestedGreaterGreater": "\u2AA2\u0338", + "NotNestedLessLess": "\u2AA1\u0338", + "notni": "\u220C", + "notniva": "\u220C", + "notnivb": "\u22FE", + "notnivc": "\u22FD", + "NotPrecedes": "\u2280", + "NotPrecedesEqual": "\u2AAF\u0338", + "NotPrecedesSlantEqual": "\u22E0", + "NotReverseElement": "\u220C", + "NotRightTriangle": "\u22EB", + "NotRightTriangleBar": "\u29D0\u0338", + "NotRightTriangleEqual": "\u22ED", + "NotSquareSubset": "\u228F\u0338", + "NotSquareSubsetEqual": "\u22E2", + "NotSquareSuperset": "\u2290\u0338", + "NotSquareSupersetEqual": "\u22E3", + "NotSubset": "\u2282\u20D2", + "NotSubsetEqual": "\u2288", + "NotSucceeds": "\u2281", + "NotSucceedsEqual": "\u2AB0\u0338", + "NotSucceedsSlantEqual": "\u22E1", + "NotSucceedsTilde": "\u227F\u0338", + "NotSuperset": "\u2283\u20D2", + "NotSupersetEqual": "\u2289", + "NotTilde": "\u2241", + "NotTildeEqual": "\u2244", + "NotTildeFullEqual": "\u2247", + "NotTildeTilde": "\u2249", + "NotVerticalBar": "\u2224", + "npar": "\u2226", + "nparallel": "\u2226", + "nparsl": "\u2AFD\u20E5", + "npart": "\u2202\u0338", + "npolint": "\u2A14", + "npr": "\u2280", + "nprcue": "\u22E0", + "npre": "\u2AAF\u0338", + "nprec": "\u2280", + "npreceq": "\u2AAF\u0338", + "nrArr": "\u21CF", + "nrarr": "\u219B", + "nrarrc": "\u2933\u0338", + "nrarrw": "\u219D\u0338", + "nRightarrow": "\u21CF", + "nrightarrow": "\u219B", + "nrtri": "\u22EB", + "nrtrie": "\u22ED", + "nsc": "\u2281", + "nsccue": "\u22E1", + "nsce": "\u2AB0\u0338", + "Nscr": "\uD835\uDCA9", + "nscr": "\uD835\uDCC3", + "nshortmid": "\u2224", + "nshortparallel": "\u2226", + "nsim": "\u2241", + "nsime": "\u2244", + "nsimeq": "\u2244", + "nsmid": "\u2224", + "nspar": "\u2226", + "nsqsube": "\u22E2", + "nsqsupe": "\u22E3", + "nsub": "\u2284", + "nsubE": "\u2AC5\u0338", + "nsube": "\u2288", + "nsubset": "\u2282\u20D2", + "nsubseteq": "\u2288", + "nsubseteqq": "\u2AC5\u0338", + "nsucc": "\u2281", + "nsucceq": "\u2AB0\u0338", + "nsup": "\u2285", + "nsupE": "\u2AC6\u0338", + "nsupe": "\u2289", + "nsupset": "\u2283\u20D2", + "nsupseteq": "\u2289", + "nsupseteqq": "\u2AC6\u0338", + "ntgl": "\u2279", + "Ntilde": "\xD1", + "ntilde": "\xF1", + "ntlg": "\u2278", + "ntriangleleft": "\u22EA", + "ntrianglelefteq": "\u22EC", + "ntriangleright": "\u22EB", + "ntrianglerighteq": "\u22ED", + "Nu": "\u039D", + "nu": "\u03BD", + "num": "#", + "numero": "\u2116", + "numsp": "\u2007", + "nvap": "\u224D\u20D2", + "nVDash": "\u22AF", + "nVdash": "\u22AE", + "nvDash": "\u22AD", + "nvdash": "\u22AC", + "nvge": "\u2265\u20D2", + "nvgt": ">\u20D2", + "nvHarr": "\u2904", + "nvinfin": "\u29DE", + "nvlArr": "\u2902", + "nvle": "\u2264\u20D2", + "nvlt": "<\u20D2", + "nvltrie": "\u22B4\u20D2", + "nvrArr": "\u2903", + "nvrtrie": "\u22B5\u20D2", + "nvsim": "\u223C\u20D2", + "nwarhk": "\u2923", + "nwArr": "\u21D6", + "nwarr": "\u2196", + "nwarrow": "\u2196", + "nwnear": "\u2927", + "Oacute": "\xD3", + "oacute": "\xF3", + "oast": "\u229B", + "ocir": "\u229A", + "Ocirc": "\xD4", + "ocirc": "\xF4", + "Ocy": "\u041E", + "ocy": "\u043E", + "odash": "\u229D", + "Odblac": "\u0150", + "odblac": "\u0151", + "odiv": "\u2A38", + "odot": "\u2299", + "odsold": "\u29BC", + "OElig": "\u0152", + "oelig": "\u0153", + "ofcir": "\u29BF", + "Ofr": "\uD835\uDD12", + "ofr": "\uD835\uDD2C", + "ogon": "\u02DB", + "Ograve": "\xD2", + "ograve": "\xF2", + "ogt": "\u29C1", + "ohbar": "\u29B5", + "ohm": "\u03A9", + "oint": "\u222E", + "olarr": "\u21BA", + "olcir": "\u29BE", + "olcross": "\u29BB", + "oline": "\u203E", + "olt": "\u29C0", + "Omacr": "\u014C", + "omacr": "\u014D", + "Omega": "\u03A9", + "omega": "\u03C9", + "Omicron": "\u039F", + "omicron": "\u03BF", + "omid": "\u29B6", + "ominus": "\u2296", + "Oopf": "\uD835\uDD46", + "oopf": "\uD835\uDD60", + "opar": "\u29B7", + "OpenCurlyDoubleQuote": "\u201C", + "OpenCurlyQuote": "\u2018", + "operp": "\u29B9", + "oplus": "\u2295", + "Or": "\u2A54", + "or": "\u2228", + "orarr": "\u21BB", + "ord": "\u2A5D", + "order": "\u2134", + "orderof": "\u2134", + "ordf": "\xAA", + "ordm": "\xBA", + "origof": "\u22B6", + "oror": "\u2A56", + "orslope": "\u2A57", + "orv": "\u2A5B", + "oS": "\u24C8", + "Oscr": "\uD835\uDCAA", + "oscr": "\u2134", + "Oslash": "\xD8", + "oslash": "\xF8", + "osol": "\u2298", + "Otilde": "\xD5", + "otilde": "\xF5", + "Otimes": "\u2A37", + "otimes": "\u2297", + "otimesas": "\u2A36", + "Ouml": "\xD6", + "ouml": "\xF6", + "ovbar": "\u233D", + "OverBar": "\u203E", + "OverBrace": "\u23DE", + "OverBracket": "\u23B4", + "OverParenthesis": "\u23DC", + "par": "\u2225", + "para": "\xB6", + "parallel": "\u2225", + "parsim": "\u2AF3", + "parsl": "\u2AFD", + "part": "\u2202", + "PartialD": "\u2202", + "Pcy": "\u041F", + "pcy": "\u043F", + "percnt": "%", + "period": ".", + "permil": "\u2030", + "perp": "\u22A5", + "pertenk": "\u2031", + "Pfr": "\uD835\uDD13", + "pfr": "\uD835\uDD2D", + "Phi": "\u03A6", + "phi": "\u03C6", + "phiv": "\u03D5", + "phmmat": "\u2133", + "phone": "\u260E", + "Pi": "\u03A0", + "pi": "\u03C0", + "pitchfork": "\u22D4", + "piv": "\u03D6", + "planck": "\u210F", + "planckh": "\u210E", + "plankv": "\u210F", + "plus": "+", + "plusacir": "\u2A23", + "plusb": "\u229E", + "pluscir": "\u2A22", + "plusdo": "\u2214", + "plusdu": "\u2A25", + "pluse": "\u2A72", + "PlusMinus": "\xB1", + "plusmn": "\xB1", + "plussim": "\u2A26", + "plustwo": "\u2A27", + "pm": "\xB1", + "Poincareplane": "\u210C", + "pointint": "\u2A15", + "Popf": "\u2119", + "popf": "\uD835\uDD61", + "pound": "\xA3", + "Pr": "\u2ABB", + "pr": "\u227A", + "prap": "\u2AB7", + "prcue": "\u227C", + "prE": "\u2AB3", + "pre": "\u2AAF", + "prec": "\u227A", + "precapprox": "\u2AB7", + "preccurlyeq": "\u227C", + "Precedes": "\u227A", + "PrecedesEqual": "\u2AAF", + "PrecedesSlantEqual": "\u227C", + "PrecedesTilde": "\u227E", + "preceq": "\u2AAF", + "precnapprox": "\u2AB9", + "precneqq": "\u2AB5", + "precnsim": "\u22E8", + "precsim": "\u227E", + "Prime": "\u2033", + "prime": "\u2032", + "primes": "\u2119", + "prnap": "\u2AB9", + "prnE": "\u2AB5", + "prnsim": "\u22E8", + "prod": "\u220F", + "Product": "\u220F", + "profalar": "\u232E", + "profline": "\u2312", + "profsurf": "\u2313", + "prop": "\u221D", + "Proportion": "\u2237", + "Proportional": "\u221D", + "propto": "\u221D", + "prsim": "\u227E", + "prurel": "\u22B0", + "Pscr": "\uD835\uDCAB", + "pscr": "\uD835\uDCC5", + "Psi": "\u03A8", + "psi": "\u03C8", + "puncsp": "\u2008", + "Qfr": "\uD835\uDD14", + "qfr": "\uD835\uDD2E", + "qint": "\u2A0C", + "Qopf": "\u211A", + "qopf": "\uD835\uDD62", + "qprime": "\u2057", + "Qscr": "\uD835\uDCAC", + "qscr": "\uD835\uDCC6", + "quaternions": "\u210D", + "quatint": "\u2A16", + "quest": "?", + "questeq": "\u225F", + "QUOT": "\"", + "quot": "\"", + "rAarr": "\u21DB", + "race": "\u223D\u0331", + "Racute": "\u0154", + "racute": "\u0155", + "radic": "\u221A", + "raemptyv": "\u29B3", + "Rang": "\u27EB", + "rang": "\u27E9", + "rangd": "\u2992", + "range": "\u29A5", + "rangle": "\u27E9", + "raquo": "\xBB", + "Rarr": "\u21A0", + "rArr": "\u21D2", + "rarr": "\u2192", + "rarrap": "\u2975", + "rarrb": "\u21E5", + "rarrbfs": "\u2920", + "rarrc": "\u2933", + "rarrfs": "\u291E", + "rarrhk": "\u21AA", + "rarrlp": "\u21AC", + "rarrpl": "\u2945", + "rarrsim": "\u2974", + "Rarrtl": "\u2916", + "rarrtl": "\u21A3", + "rarrw": "\u219D", + "rAtail": "\u291C", + "ratail": "\u291A", + "ratio": "\u2236", + "rationals": "\u211A", + "RBarr": "\u2910", + "rBarr": "\u290F", + "rbarr": "\u290D", + "rbbrk": "\u2773", + "rbrace": "}", + "rbrack": "]", + "rbrke": "\u298C", + "rbrksld": "\u298E", + "rbrkslu": "\u2990", + "Rcaron": "\u0158", + "rcaron": "\u0159", + "Rcedil": "\u0156", + "rcedil": "\u0157", + "rceil": "\u2309", + "rcub": "}", + "Rcy": "\u0420", + "rcy": "\u0440", + "rdca": "\u2937", + "rdldhar": "\u2969", + "rdquo": "\u201D", + "rdquor": "\u201D", + "rdsh": "\u21B3", + "Re": "\u211C", + "real": "\u211C", + "realine": "\u211B", + "realpart": "\u211C", + "reals": "\u211D", + "rect": "\u25AD", + "REG": "\xAE", + "reg": "\xAE", + "ReverseElement": "\u220B", + "ReverseEquilibrium": "\u21CB", + "ReverseUpEquilibrium": "\u296F", + "rfisht": "\u297D", + "rfloor": "\u230B", + "Rfr": "\u211C", + "rfr": "\uD835\uDD2F", + "rHar": "\u2964", + "rhard": "\u21C1", + "rharu": "\u21C0", + "rharul": "\u296C", + "Rho": "\u03A1", + "rho": "\u03C1", + "rhov": "\u03F1", + "RightAngleBracket": "\u27E9", + "RightArrow": "\u2192", + "Rightarrow": "\u21D2", + "rightarrow": "\u2192", + "RightArrowBar": "\u21E5", + "RightArrowLeftArrow": "\u21C4", + "rightarrowtail": "\u21A3", + "RightCeiling": "\u2309", + "RightDoubleBracket": "\u27E7", + "RightDownTeeVector": "\u295D", + "RightDownVector": "\u21C2", + "RightDownVectorBar": "\u2955", + "RightFloor": "\u230B", + "rightharpoondown": "\u21C1", + "rightharpoonup": "\u21C0", + "rightleftarrows": "\u21C4", + "rightleftharpoons": "\u21CC", + "rightrightarrows": "\u21C9", + "rightsquigarrow": "\u219D", + "RightTee": "\u22A2", + "RightTeeArrow": "\u21A6", + "RightTeeVector": "\u295B", + "rightthreetimes": "\u22CC", + "RightTriangle": "\u22B3", + "RightTriangleBar": "\u29D0", + "RightTriangleEqual": "\u22B5", + "RightUpDownVector": "\u294F", + "RightUpTeeVector": "\u295C", + "RightUpVector": "\u21BE", + "RightUpVectorBar": "\u2954", + "RightVector": "\u21C0", + "RightVectorBar": "\u2953", + "ring": "\u02DA", + "risingdotseq": "\u2253", + "rlarr": "\u21C4", + "rlhar": "\u21CC", + "rlm": "\u200F", + "rmoust": "\u23B1", + "rmoustache": "\u23B1", + "rnmid": "\u2AEE", + "roang": "\u27ED", + "roarr": "\u21FE", + "robrk": "\u27E7", + "ropar": "\u2986", + "Ropf": "\u211D", + "ropf": "\uD835\uDD63", + "roplus": "\u2A2E", + "rotimes": "\u2A35", + "RoundImplies": "\u2970", + "rpar": ")", + "rpargt": "\u2994", + "rppolint": "\u2A12", + "rrarr": "\u21C9", + "Rrightarrow": "\u21DB", + "rsaquo": "\u203A", + "Rscr": "\u211B", + "rscr": "\uD835\uDCC7", + "Rsh": "\u21B1", + "rsh": "\u21B1", + "rsqb": "]", + "rsquo": "\u2019", + "rsquor": "\u2019", + "rthree": "\u22CC", + "rtimes": "\u22CA", + "rtri": "\u25B9", + "rtrie": "\u22B5", + "rtrif": "\u25B8", + "rtriltri": "\u29CE", + "RuleDelayed": "\u29F4", + "ruluhar": "\u2968", + "rx": "\u211E", + "Sacute": "\u015A", + "sacute": "\u015B", + "sbquo": "\u201A", + "Sc": "\u2ABC", + "sc": "\u227B", + "scap": "\u2AB8", + "Scaron": "\u0160", + "scaron": "\u0161", + "sccue": "\u227D", + "scE": "\u2AB4", + "sce": "\u2AB0", + "Scedil": "\u015E", + "scedil": "\u015F", + "Scirc": "\u015C", + "scirc": "\u015D", + "scnap": "\u2ABA", + "scnE": "\u2AB6", + "scnsim": "\u22E9", + "scpolint": "\u2A13", + "scsim": "\u227F", + "Scy": "\u0421", + "scy": "\u0441", + "sdot": "\u22C5", + "sdotb": "\u22A1", + "sdote": "\u2A66", + "searhk": "\u2925", + "seArr": "\u21D8", + "searr": "\u2198", + "searrow": "\u2198", + "sect": "\xA7", + "semi": ";", + "seswar": "\u2929", + "setminus": "\u2216", + "setmn": "\u2216", + "sext": "\u2736", + "Sfr": "\uD835\uDD16", + "sfr": "\uD835\uDD30", + "sfrown": "\u2322", + "sharp": "\u266F", + "SHCHcy": "\u0429", + "shchcy": "\u0449", + "SHcy": "\u0428", + "shcy": "\u0448", + "ShortDownArrow": "\u2193", + "ShortLeftArrow": "\u2190", + "shortmid": "\u2223", + "shortparallel": "\u2225", + "ShortRightArrow": "\u2192", + "ShortUpArrow": "\u2191", + "shy": "\xAD", + "Sigma": "\u03A3", + "sigma": "\u03C3", + "sigmaf": "\u03C2", + "sigmav": "\u03C2", + "sim": "\u223C", + "simdot": "\u2A6A", + "sime": "\u2243", + "simeq": "\u2243", + "simg": "\u2A9E", + "simgE": "\u2AA0", + "siml": "\u2A9D", + "simlE": "\u2A9F", + "simne": "\u2246", + "simplus": "\u2A24", + "simrarr": "\u2972", + "slarr": "\u2190", + "SmallCircle": "\u2218", + "smallsetminus": "\u2216", + "smashp": "\u2A33", + "smeparsl": "\u29E4", + "smid": "\u2223", + "smile": "\u2323", + "smt": "\u2AAA", + "smte": "\u2AAC", + "smtes": "\u2AAC\uFE00", + "SOFTcy": "\u042C", + "softcy": "\u044C", + "sol": "/", + "solb": "\u29C4", + "solbar": "\u233F", + "Sopf": "\uD835\uDD4A", + "sopf": "\uD835\uDD64", + "spades": "\u2660", + "spadesuit": "\u2660", + "spar": "\u2225", + "sqcap": "\u2293", + "sqcaps": "\u2293\uFE00", + "sqcup": "\u2294", + "sqcups": "\u2294\uFE00", + "Sqrt": "\u221A", + "sqsub": "\u228F", + "sqsube": "\u2291", + "sqsubset": "\u228F", + "sqsubseteq": "\u2291", + "sqsup": "\u2290", + "sqsupe": "\u2292", + "sqsupset": "\u2290", + "sqsupseteq": "\u2292", + "squ": "\u25A1", + "Square": "\u25A1", + "square": "\u25A1", + "SquareIntersection": "\u2293", + "SquareSubset": "\u228F", + "SquareSubsetEqual": "\u2291", + "SquareSuperset": "\u2290", + "SquareSupersetEqual": "\u2292", + "SquareUnion": "\u2294", + "squarf": "\u25AA", + "squf": "\u25AA", + "srarr": "\u2192", + "Sscr": "\uD835\uDCAE", + "sscr": "\uD835\uDCC8", + "ssetmn": "\u2216", + "ssmile": "\u2323", + "sstarf": "\u22C6", + "Star": "\u22C6", + "star": "\u2606", + "starf": "\u2605", + "straightepsilon": "\u03F5", + "straightphi": "\u03D5", + "strns": "\xAF", + "Sub": "\u22D0", + "sub": "\u2282", + "subdot": "\u2ABD", + "subE": "\u2AC5", + "sube": "\u2286", + "subedot": "\u2AC3", + "submult": "\u2AC1", + "subnE": "\u2ACB", + "subne": "\u228A", + "subplus": "\u2ABF", + "subrarr": "\u2979", + "Subset": "\u22D0", + "subset": "\u2282", + "subseteq": "\u2286", + "subseteqq": "\u2AC5", + "SubsetEqual": "\u2286", + "subsetneq": "\u228A", + "subsetneqq": "\u2ACB", + "subsim": "\u2AC7", + "subsub": "\u2AD5", + "subsup": "\u2AD3", + "succ": "\u227B", + "succapprox": "\u2AB8", + "succcurlyeq": "\u227D", + "Succeeds": "\u227B", + "SucceedsEqual": "\u2AB0", + "SucceedsSlantEqual": "\u227D", + "SucceedsTilde": "\u227F", + "succeq": "\u2AB0", + "succnapprox": "\u2ABA", + "succneqq": "\u2AB6", + "succnsim": "\u22E9", + "succsim": "\u227F", + "SuchThat": "\u220B", + "Sum": "\u2211", + "sum": "\u2211", + "sung": "\u266A", + "Sup": "\u22D1", + "sup": "\u2283", + "sup1": "\xB9", + "sup2": "\xB2", + "sup3": "\xB3", + "supdot": "\u2ABE", + "supdsub": "\u2AD8", + "supE": "\u2AC6", + "supe": "\u2287", + "supedot": "\u2AC4", + "Superset": "\u2283", + "SupersetEqual": "\u2287", + "suphsol": "\u27C9", + "suphsub": "\u2AD7", + "suplarr": "\u297B", + "supmult": "\u2AC2", + "supnE": "\u2ACC", + "supne": "\u228B", + "supplus": "\u2AC0", + "Supset": "\u22D1", + "supset": "\u2283", + "supseteq": "\u2287", + "supseteqq": "\u2AC6", + "supsetneq": "\u228B", + "supsetneqq": "\u2ACC", + "supsim": "\u2AC8", + "supsub": "\u2AD4", + "supsup": "\u2AD6", + "swarhk": "\u2926", + "swArr": "\u21D9", + "swarr": "\u2199", + "swarrow": "\u2199", + "swnwar": "\u292A", + "szlig": "\xDF", + "Tab": "\t", + "target": "\u2316", + "Tau": "\u03A4", + "tau": "\u03C4", + "tbrk": "\u23B4", + "Tcaron": "\u0164", + "tcaron": "\u0165", + "Tcedil": "\u0162", + "tcedil": "\u0163", + "Tcy": "\u0422", + "tcy": "\u0442", + "tdot": "\u20DB", + "telrec": "\u2315", + "Tfr": "\uD835\uDD17", + "tfr": "\uD835\uDD31", + "there4": "\u2234", + "Therefore": "\u2234", + "therefore": "\u2234", + "Theta": "\u0398", + "theta": "\u03B8", + "thetasym": "\u03D1", + "thetav": "\u03D1", + "thickapprox": "\u2248", + "thicksim": "\u223C", + "ThickSpace": "\u205F\u200A", + "thinsp": "\u2009", + "ThinSpace": "\u2009", + "thkap": "\u2248", + "thksim": "\u223C", + "THORN": "\xDE", + "thorn": "\xFE", + "Tilde": "\u223C", + "tilde": "\u02DC", + "TildeEqual": "\u2243", + "TildeFullEqual": "\u2245", + "TildeTilde": "\u2248", + "times": "\xD7", + "timesb": "\u22A0", + "timesbar": "\u2A31", + "timesd": "\u2A30", + "tint": "\u222D", + "toea": "\u2928", + "top": "\u22A4", + "topbot": "\u2336", + "topcir": "\u2AF1", + "Topf": "\uD835\uDD4B", + "topf": "\uD835\uDD65", + "topfork": "\u2ADA", + "tosa": "\u2929", + "tprime": "\u2034", + "TRADE": "\u2122", + "trade": "\u2122", + "triangle": "\u25B5", + "triangledown": "\u25BF", + "triangleleft": "\u25C3", + "trianglelefteq": "\u22B4", + "triangleq": "\u225C", + "triangleright": "\u25B9", + "trianglerighteq": "\u22B5", + "tridot": "\u25EC", + "trie": "\u225C", + "triminus": "\u2A3A", + "TripleDot": "\u20DB", + "triplus": "\u2A39", + "trisb": "\u29CD", + "tritime": "\u2A3B", + "trpezium": "\u23E2", + "Tscr": "\uD835\uDCAF", + "tscr": "\uD835\uDCC9", + "TScy": "\u0426", + "tscy": "\u0446", + "TSHcy": "\u040B", + "tshcy": "\u045B", + "Tstrok": "\u0166", + "tstrok": "\u0167", + "twixt": "\u226C", + "twoheadleftarrow": "\u219E", + "twoheadrightarrow": "\u21A0", + "Uacute": "\xDA", + "uacute": "\xFA", + "Uarr": "\u219F", + "uArr": "\u21D1", + "uarr": "\u2191", + "Uarrocir": "\u2949", + "Ubrcy": "\u040E", + "ubrcy": "\u045E", + "Ubreve": "\u016C", + "ubreve": "\u016D", + "Ucirc": "\xDB", + "ucirc": "\xFB", + "Ucy": "\u0423", + "ucy": "\u0443", + "udarr": "\u21C5", + "Udblac": "\u0170", + "udblac": "\u0171", + "udhar": "\u296E", + "ufisht": "\u297E", + "Ufr": "\uD835\uDD18", + "ufr": "\uD835\uDD32", + "Ugrave": "\xD9", + "ugrave": "\xF9", + "uHar": "\u2963", + "uharl": "\u21BF", + "uharr": "\u21BE", + "uhblk": "\u2580", + "ulcorn": "\u231C", + "ulcorner": "\u231C", + "ulcrop": "\u230F", + "ultri": "\u25F8", + "Umacr": "\u016A", + "umacr": "\u016B", + "uml": "\xA8", + "UnderBar": "_", + "UnderBrace": "\u23DF", + "UnderBracket": "\u23B5", + "UnderParenthesis": "\u23DD", + "Union": "\u22C3", + "UnionPlus": "\u228E", + "Uogon": "\u0172", + "uogon": "\u0173", + "Uopf": "\uD835\uDD4C", + "uopf": "\uD835\uDD66", + "UpArrow": "\u2191", + "Uparrow": "\u21D1", + "uparrow": "\u2191", + "UpArrowBar": "\u2912", + "UpArrowDownArrow": "\u21C5", + "UpDownArrow": "\u2195", + "Updownarrow": "\u21D5", + "updownarrow": "\u2195", + "UpEquilibrium": "\u296E", + "upharpoonleft": "\u21BF", + "upharpoonright": "\u21BE", + "uplus": "\u228E", + "UpperLeftArrow": "\u2196", + "UpperRightArrow": "\u2197", + "Upsi": "\u03D2", + "upsi": "\u03C5", + "upsih": "\u03D2", + "Upsilon": "\u03A5", + "upsilon": "\u03C5", + "UpTee": "\u22A5", + "UpTeeArrow": "\u21A5", + "upuparrows": "\u21C8", + "urcorn": "\u231D", + "urcorner": "\u231D", + "urcrop": "\u230E", + "Uring": "\u016E", + "uring": "\u016F", + "urtri": "\u25F9", + "Uscr": "\uD835\uDCB0", + "uscr": "\uD835\uDCCA", + "utdot": "\u22F0", + "Utilde": "\u0168", + "utilde": "\u0169", + "utri": "\u25B5", + "utrif": "\u25B4", + "uuarr": "\u21C8", + "Uuml": "\xDC", + "uuml": "\xFC", + "uwangle": "\u29A7", + "vangrt": "\u299C", + "varepsilon": "\u03F5", + "varkappa": "\u03F0", + "varnothing": "\u2205", + "varphi": "\u03D5", + "varpi": "\u03D6", + "varpropto": "\u221D", + "vArr": "\u21D5", + "varr": "\u2195", + "varrho": "\u03F1", + "varsigma": "\u03C2", + "varsubsetneq": "\u228A\uFE00", + "varsubsetneqq": "\u2ACB\uFE00", + "varsupsetneq": "\u228B\uFE00", + "varsupsetneqq": "\u2ACC\uFE00", + "vartheta": "\u03D1", + "vartriangleleft": "\u22B2", + "vartriangleright": "\u22B3", + "Vbar": "\u2AEB", + "vBar": "\u2AE8", + "vBarv": "\u2AE9", + "Vcy": "\u0412", + "vcy": "\u0432", + "VDash": "\u22AB", + "Vdash": "\u22A9", + "vDash": "\u22A8", + "vdash": "\u22A2", + "Vdashl": "\u2AE6", + "Vee": "\u22C1", + "vee": "\u2228", + "veebar": "\u22BB", + "veeeq": "\u225A", + "vellip": "\u22EE", + "Verbar": "\u2016", + "verbar": "|", + "Vert": "\u2016", + "vert": "|", + "VerticalBar": "\u2223", + "VerticalLine": "|", + "VerticalSeparator": "\u2758", + "VerticalTilde": "\u2240", + "VeryThinSpace": "\u200A", + "Vfr": "\uD835\uDD19", + "vfr": "\uD835\uDD33", + "vltri": "\u22B2", + "vnsub": "\u2282\u20D2", + "vnsup": "\u2283\u20D2", + "Vopf": "\uD835\uDD4D", + "vopf": "\uD835\uDD67", + "vprop": "\u221D", + "vrtri": "\u22B3", + "Vscr": "\uD835\uDCB1", + "vscr": "\uD835\uDCCB", + "vsubnE": "\u2ACB\uFE00", + "vsubne": "\u228A\uFE00", + "vsupnE": "\u2ACC\uFE00", + "vsupne": "\u228B\uFE00", + "Vvdash": "\u22AA", + "vzigzag": "\u299A", + "Wcirc": "\u0174", + "wcirc": "\u0175", + "wedbar": "\u2A5F", + "Wedge": "\u22C0", + "wedge": "\u2227", + "wedgeq": "\u2259", + "weierp": "\u2118", + "Wfr": "\uD835\uDD1A", + "wfr": "\uD835\uDD34", + "Wopf": "\uD835\uDD4E", + "wopf": "\uD835\uDD68", + "wp": "\u2118", + "wr": "\u2240", + "wreath": "\u2240", + "Wscr": "\uD835\uDCB2", + "wscr": "\uD835\uDCCC", + "xcap": "\u22C2", + "xcirc": "\u25EF", + "xcup": "\u22C3", + "xdtri": "\u25BD", + "Xfr": "\uD835\uDD1B", + "xfr": "\uD835\uDD35", + "xhArr": "\u27FA", + "xharr": "\u27F7", + "Xi": "\u039E", + "xi": "\u03BE", + "xlArr": "\u27F8", + "xlarr": "\u27F5", + "xmap": "\u27FC", + "xnis": "\u22FB", + "xodot": "\u2A00", + "Xopf": "\uD835\uDD4F", + "xopf": "\uD835\uDD69", + "xoplus": "\u2A01", + "xotime": "\u2A02", + "xrArr": "\u27F9", + "xrarr": "\u27F6", + "Xscr": "\uD835\uDCB3", + "xscr": "\uD835\uDCCD", + "xsqcup": "\u2A06", + "xuplus": "\u2A04", + "xutri": "\u25B3", + "xvee": "\u22C1", + "xwedge": "\u22C0", + "Yacute": "\xDD", + "yacute": "\xFD", + "YAcy": "\u042F", + "yacy": "\u044F", + "Ycirc": "\u0176", + "ycirc": "\u0177", + "Ycy": "\u042B", + "ycy": "\u044B", + "yen": "\xA5", + "Yfr": "\uD835\uDD1C", + "yfr": "\uD835\uDD36", + "YIcy": "\u0407", + "yicy": "\u0457", + "Yopf": "\uD835\uDD50", + "yopf": "\uD835\uDD6A", + "Yscr": "\uD835\uDCB4", + "yscr": "\uD835\uDCCE", + "YUcy": "\u042E", + "yucy": "\u044E", + "Yuml": "\u0178", + "yuml": "\xFF", + "Zacute": "\u0179", + "zacute": "\u017A", + "Zcaron": "\u017D", + "zcaron": "\u017E", + "Zcy": "\u0417", + "zcy": "\u0437", + "Zdot": "\u017B", + "zdot": "\u017C", + "zeetrf": "\u2128", + "ZeroWidthSpace": "\u200B", + "Zeta": "\u0396", + "zeta": "\u03B6", + "Zfr": "\u2128", + "zfr": "\uD835\uDD37", + "ZHcy": "\u0416", + "zhcy": "\u0436", + "zigrarr": "\u21DD", + "Zopf": "\u2124", + "zopf": "\uD835\uDD6B", + "Zscr": "\uD835\uDCB5", + "zscr": "\uD835\uDCCF", + "zwj": "\u200D", + "zwnj": "\u200C" +}; +var hasOwn = Object.prototype.hasOwnProperty; + +function has(object, key) { + return object ? hasOwn.call(object, key) : false; +} + +function decodeEntity(name) { + if (has(entities, name)) { + return entities[name]; + } else { + return name; + } +} + +var hasOwn$1 = Object.prototype.hasOwnProperty; + +function has$1(object, key) { + return object ? hasOwn$1.call(object, key) : false; +} // Extend objects +// + + +function assign(obj +/*from1, from2, from3, ...*/ +) { + var sources = [].slice.call(arguments, 1); + sources.forEach(function (source) { + if (!source) { + return; + } + + if (typeof source !== 'object') { + throw new TypeError(source + 'must be object'); + } + + Object.keys(source).forEach(function (key) { + obj[key] = source[key]; + }); + }); + return obj; +} //////////////////////////////////////////////////////////////////////////////// + + +var UNESCAPE_MD_RE = /\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g; + +function unescapeMd(str) { + if (str.indexOf('\\') < 0) { + return str; + } + + return str.replace(UNESCAPE_MD_RE, '$1'); +} //////////////////////////////////////////////////////////////////////////////// + + +function isValidEntityCode(c) { + /*eslint no-bitwise:0*/ + // broken sequence + if (c >= 0xD800 && c <= 0xDFFF) { + return false; + } // never used + + + if (c >= 0xFDD0 && c <= 0xFDEF) { + return false; + } + + if ((c & 0xFFFF) === 0xFFFF || (c & 0xFFFF) === 0xFFFE) { + return false; + } // control codes + + + if (c >= 0x00 && c <= 0x08) { + return false; + } + + if (c === 0x0B) { + return false; + } + + if (c >= 0x0E && c <= 0x1F) { + return false; + } + + if (c >= 0x7F && c <= 0x9F) { + return false; + } // out of range + + + if (c > 0x10FFFF) { + return false; + } + + return true; +} + +function fromCodePoint(c) { + /*eslint no-bitwise:0*/ + if (c > 0xffff) { + c -= 0x10000; + var surrogate1 = 0xd800 + (c >> 10), + surrogate2 = 0xdc00 + (c & 0x3ff); + return String.fromCharCode(surrogate1, surrogate2); + } + + return String.fromCharCode(c); +} + +var NAMED_ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi; +var DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i; + +function replaceEntityPattern(match, name) { + var code = 0; + var decoded = decodeEntity(name); + + if (name !== decoded) { + return decoded; + } else if (name.charCodeAt(0) === 0x23 + /* # */ + && DIGITAL_ENTITY_TEST_RE.test(name)) { + code = name[1].toLowerCase() === 'x' ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10); + + if (isValidEntityCode(code)) { + return fromCodePoint(code); + } + } + + return match; +} + +function replaceEntities(str) { + if (str.indexOf('&') < 0) { + return str; + } + + return str.replace(NAMED_ENTITY_RE, replaceEntityPattern); +} //////////////////////////////////////////////////////////////////////////////// + + +var HTML_ESCAPE_TEST_RE = /[&<>"]/; +var HTML_ESCAPE_REPLACE_RE = /[&<>"]/g; +var HTML_REPLACEMENTS = { + '&': '&', + '<': '<', + '>': '>', + '"': '"' +}; + +function replaceUnsafeChar(ch) { + return HTML_REPLACEMENTS[ch]; +} + +function escapeHtml(str) { + if (HTML_ESCAPE_TEST_RE.test(str)) { + return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar); + } + + return str; +} +/** + * Renderer rules cache + */ + +var rules = {}; +/** + * Blockquotes + */ + +rules.blockquote_open = function () +/* tokens, idx, options, env */ +{ + return '
\n'; +}; + +rules.blockquote_close = function (tokens, idx +/*, options, env */ +) { + return '
' + getBreak(tokens, idx); +}; +/** + * Code + */ + + +rules.code = function (tokens, idx +/*, options, env */ +) { + if (tokens[idx].block) { + return '
' + escapeHtml(tokens[idx].content) + '
' + getBreak(tokens, idx); + } + + return '' + escapeHtml(tokens[idx].content) + ''; +}; +/** + * Fenced code blocks + */ + + +rules.fence = function (tokens, idx, options, env, instance) { + var token = tokens[idx]; + var langClass = ''; + var langPrefix = options.langPrefix; + var langName = '', + fences, + fenceName; + var highlighted; + + if (token.params) { + // + // ```foo bar + // + // Try custom renderer "foo" first. That will simplify overwrite + // for diagrams, latex, and any other fenced block with custom look + // + fences = token.params.split(/\s+/g); + fenceName = fences.join(' '); + + if (has$1(instance.rules.fence_custom, fences[0])) { + return instance.rules.fence_custom[fences[0]](tokens, idx, options, env, instance); + } + + langName = escapeHtml(replaceEntities(unescapeMd(fenceName))); + langClass = ' class="' + langPrefix + langName + '"'; + } + + if (options.highlight) { + highlighted = options.highlight.apply(options.highlight, [token.content].concat(fences)) || escapeHtml(token.content); + } else { + highlighted = escapeHtml(token.content); + } + + return '
' + highlighted + '
' + getBreak(tokens, idx); +}; + +rules.fence_custom = {}; +/** + * Headings + */ + +rules.heading_open = function (tokens, idx +/*, options, env */ +) { + return ''; +}; + +rules.heading_close = function (tokens, idx +/*, options, env */ +) { + return '\n'; +}; +/** + * Horizontal rules + */ + + +rules.hr = function (tokens, idx, options +/*, env */ +) { + return (options.xhtmlOut ? '
' : '
') + getBreak(tokens, idx); +}; +/** + * Bullets + */ + + +rules.bullet_list_open = function () +/* tokens, idx, options, env */ +{ + return '
    \n'; +}; + +rules.bullet_list_close = function (tokens, idx +/*, options, env */ +) { + return '
' + getBreak(tokens, idx); +}; +/** + * List items + */ + + +rules.list_item_open = function () +/* tokens, idx, options, env */ +{ + return '
  • '; +}; + +rules.list_item_close = function () +/* tokens, idx, options, env */ +{ + return '
  • \n'; +}; +/** + * Ordered list items + */ + + +rules.ordered_list_open = function (tokens, idx +/*, options, env */ +) { + var token = tokens[idx]; + var order = token.order > 1 ? ' start="' + token.order + '"' : ''; + return '\n'; +}; + +rules.ordered_list_close = function (tokens, idx +/*, options, env */ +) { + return '' + getBreak(tokens, idx); +}; +/** + * Paragraphs + */ + + +rules.paragraph_open = function (tokens, idx +/*, options, env */ +) { + return tokens[idx].tight ? '' : '

    '; +}; + +rules.paragraph_close = function (tokens, idx +/*, options, env */ +) { + var addBreak = !(tokens[idx].tight && idx && tokens[idx - 1].type === 'inline' && !tokens[idx - 1].content); + return (tokens[idx].tight ? '' : '

    ') + (addBreak ? getBreak(tokens, idx) : ''); +}; +/** + * Links + */ + + +rules.link_open = function (tokens, idx, options +/* env */ +) { + var title = tokens[idx].title ? ' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"' : ''; + var target = options.linkTarget ? ' target="' + options.linkTarget + '"' : ''; + return ''; +}; + +rules.link_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Images + */ + + +rules.image = function (tokens, idx, options +/*, env */ +) { + var src = ' src="' + escapeHtml(tokens[idx].src) + '"'; + var title = tokens[idx].title ? ' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"' : ''; + var alt = ' alt="' + (tokens[idx].alt ? escapeHtml(replaceEntities(unescapeMd(tokens[idx].alt))) : '') + '"'; + var suffix = options.xhtmlOut ? ' /' : ''; + return ''; +}; +/** + * Tables + */ + + +rules.table_open = function () +/* tokens, idx, options, env */ +{ + return '\n'; +}; + +rules.table_close = function () +/* tokens, idx, options, env */ +{ + return '
    \n'; +}; + +rules.thead_open = function () +/* tokens, idx, options, env */ +{ + return '\n'; +}; + +rules.thead_close = function () +/* tokens, idx, options, env */ +{ + return '\n'; +}; + +rules.tbody_open = function () +/* tokens, idx, options, env */ +{ + return '\n'; +}; + +rules.tbody_close = function () +/* tokens, idx, options, env */ +{ + return '\n'; +}; + +rules.tr_open = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.tr_close = function () +/* tokens, idx, options, env */ +{ + return '\n'; +}; + +rules.th_open = function (tokens, idx +/*, options, env */ +) { + var token = tokens[idx]; + return ''; +}; + +rules.th_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.td_open = function (tokens, idx +/*, options, env */ +) { + var token = tokens[idx]; + return ''; +}; + +rules.td_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Bold + */ + + +rules.strong_open = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.strong_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Italicize + */ + + +rules.em_open = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.em_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Strikethrough + */ + + +rules.del_open = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.del_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Insert + */ + + +rules.ins_open = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.ins_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Highlight + */ + + +rules.mark_open = function () +/* tokens, idx, options, env */ +{ + return ''; +}; + +rules.mark_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Super- and sub-script + */ + + +rules.sub = function (tokens, idx +/*, options, env */ +) { + return '' + escapeHtml(tokens[idx].content) + ''; +}; + +rules.sup = function (tokens, idx +/*, options, env */ +) { + return '' + escapeHtml(tokens[idx].content) + ''; +}; +/** + * Breaks + */ + + +rules.hardbreak = function (tokens, idx, options +/*, env */ +) { + return options.xhtmlOut ? '
    \n' : '
    \n'; +}; + +rules.softbreak = function (tokens, idx, options +/*, env */ +) { + return options.breaks ? options.xhtmlOut ? '
    \n' : '
    \n' : '\n'; +}; +/** + * Text + */ + + +rules.text = function (tokens, idx +/*, options, env */ +) { + return escapeHtml(tokens[idx].content); +}; +/** + * Content + */ + + +rules.htmlblock = function (tokens, idx +/*, options, env */ +) { + return tokens[idx].content; +}; + +rules.htmltag = function (tokens, idx +/*, options, env */ +) { + return tokens[idx].content; +}; +/** + * Abbreviations, initialism + */ + + +rules.abbr_open = function (tokens, idx +/*, options, env */ +) { + return ''; +}; + +rules.abbr_close = function () +/* tokens, idx, options, env */ +{ + return ''; +}; +/** + * Footnotes + */ + + +rules.footnote_ref = function (tokens, idx) { + var n = Number(tokens[idx].id + 1).toString(); + var id = 'fnref' + n; + + if (tokens[idx].subId > 0) { + id += ':' + tokens[idx].subId; + } + + return '[' + n + ']'; +}; + +rules.footnote_block_open = function (tokens, idx, options) { + var hr = options.xhtmlOut ? '
    \n' : '
    \n'; + return hr + '
    \n
      \n'; +}; + +rules.footnote_block_close = function () { + return '
    \n
    \n'; +}; + +rules.footnote_open = function (tokens, idx) { + var id = Number(tokens[idx].id + 1).toString(); + return '
  • '; +}; + +rules.footnote_close = function () { + return '
  • \n'; +}; + +rules.footnote_anchor = function (tokens, idx) { + var n = Number(tokens[idx].id + 1).toString(); + var id = 'fnref' + n; + + if (tokens[idx].subId > 0) { + id += ':' + tokens[idx].subId; + } + + return ' '; +}; +/** + * Definition lists + */ + + +rules.dl_open = function () { + return '
    \n'; +}; + +rules.dt_open = function () { + return '
    '; +}; + +rules.dd_open = function () { + return '
    '; +}; + +rules.dl_close = function () { + return '
    \n'; +}; + +rules.dt_close = function () { + return '\n'; +}; + +rules.dd_close = function () { + return '\n'; +}; +/** + * Helper functions + */ + + +function nextToken(tokens, idx) { + if (++idx >= tokens.length - 2) { + return idx; + } + + if (tokens[idx].type === 'paragraph_open' && tokens[idx].tight && tokens[idx + 1].type === 'inline' && tokens[idx + 1].content.length === 0 && tokens[idx + 2].type === 'paragraph_close' && tokens[idx + 2].tight) { + return nextToken(tokens, idx + 2); + } + + return idx; +} +/** + * Check to see if `\n` is needed before the next token. + * + * @param {Array} `tokens` + * @param {Number} `idx` + * @return {String} Empty string or newline + * @api private + */ + + +var getBreak = rules.getBreak = function getBreak(tokens, idx) { + idx = nextToken(tokens, idx); + + if (idx < tokens.length && tokens[idx].type === 'list_item_close') { + return ''; + } + + return '\n'; +}; +/** + * Renderer class. Renders HTML and exposes `rules` to allow + * local modifications. + */ + + +function Renderer() { + this.rules = assign({}, rules); // exported helper, for custom rules only + + this.getBreak = rules.getBreak; +} +/** + * Render a string of inline HTML with the given `tokens` and + * `options`. + * + * @param {Array} `tokens` + * @param {Object} `options` + * @param {Object} `env` + * @return {String} + * @api public + */ + + +Renderer.prototype.renderInline = function (tokens, options, env) { + var _rules = this.rules; + var len = tokens.length, + i = 0; + var result = ''; + + while (len--) { + result += _rules[tokens[i].type](tokens, i++, options, env, this); + } + + return result; +}; +/** + * Render a string of HTML with the given `tokens` and + * `options`. + * + * @param {Array} `tokens` + * @param {Object} `options` + * @param {Object} `env` + * @return {String} + * @api public + */ + + +Renderer.prototype.render = function (tokens, options, env) { + var _rules = this.rules; + var len = tokens.length, + i = -1; + var result = ''; + + while (++i < len) { + if (tokens[i].type === 'inline') { + result += this.renderInline(tokens[i].children, options, env); + } else { + result += _rules[tokens[i].type](tokens, i, options, env, this); + } + } + + return result; +}; +/** + * Ruler is a helper class for building responsibility chains from + * parse rules. It allows: + * + * - easy stack rules chains + * - getting main chain and named chains content (as arrays of functions) + * + * Helper methods, should not be used directly. + * @api private + */ + + +function Ruler() { + // List of added rules. Each element is: + // + // { name: XXX, + // enabled: Boolean, + // fn: Function(), + // alt: [ name2, name3 ] } + // + this.__rules__ = []; // Cached rule chains. + // + // First level - chain name, '' for default. + // Second level - digital anchor for fast filtering by charcodes. + // + + this.__cache__ = null; +} +/** + * Find the index of a rule by `name`. + * + * @param {String} `name` + * @return {Number} Index of the given `name` + * @api private + */ + + +Ruler.prototype.__find__ = function (name) { + var len = this.__rules__.length; + var i = -1; + + while (len--) { + if (this.__rules__[++i].name === name) { + return i; + } + } + + return -1; +}; +/** + * Build the rules lookup cache + * + * @api private + */ + + +Ruler.prototype.__compile__ = function () { + var self = this; + var chains = ['']; // collect unique names + + self.__rules__.forEach(function (rule) { + if (!rule.enabled) { + return; + } + + rule.alt.forEach(function (altName) { + if (chains.indexOf(altName) < 0) { + chains.push(altName); + } + }); + }); + + self.__cache__ = {}; + chains.forEach(function (chain) { + self.__cache__[chain] = []; + + self.__rules__.forEach(function (rule) { + if (!rule.enabled) { + return; + } + + if (chain && rule.alt.indexOf(chain) < 0) { + return; + } + + self.__cache__[chain].push(rule.fn); + }); + }); +}; +/** + * Ruler public methods + * ------------------------------------------------ + */ + +/** + * Replace rule function + * + * @param {String} `name` Rule name + * @param {Function `fn` + * @param {Object} `options` + * @api private + */ + + +Ruler.prototype.at = function (name, fn, options) { + var idx = this.__find__(name); + + var opt = options || {}; + + if (idx === -1) { + throw new Error('Parser rule not found: ' + name); + } + + this.__rules__[idx].fn = fn; + this.__rules__[idx].alt = opt.alt || []; + this.__cache__ = null; +}; +/** + * Add a rule to the chain before given the `ruleName`. + * + * @param {String} `beforeName` + * @param {String} `ruleName` + * @param {Function} `fn` + * @param {Object} `options` + * @api private + */ + + +Ruler.prototype.before = function (beforeName, ruleName, fn, options) { + var idx = this.__find__(beforeName); + + var opt = options || {}; + + if (idx === -1) { + throw new Error('Parser rule not found: ' + beforeName); + } + + this.__rules__.splice(idx, 0, { + name: ruleName, + enabled: true, + fn: fn, + alt: opt.alt || [] + }); + + this.__cache__ = null; +}; +/** + * Add a rule to the chain after the given `ruleName`. + * + * @param {String} `afterName` + * @param {String} `ruleName` + * @param {Function} `fn` + * @param {Object} `options` + * @api private + */ + + +Ruler.prototype.after = function (afterName, ruleName, fn, options) { + var idx = this.__find__(afterName); + + var opt = options || {}; + + if (idx === -1) { + throw new Error('Parser rule not found: ' + afterName); + } + + this.__rules__.splice(idx + 1, 0, { + name: ruleName, + enabled: true, + fn: fn, + alt: opt.alt || [] + }); + + this.__cache__ = null; +}; +/** + * Add a rule to the end of chain. + * + * @param {String} `ruleName` + * @param {Function} `fn` + * @param {Object} `options` + * @return {String} + */ + + +Ruler.prototype.push = function (ruleName, fn, options) { + var opt = options || {}; + + this.__rules__.push({ + name: ruleName, + enabled: true, + fn: fn, + alt: opt.alt || [] + }); + + this.__cache__ = null; +}; +/** + * Enable a rule or list of rules. + * + * @param {String|Array} `list` Name or array of rule names to enable + * @param {Boolean} `strict` If `true`, all non listed rules will be disabled. + * @api private + */ + + +Ruler.prototype.enable = function (list, strict) { + list = !Array.isArray(list) ? [list] : list; // In strict mode disable all existing rules first + + if (strict) { + this.__rules__.forEach(function (rule) { + rule.enabled = false; + }); + } // Search by name and enable + + + list.forEach(function (name) { + var idx = this.__find__(name); + + if (idx < 0) { + throw new Error('Rules manager: invalid rule name ' + name); + } + + this.__rules__[idx].enabled = true; + }, this); + this.__cache__ = null; +}; +/** + * Disable a rule or list of rules. + * + * @param {String|Array} `list` Name or array of rule names to disable + * @api private + */ + + +Ruler.prototype.disable = function (list) { + list = !Array.isArray(list) ? [list] : list; // Search by name and disable + + list.forEach(function (name) { + var idx = this.__find__(name); + + if (idx < 0) { + throw new Error('Rules manager: invalid rule name ' + name); + } + + this.__rules__[idx].enabled = false; + }, this); + this.__cache__ = null; +}; +/** + * Get a rules list as an array of functions. + * + * @param {String} `chainName` + * @return {Object} + * @api private + */ + + +Ruler.prototype.getRules = function (chainName) { + if (this.__cache__ === null) { + this.__compile__(); + } + + return this.__cache__[chainName] || []; +}; + +function block(state) { + if (state.inlineMode) { + state.tokens.push({ + type: 'inline', + content: state.src.replace(/\n/g, ' ').trim(), + level: 0, + lines: [0, 1], + children: [] + }); + } else { + state.block.parse(state.src, state.options, state.env, state.tokens); + } +} // Inline parser state + + +function StateInline(src, parserInline, options, env, outTokens) { + this.src = src; + this.env = env; + this.options = options; + this.parser = parserInline; + this.tokens = outTokens; + this.pos = 0; + this.posMax = this.src.length; + this.level = 0; + this.pending = ''; + this.pendingLevel = 0; + this.cache = []; // Stores { start: end } pairs. Useful for backtrack + // optimization of pairs parse (emphasis, strikes). + // Link parser state vars + + this.isInLabel = false; // Set true when seek link label - we should disable + // "paired" rules (emphasis, strikes) to not skip + // tailing `]` + + this.linkLevel = 0; // Increment for each nesting link. Used to prevent + // nesting in definitions + + this.linkContent = ''; // Temporary storage for link url + + this.labelUnmatchedScopes = 0; // Track unpaired `[` for link labels + // (backtrack optimization) +} // Flush pending text +// + + +StateInline.prototype.pushPending = function () { + this.tokens.push({ + type: 'text', + content: this.pending, + level: this.pendingLevel + }); + this.pending = ''; +}; // Push new token to "stream". +// If pending text exists - flush it as text token +// + + +StateInline.prototype.push = function (token) { + if (this.pending) { + this.pushPending(); + } + + this.tokens.push(token); + this.pendingLevel = this.level; +}; // Store value to cache. +// !!! Implementation has parser-specific optimizations +// !!! keys MUST be integer, >= 0; values MUST be integer, > 0 +// + + +StateInline.prototype.cacheSet = function (key, val) { + for (var i = this.cache.length; i <= key; i++) { + this.cache.push(0); + } + + this.cache[key] = val; +}; // Get cache value +// + + +StateInline.prototype.cacheGet = function (key) { + return key < this.cache.length ? this.cache[key] : 0; +}; +/** + * Parse link labels + * + * This function assumes that first character (`[`) already matches; + * returns the end of the label. + * + * @param {Object} state + * @param {Number} start + * @api private + */ + + +function parseLinkLabel(state, start) { + var level, + found, + marker, + labelEnd = -1, + max = state.posMax, + oldPos = state.pos, + oldFlag = state.isInLabel; + + if (state.isInLabel) { + return -1; + } + + if (state.labelUnmatchedScopes) { + state.labelUnmatchedScopes--; + return -1; + } + + state.pos = start + 1; + state.isInLabel = true; + level = 1; + + while (state.pos < max) { + marker = state.src.charCodeAt(state.pos); + + if (marker === 0x5B + /* [ */ + ) { + level++; + } else if (marker === 0x5D + /* ] */ + ) { + level--; + + if (level === 0) { + found = true; + break; + } + } + + state.parser.skipToken(state); + } + + if (found) { + labelEnd = state.pos; + state.labelUnmatchedScopes = 0; + } else { + state.labelUnmatchedScopes = level - 1; + } // restore old state + + + state.pos = oldPos; + state.isInLabel = oldFlag; + return labelEnd; +} // Parse abbreviation definitions, i.e. `*[abbr]: description` + + +function parseAbbr(str, parserInline, options, env) { + var state, labelEnd, pos, max, label, title; + + if (str.charCodeAt(0) !== 0x2A + /* * */ + ) { + return -1; + } + + if (str.charCodeAt(1) !== 0x5B + /* [ */ + ) { + return -1; + } + + if (str.indexOf(']:') === -1) { + return -1; + } + + state = new StateInline(str, parserInline, options, env, []); + labelEnd = parseLinkLabel(state, 1); + + if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A + /* : */ + ) { + return -1; + } + + max = state.posMax; // abbr title is always one line, so looking for ending "\n" here + + for (pos = labelEnd + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x0A) { + break; + } + } + + label = str.slice(2, labelEnd); + title = str.slice(labelEnd + 2, pos).trim(); + + if (title.length === 0) { + return -1; + } + + if (!env.abbreviations) { + env.abbreviations = {}; + } // prepend ':' to avoid conflict with Object.prototype members + + + if (typeof env.abbreviations[':' + label] === 'undefined') { + env.abbreviations[':' + label] = title; + } + + return pos; +} + +function abbr(state) { + var tokens = state.tokens, + i, + l, + content, + pos; + + if (state.inlineMode) { + return; + } // Parse inlines + + + for (i = 1, l = tokens.length - 1; i < l; i++) { + if (tokens[i - 1].type === 'paragraph_open' && tokens[i].type === 'inline' && tokens[i + 1].type === 'paragraph_close') { + content = tokens[i].content; + + while (content.length) { + pos = parseAbbr(content, state.inline, state.options, state.env); + + if (pos < 0) { + break; + } + + content = content.slice(pos).trim(); + } + + tokens[i].content = content; + + if (!content.length) { + tokens[i - 1].tight = true; + tokens[i + 1].tight = true; + } + } + } +} + +function normalizeLink(url) { + var normalized = replaceEntities(url); // We shouldn't care about the result of malformed URIs, + // and should not throw an exception. + + try { + normalized = decodeURI(normalized); + } catch (err) {} + + return encodeURI(normalized); +} +/** + * Parse link destination + * + * - on success it returns a string and updates state.pos; + * - on failure it returns null + * + * @param {Object} state + * @param {Number} pos + * @api private + */ + + +function parseLinkDestination(state, pos) { + var code, + level, + link, + start = pos, + max = state.posMax; + + if (state.src.charCodeAt(pos) === 0x3C + /* < */ + ) { + pos++; + + while (pos < max) { + code = state.src.charCodeAt(pos); + + if (code === 0x0A + /* \n */ + ) { + return false; + } + + if (code === 0x3E + /* > */ + ) { + link = normalizeLink(unescapeMd(state.src.slice(start + 1, pos))); + + if (!state.parser.validateLink(link)) { + return false; + } + + state.pos = pos + 1; + state.linkContent = link; + return true; + } + + if (code === 0x5C + /* \ */ + && pos + 1 < max) { + pos += 2; + continue; + } + + pos++; + } // no closing '>' + + + return false; + } // this should be ... } else { ... branch + + + level = 0; + + while (pos < max) { + code = state.src.charCodeAt(pos); + + if (code === 0x20) { + break; + } // ascii control chars + + + if (code < 0x20 || code === 0x7F) { + break; + } + + if (code === 0x5C + /* \ */ + && pos + 1 < max) { + pos += 2; + continue; + } + + if (code === 0x28 + /* ( */ + ) { + level++; + + if (level > 1) { + break; + } + } + + if (code === 0x29 + /* ) */ + ) { + level--; + + if (level < 0) { + break; + } + } + + pos++; + } + + if (start === pos) { + return false; + } + + link = unescapeMd(state.src.slice(start, pos)); + + if (!state.parser.validateLink(link)) { + return false; + } + + state.linkContent = link; + state.pos = pos; + return true; +} +/** + * Parse link title + * + * - on success it returns a string and updates state.pos; + * - on failure it returns null + * + * @param {Object} state + * @param {Number} pos + * @api private + */ + + +function parseLinkTitle(state, pos) { + var code, + start = pos, + max = state.posMax, + marker = state.src.charCodeAt(pos); + + if (marker !== 0x22 + /* " */ + && marker !== 0x27 + /* ' */ + && marker !== 0x28 + /* ( */ + ) { + return false; + } + + pos++; // if opening marker is "(", switch it to closing marker ")" + + if (marker === 0x28) { + marker = 0x29; + } + + while (pos < max) { + code = state.src.charCodeAt(pos); + + if (code === marker) { + state.pos = pos + 1; + state.linkContent = unescapeMd(state.src.slice(start + 1, pos)); + return true; + } + + if (code === 0x5C + /* \ */ + && pos + 1 < max) { + pos += 2; + continue; + } + + pos++; + } + + return false; +} + +function normalizeReference(str) { + // use .toUpperCase() instead of .toLowerCase() + // here to avoid a conflict with Object.prototype + // members (most notably, `__proto__`) + return str.trim().replace(/\s+/g, ' ').toUpperCase(); +} + +function parseReference(str, parser, options, env) { + var state, labelEnd, pos, max, code, start, href, title, label; + + if (str.charCodeAt(0) !== 0x5B + /* [ */ + ) { + return -1; + } + + if (str.indexOf(']:') === -1) { + return -1; + } + + state = new StateInline(str, parser, options, env, []); + labelEnd = parseLinkLabel(state, 0); + + if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A + /* : */ + ) { + return -1; + } + + max = state.posMax; // [label]: destination 'title' + // ^^^ skip optional whitespace here + + for (pos = labelEnd + 2; pos < max; pos++) { + code = state.src.charCodeAt(pos); + + if (code !== 0x20 && code !== 0x0A) { + break; + } + } // [label]: destination 'title' + // ^^^^^^^^^^^ parse this + + + if (!parseLinkDestination(state, pos)) { + return -1; + } + + href = state.linkContent; + pos = state.pos; // [label]: destination 'title' + // ^^^ skipping those spaces + + start = pos; + + for (pos = pos + 1; pos < max; pos++) { + code = state.src.charCodeAt(pos); + + if (code !== 0x20 && code !== 0x0A) { + break; + } + } // [label]: destination 'title' + // ^^^^^^^ parse this + + + if (pos < max && start !== pos && parseLinkTitle(state, pos)) { + title = state.linkContent; + pos = state.pos; + } else { + title = ''; + pos = start; + } // ensure that the end of the line is empty + + + while (pos < max && state.src.charCodeAt(pos) === 0x20 + /* space */ + ) { + pos++; + } + + if (pos < max && state.src.charCodeAt(pos) !== 0x0A) { + return -1; + } + + label = normalizeReference(str.slice(1, labelEnd)); + + if (typeof env.references[label] === 'undefined') { + env.references[label] = { + title: title, + href: href + }; + } + + return pos; +} + +function references(state) { + var tokens = state.tokens, + i, + l, + content, + pos; + state.env.references = state.env.references || {}; + + if (state.inlineMode) { + return; + } // Scan definitions in paragraph inlines + + + for (i = 1, l = tokens.length - 1; i < l; i++) { + if (tokens[i].type === 'inline' && tokens[i - 1].type === 'paragraph_open' && tokens[i + 1].type === 'paragraph_close') { + content = tokens[i].content; + + while (content.length) { + pos = parseReference(content, state.inline, state.options, state.env); + + if (pos < 0) { + break; + } + + content = content.slice(pos).trim(); + } + + tokens[i].content = content; + + if (!content.length) { + tokens[i - 1].tight = true; + tokens[i + 1].tight = true; + } + } + } +} + +function inline(state) { + var tokens = state.tokens, + tok, + i, + l; // Parse inlines + + for (i = 0, l = tokens.length; i < l; i++) { + tok = tokens[i]; + + if (tok.type === 'inline') { + state.inline.parse(tok.content, state.options, state.env, tok.children); + } + } +} + +function footnote_block(state) { + var i, + l, + j, + t, + lastParagraph, + list, + tokens, + current, + currentLabel, + level = 0, + insideRef = false, + refTokens = {}; + + if (!state.env.footnotes) { + return; + } + + state.tokens = state.tokens.filter(function (tok) { + if (tok.type === 'footnote_reference_open') { + insideRef = true; + current = []; + currentLabel = tok.label; + return false; + } + + if (tok.type === 'footnote_reference_close') { + insideRef = false; // prepend ':' to avoid conflict with Object.prototype members + + refTokens[':' + currentLabel] = current; + return false; + } + + if (insideRef) { + current.push(tok); + } + + return !insideRef; + }); + + if (!state.env.footnotes.list) { + return; + } + + list = state.env.footnotes.list; + state.tokens.push({ + type: 'footnote_block_open', + level: level++ + }); + + for (i = 0, l = list.length; i < l; i++) { + state.tokens.push({ + type: 'footnote_open', + id: i, + level: level++ + }); + + if (list[i].tokens) { + tokens = []; + tokens.push({ + type: 'paragraph_open', + tight: false, + level: level++ + }); + tokens.push({ + type: 'inline', + content: '', + level: level, + children: list[i].tokens + }); + tokens.push({ + type: 'paragraph_close', + tight: false, + level: --level + }); + } else if (list[i].label) { + tokens = refTokens[':' + list[i].label]; + } + + state.tokens = state.tokens.concat(tokens); + + if (state.tokens[state.tokens.length - 1].type === 'paragraph_close') { + lastParagraph = state.tokens.pop(); + } else { + lastParagraph = null; + } + + t = list[i].count > 0 ? list[i].count : 1; + + for (j = 0; j < t; j++) { + state.tokens.push({ + type: 'footnote_anchor', + id: i, + subId: j, + level: level + }); + } + + if (lastParagraph) { + state.tokens.push(lastParagraph); + } + + state.tokens.push({ + type: 'footnote_close', + level: --level + }); + } + + state.tokens.push({ + type: 'footnote_block_close', + level: --level + }); +} // Enclose abbreviations in tags +// + + +var PUNCT_CHARS = ' \n()[]\'".,!?-'; // from Google closure library +// http://closure-library.googlecode.com/git-history/docs/local_closure_goog_string_string.js.source.html#line1021 + +function regEscape(s) { + return s.replace(/([-()\[\]{}+?*.$\^|,:#= 0; i--) { + token = tokens[i]; + + if (token.type !== 'text') { + continue; + } + + pos = 0; + text = token.content; + reg.lastIndex = 0; + level = token.level; + nodes = []; + + while (m = reg.exec(text)) { + if (reg.lastIndex > pos) { + nodes.push({ + type: 'text', + content: text.slice(pos, m.index + m[1].length), + level: level + }); + } + + nodes.push({ + type: 'abbr_open', + title: state.env.abbreviations[':' + m[2]], + level: level++ + }); + nodes.push({ + type: 'text', + content: m[2], + level: level + }); + nodes.push({ + type: 'abbr_close', + level: --level + }); + pos = reg.lastIndex - m[3].length; + } + + if (!nodes.length) { + continue; + } + + if (pos < text.length) { + nodes.push({ + type: 'text', + content: text.slice(pos), + level: level + }); + } // replace current node + + + blockTokens[j].children = tokens = [].concat(tokens.slice(0, i), nodes, tokens.slice(i + 1)); + } + } +} // Simple typographical replacements +// +// TODO: +// - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾ +// - miltiplication 2 x 4 -> 2 × 4 + + +var RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/; +var SCOPED_ABBR_RE = /\((c|tm|r|p)\)/ig; +var SCOPED_ABBR = { + 'c': '©', + 'r': '®', + 'p': '§', + 'tm': '™' +}; + +function replaceScopedAbbr(str) { + if (str.indexOf('(') < 0) { + return str; + } + + return str.replace(SCOPED_ABBR_RE, function (match, name) { + return SCOPED_ABBR[name.toLowerCase()]; + }); +} + +function replace(state) { + var i, token, text, inlineTokens, blkIdx; + + if (!state.options.typographer) { + return; + } + + for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { + if (state.tokens[blkIdx].type !== 'inline') { + continue; + } + + inlineTokens = state.tokens[blkIdx].children; + + for (i = inlineTokens.length - 1; i >= 0; i--) { + token = inlineTokens[i]; + + if (token.type === 'text') { + text = token.content; + text = replaceScopedAbbr(text); + + if (RARE_RE.test(text)) { + text = text.replace(/\+-/g, '±') // .., ..., ....... -> … + // but ?..... & !..... -> ?.. & !.. + .replace(/\.{2,}/g, '…').replace(/([?!])…/g, '$1..').replace(/([?!]){4,}/g, '$1$1$1').replace(/,{2,}/g, ',') // em-dash + .replace(/(^|[^-])---([^-]|$)/mg, "$1\u2014$2") // en-dash + .replace(/(^|\s)--(\s|$)/mg, "$1\u2013$2").replace(/(^|[^-\s])--([^-\s]|$)/mg, "$1\u2013$2"); + } + + token.content = text; + } + } + } +} // Convert straight quotation marks to typographic ones +// + + +var QUOTE_TEST_RE = /['"]/; +var QUOTE_RE = /['"]/g; +var PUNCT_RE = /[-\s()\[\]]/; +var APOSTROPHE = '’'; // This function returns true if the character at `pos` +// could be inside a word. + +function isLetter(str, pos) { + if (pos < 0 || pos >= str.length) { + return false; + } + + return !PUNCT_RE.test(str[pos]); +} + +function replaceAt(str, index, ch) { + return str.substr(0, index) + ch + str.substr(index + 1); +} + +function smartquotes(state) { + /*eslint max-depth:0*/ + var i, token, text, t, pos, max, thisLevel, lastSpace, nextSpace, item, canOpen, canClose, j, isSingle, blkIdx, tokens, stack; + + if (!state.options.typographer) { + return; + } + + stack = []; + + for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { + if (state.tokens[blkIdx].type !== 'inline') { + continue; + } + + tokens = state.tokens[blkIdx].children; + stack.length = 0; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + + if (token.type !== 'text' || QUOTE_TEST_RE.test(token.text)) { + continue; + } + + thisLevel = tokens[i].level; + + for (j = stack.length - 1; j >= 0; j--) { + if (stack[j].level <= thisLevel) { + break; + } + } + + stack.length = j + 1; + text = token.content; + pos = 0; + max = text.length; + /*eslint no-labels:0,block-scoped-var:0*/ + + OUTER: while (pos < max) { + QUOTE_RE.lastIndex = pos; + t = QUOTE_RE.exec(text); + + if (!t) { + break; + } + + lastSpace = !isLetter(text, t.index - 1); + pos = t.index + 1; + isSingle = t[0] === "'"; + nextSpace = !isLetter(text, pos); + + if (!nextSpace && !lastSpace) { + // middle of word + if (isSingle) { + token.content = replaceAt(token.content, t.index, APOSTROPHE); + } + + continue; + } + + canOpen = !nextSpace; + canClose = !lastSpace; + + if (canClose) { + // this could be a closing quote, rewind the stack to get a match + for (j = stack.length - 1; j >= 0; j--) { + item = stack[j]; + + if (stack[j].level < thisLevel) { + break; + } + + if (item.single === isSingle && stack[j].level === thisLevel) { + item = stack[j]; + + if (isSingle) { + tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, state.options.quotes[2]); + token.content = replaceAt(token.content, t.index, state.options.quotes[3]); + } else { + tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, state.options.quotes[0]); + token.content = replaceAt(token.content, t.index, state.options.quotes[1]); + } + + stack.length = j; + continue OUTER; + } + } + } + + if (canOpen) { + stack.push({ + token: i, + pos: t.index, + single: isSingle, + level: thisLevel + }); + } else if (canClose && isSingle) { + token.content = replaceAt(token.content, t.index, APOSTROPHE); + } + } + } + } +} +/** + * Core parser `rules` + */ + + +var _rules = [['block', block], ['abbr', abbr], ['references', references], ['inline', inline], ['footnote_tail', footnote_block], ['abbr2', abbr2], ['replacements', replace], ['smartquotes', smartquotes]]; +/** + * Class for top level (`core`) parser rules + * + * @api private + */ + +function Core() { + this.options = {}; + this.ruler = new Ruler(); + + for (var i = 0; i < _rules.length; i++) { + this.ruler.push(_rules[i][0], _rules[i][1]); + } +} +/** + * Process rules with the given `state` + * + * @param {Object} `state` + * @api private + */ + + +Core.prototype.process = function (state) { + var i, l, rules; + rules = this.ruler.getRules(''); + + for (i = 0, l = rules.length; i < l; i++) { + rules[i](state); + } +}; // Parser state class + + +function StateBlock(src, parser, options, env, tokens) { + var ch, s, start, pos, len, indent, indent_found; + this.src = src; // Shortcuts to simplify nested calls + + this.parser = parser; + this.options = options; + this.env = env; // + // Internal state vartiables + // + + this.tokens = tokens; + this.bMarks = []; // line begin offsets for fast jumps + + this.eMarks = []; // line end offsets for fast jumps + + this.tShift = []; // indent for each line + // block parser variables + + this.blkIndent = 0; // required block content indent + // (for example, if we are in list) + + this.line = 0; // line index in src + + this.lineMax = 0; // lines count + + this.tight = false; // loose/tight mode for lists + + this.parentType = 'root'; // if `list`, block parser stops on two newlines + + this.ddIndent = -1; // indent of the current dd block (-1 if there isn't any) + + this.level = 0; // renderer + + this.result = ''; // Create caches + // Generate markers. + + s = this.src; + indent = 0; + indent_found = false; + + for (start = pos = indent = 0, len = s.length; pos < len; pos++) { + ch = s.charCodeAt(pos); + + if (!indent_found) { + if (ch === 0x20 + /* space */ + ) { + indent++; + continue; + } else { + indent_found = true; + } + } + + if (ch === 0x0A || pos === len - 1) { + if (ch !== 0x0A) { + pos++; + } + + this.bMarks.push(start); + this.eMarks.push(pos); + this.tShift.push(indent); + indent_found = false; + indent = 0; + start = pos + 1; + } + } // Push fake entry to simplify cache bounds checks + + + this.bMarks.push(s.length); + this.eMarks.push(s.length); + this.tShift.push(0); + this.lineMax = this.bMarks.length - 1; // don't count last fake line +} + +StateBlock.prototype.isEmpty = function isEmpty(line) { + return this.bMarks[line] + this.tShift[line] >= this.eMarks[line]; +}; + +StateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) { + for (var max = this.lineMax; from < max; from++) { + if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) { + break; + } + } + + return from; +}; // Skip spaces from given position. + + +StateBlock.prototype.skipSpaces = function skipSpaces(pos) { + for (var max = this.src.length; pos < max; pos++) { + if (this.src.charCodeAt(pos) !== 0x20 + /* space */ + ) { + break; + } + } + + return pos; +}; // Skip char codes from given position + + +StateBlock.prototype.skipChars = function skipChars(pos, code) { + for (var max = this.src.length; pos < max; pos++) { + if (this.src.charCodeAt(pos) !== code) { + break; + } + } + + return pos; +}; // Skip char codes reverse from given position - 1 + + +StateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code, min) { + if (pos <= min) { + return pos; + } + + while (pos > min) { + if (code !== this.src.charCodeAt(--pos)) { + return pos + 1; + } + } + + return pos; +}; // cut lines range from source. + + +StateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) { + var i, + first, + last, + queue, + shift, + line = begin; + + if (begin >= end) { + return ''; + } // Opt: don't use push queue for single line; + + + if (line + 1 === end) { + first = this.bMarks[line] + Math.min(this.tShift[line], indent); + last = keepLastLF ? this.eMarks[line] + 1 : this.eMarks[line]; + return this.src.slice(first, last); + } + + queue = new Array(end - begin); + + for (i = 0; line < end; line++, i++) { + shift = this.tShift[line]; + + if (shift > indent) { + shift = indent; + } + + if (shift < 0) { + shift = 0; + } + + first = this.bMarks[line] + shift; + + if (line + 1 < end || keepLastLF) { + // No need for bounds check because we have fake entry on tail. + last = this.eMarks[line] + 1; + } else { + last = this.eMarks[line]; + } + + queue[i] = this.src.slice(first, last); + } + + return queue.join(''); +}; // Code block (4 spaces padded) + + +function code(state, startLine, endLine +/*, silent*/ +) { + var nextLine, last; + + if (state.tShift[startLine] - state.blkIndent < 4) { + return false; + } + + last = nextLine = startLine + 1; + + while (nextLine < endLine) { + if (state.isEmpty(nextLine)) { + nextLine++; + continue; + } + + if (state.tShift[nextLine] - state.blkIndent >= 4) { + nextLine++; + last = nextLine; + continue; + } + + break; + } + + state.line = nextLine; + state.tokens.push({ + type: 'code', + content: state.getLines(startLine, last, 4 + state.blkIndent, true), + block: true, + lines: [startLine, state.line], + level: state.level + }); + return true; +} // fences (``` lang, ~~~ lang) + + +function fences(state, startLine, endLine, silent) { + var marker, + len, + params, + nextLine, + mem, + haveEndMarker = false, + pos = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; + + if (pos + 3 > max) { + return false; + } + + marker = state.src.charCodeAt(pos); + + if (marker !== 0x7E + /* ~ */ + && marker !== 0x60 + /* ` */ + ) { + return false; + } // scan marker length + + + mem = pos; + pos = state.skipChars(pos, marker); + len = pos - mem; + + if (len < 3) { + return false; + } + + params = state.src.slice(pos, max).trim(); + + if (params.indexOf('`') >= 0) { + return false; + } // Since start is found, we can report success here in validation mode + + + if (silent) { + return true; + } // search end of block + + + nextLine = startLine; + + for (;;) { + nextLine++; + + if (nextLine >= endLine) { + // unclosed block should be autoclosed by end of document. + // also block seems to be autoclosed by end of parent + break; + } + + pos = mem = state.bMarks[nextLine] + state.tShift[nextLine]; + max = state.eMarks[nextLine]; + + if (pos < max && state.tShift[nextLine] < state.blkIndent) { + // non-empty line with negative indent should stop the list: + // - ``` + // test + break; + } + + if (state.src.charCodeAt(pos) !== marker) { + continue; + } + + if (state.tShift[nextLine] - state.blkIndent >= 4) { + // closing fence should be indented less than 4 spaces + continue; + } + + pos = state.skipChars(pos, marker); // closing code fence must be at least as long as the opening one + + if (pos - mem < len) { + continue; + } // make sure tail has spaces only + + + pos = state.skipSpaces(pos); + + if (pos < max) { + continue; + } + + haveEndMarker = true; // found! + + break; + } // If a fence has heading spaces, they should be removed from its inner block + + + len = state.tShift[startLine]; + state.line = nextLine + (haveEndMarker ? 1 : 0); + state.tokens.push({ + type: 'fence', + params: params, + content: state.getLines(startLine + 1, nextLine, len, true), + lines: [startLine, state.line], + level: state.level + }); + return true; +} // Block quotes + + +function blockquote(state, startLine, endLine, silent) { + var nextLine, + lastLineEmpty, + oldTShift, + oldBMarks, + oldIndent, + oldParentType, + lines, + terminatorRules, + i, + l, + terminate, + pos = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; + + if (pos > max) { + return false; + } // check the block quote marker + + + if (state.src.charCodeAt(pos++) !== 0x3E + /* > */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } // we know that it's going to be a valid blockquote, + // so no point trying to find the end of it in silent mode + + + if (silent) { + return true; + } // skip one optional space after '>' + + + if (state.src.charCodeAt(pos) === 0x20) { + pos++; + } + + oldIndent = state.blkIndent; + state.blkIndent = 0; + oldBMarks = [state.bMarks[startLine]]; + state.bMarks[startLine] = pos; // check if we have an empty blockquote + + pos = pos < max ? state.skipSpaces(pos) : pos; + lastLineEmpty = pos >= max; + oldTShift = [state.tShift[startLine]]; + state.tShift[startLine] = pos - state.bMarks[startLine]; + terminatorRules = state.parser.ruler.getRules('blockquote'); // Search the end of the block + // + // Block ends with either: + // 1. an empty line outside: + // ``` + // > test + // + // ``` + // 2. an empty line inside: + // ``` + // > + // test + // ``` + // 3. another tag + // ``` + // > test + // - - - + // ``` + + for (nextLine = startLine + 1; nextLine < endLine; nextLine++) { + pos = state.bMarks[nextLine] + state.tShift[nextLine]; + max = state.eMarks[nextLine]; + + if (pos >= max) { + // Case 1: line is not inside the blockquote, and this line is empty. + break; + } + + if (state.src.charCodeAt(pos++) === 0x3E + /* > */ + ) { + // This line is inside the blockquote. + // skip one optional space after '>' + if (state.src.charCodeAt(pos) === 0x20) { + pos++; + } + + oldBMarks.push(state.bMarks[nextLine]); + state.bMarks[nextLine] = pos; + pos = pos < max ? state.skipSpaces(pos) : pos; + lastLineEmpty = pos >= max; + oldTShift.push(state.tShift[nextLine]); + state.tShift[nextLine] = pos - state.bMarks[nextLine]; + continue; + } // Case 2: line is not inside the blockquote, and the last line was empty. + + + if (lastLineEmpty) { + break; + } // Case 3: another tag found. + + + terminate = false; + + for (i = 0, l = terminatorRules.length; i < l; i++) { + if (terminatorRules[i](state, nextLine, endLine, true)) { + terminate = true; + break; + } + } + + if (terminate) { + break; + } + + oldBMarks.push(state.bMarks[nextLine]); + oldTShift.push(state.tShift[nextLine]); // A negative number means that this is a paragraph continuation; + // + // Any negative number will do the job here, but it's better for it + // to be large enough to make any bugs obvious. + + state.tShift[nextLine] = -1337; + } + + oldParentType = state.parentType; + state.parentType = 'blockquote'; + state.tokens.push({ + type: 'blockquote_open', + lines: lines = [startLine, 0], + level: state.level++ + }); + state.parser.tokenize(state, startLine, nextLine); + state.tokens.push({ + type: 'blockquote_close', + level: --state.level + }); + state.parentType = oldParentType; + lines[1] = state.line; // Restore original tShift; this might not be necessary since the parser + // has already been here, but just to make sure we can do that. + + for (i = 0; i < oldTShift.length; i++) { + state.bMarks[i + startLine] = oldBMarks[i]; + state.tShift[i + startLine] = oldTShift[i]; + } + + state.blkIndent = oldIndent; + return true; +} // Horizontal rule + + +function hr(state, startLine, endLine, silent) { + var marker, + cnt, + ch, + pos = state.bMarks[startLine], + max = state.eMarks[startLine]; + pos += state.tShift[startLine]; + + if (pos > max) { + return false; + } + + marker = state.src.charCodeAt(pos++); // Check hr marker + + if (marker !== 0x2A + /* * */ + && marker !== 0x2D + /* - */ + && marker !== 0x5F + /* _ */ + ) { + return false; + } // markers can be mixed with spaces, but there should be at least 3 one + + + cnt = 1; + + while (pos < max) { + ch = state.src.charCodeAt(pos++); + + if (ch !== marker && ch !== 0x20 + /* space */ + ) { + return false; + } + + if (ch === marker) { + cnt++; + } + } + + if (cnt < 3) { + return false; + } + + if (silent) { + return true; + } + + state.line = startLine + 1; + state.tokens.push({ + type: 'hr', + lines: [startLine, state.line], + level: state.level + }); + return true; +} // Lists +// Search `[-+*][\n ]`, returns next pos arter marker on success +// or -1 on fail. + + +function skipBulletListMarker(state, startLine) { + var marker, pos, max; + pos = state.bMarks[startLine] + state.tShift[startLine]; + max = state.eMarks[startLine]; + + if (pos >= max) { + return -1; + } + + marker = state.src.charCodeAt(pos++); // Check bullet + + if (marker !== 0x2A + /* * */ + && marker !== 0x2D + /* - */ + && marker !== 0x2B + /* + */ + ) { + return -1; + } + + if (pos < max && state.src.charCodeAt(pos) !== 0x20) { + // " 1.test " - is not a list item + return -1; + } + + return pos; +} // Search `\d+[.)][\n ]`, returns next pos arter marker on success +// or -1 on fail. + + +function skipOrderedListMarker(state, startLine) { + var ch, + pos = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; + + if (pos + 1 >= max) { + return -1; + } + + ch = state.src.charCodeAt(pos++); + + if (ch < 0x30 + /* 0 */ + || ch > 0x39 + /* 9 */ + ) { + return -1; + } + + for (;;) { + // EOL -> fail + if (pos >= max) { + return -1; + } + + ch = state.src.charCodeAt(pos++); + + if (ch >= 0x30 + /* 0 */ + && ch <= 0x39 + /* 9 */ + ) { + continue; + } // found valid marker + + + if (ch === 0x29 + /* ) */ + || ch === 0x2e + /* . */ + ) { + break; + } + + return -1; + } + + if (pos < max && state.src.charCodeAt(pos) !== 0x20 + /* space */ + ) { + // " 1.test " - is not a list item + return -1; + } + + return pos; +} + +function markTightParagraphs(state, idx) { + var i, + l, + level = state.level + 2; + + for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) { + if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') { + state.tokens[i + 2].tight = true; + state.tokens[i].tight = true; + i += 2; + } + } +} + +function list(state, startLine, endLine, silent) { + var nextLine, + indent, + oldTShift, + oldIndent, + oldTight, + oldParentType, + start, + posAfterMarker, + max, + indentAfterMarker, + markerValue, + markerCharCode, + isOrdered, + contentStart, + listTokIdx, + prevEmptyEnd, + listLines, + itemLines, + tight = true, + terminatorRules, + i, + l, + terminate; // Detect list type and position after marker + + if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) { + isOrdered = true; + } else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) { + isOrdered = false; + } else { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } // We should terminate list on style change. Remember first one to compare. + + + markerCharCode = state.src.charCodeAt(posAfterMarker - 1); // For validation mode we can terminate immediately + + if (silent) { + return true; + } // Start list + + + listTokIdx = state.tokens.length; + + if (isOrdered) { + start = state.bMarks[startLine] + state.tShift[startLine]; + markerValue = Number(state.src.substr(start, posAfterMarker - start - 1)); + state.tokens.push({ + type: 'ordered_list_open', + order: markerValue, + lines: listLines = [startLine, 0], + level: state.level++ + }); + } else { + state.tokens.push({ + type: 'bullet_list_open', + lines: listLines = [startLine, 0], + level: state.level++ + }); + } // + // Iterate list items + // + + + nextLine = startLine; + prevEmptyEnd = false; + terminatorRules = state.parser.ruler.getRules('list'); + + while (nextLine < endLine) { + contentStart = state.skipSpaces(posAfterMarker); + max = state.eMarks[nextLine]; + + if (contentStart >= max) { + // trimming space in "- \n 3" case, indent is 1 here + indentAfterMarker = 1; + } else { + indentAfterMarker = contentStart - posAfterMarker; + } // If we have more than 4 spaces, the indent is 1 + // (the rest is just indented code block) + + + if (indentAfterMarker > 4) { + indentAfterMarker = 1; + } // If indent is less than 1, assume that it's one, example: + // "-\n test" + + + if (indentAfterMarker < 1) { + indentAfterMarker = 1; + } // " - test" + // ^^^^^ - calculating total length of this thing + + + indent = posAfterMarker - state.bMarks[nextLine] + indentAfterMarker; // Run subparser & write tokens + + state.tokens.push({ + type: 'list_item_open', + lines: itemLines = [startLine, 0], + level: state.level++ + }); + oldIndent = state.blkIndent; + oldTight = state.tight; + oldTShift = state.tShift[startLine]; + oldParentType = state.parentType; + state.tShift[startLine] = contentStart - state.bMarks[startLine]; + state.blkIndent = indent; + state.tight = true; + state.parentType = 'list'; + state.parser.tokenize(state, startLine, endLine, true); // If any of list item is tight, mark list as tight + + if (!state.tight || prevEmptyEnd) { + tight = false; + } // Item become loose if finish with empty line, + // but we should filter last element, because it means list finish + + + prevEmptyEnd = state.line - startLine > 1 && state.isEmpty(state.line - 1); + state.blkIndent = oldIndent; + state.tShift[startLine] = oldTShift; + state.tight = oldTight; + state.parentType = oldParentType; + state.tokens.push({ + type: 'list_item_close', + level: --state.level + }); + nextLine = startLine = state.line; + itemLines[1] = nextLine; + contentStart = state.bMarks[startLine]; + + if (nextLine >= endLine) { + break; + } + + if (state.isEmpty(nextLine)) { + break; + } // + // Try to check if list is terminated or continued. + // + + + if (state.tShift[nextLine] < state.blkIndent) { + break; + } // fail if terminating block found + + + terminate = false; + + for (i = 0, l = terminatorRules.length; i < l; i++) { + if (terminatorRules[i](state, nextLine, endLine, true)) { + terminate = true; + break; + } + } + + if (terminate) { + break; + } // fail if list has another type + + + if (isOrdered) { + posAfterMarker = skipOrderedListMarker(state, nextLine); + + if (posAfterMarker < 0) { + break; + } + } else { + posAfterMarker = skipBulletListMarker(state, nextLine); + + if (posAfterMarker < 0) { + break; + } + } + + if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { + break; + } + } // Finilize list + + + state.tokens.push({ + type: isOrdered ? 'ordered_list_close' : 'bullet_list_close', + level: --state.level + }); + listLines[1] = nextLine; + state.line = nextLine; // mark paragraphs tight if needed + + if (tight) { + markTightParagraphs(state, listTokIdx); + } + + return true; +} // Process footnote reference list + + +function footnote(state, startLine, endLine, silent) { + var oldBMark, + oldTShift, + oldParentType, + pos, + label, + start = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; // line should be at least 5 chars - "[^x]:" + + if (start + 4 > max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x20) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A + /* : */ + ) { + return false; + } + + if (silent) { + return true; + } + + pos++; + + if (!state.env.footnotes) { + state.env.footnotes = {}; + } + + if (!state.env.footnotes.refs) { + state.env.footnotes.refs = {}; + } + + label = state.src.slice(start + 2, pos - 2); + state.env.footnotes.refs[':' + label] = -1; + state.tokens.push({ + type: 'footnote_reference_open', + label: label, + level: state.level++ + }); + oldBMark = state.bMarks[startLine]; + oldTShift = state.tShift[startLine]; + oldParentType = state.parentType; + state.tShift[startLine] = state.skipSpaces(pos) - pos; + state.bMarks[startLine] = pos; + state.blkIndent += 4; + state.parentType = 'footnote'; + + if (state.tShift[startLine] < state.blkIndent) { + state.tShift[startLine] += state.blkIndent; + state.bMarks[startLine] -= state.blkIndent; + } + + state.parser.tokenize(state, startLine, endLine, true); + state.parentType = oldParentType; + state.blkIndent -= 4; + state.tShift[startLine] = oldTShift; + state.bMarks[startLine] = oldBMark; + state.tokens.push({ + type: 'footnote_reference_close', + level: --state.level + }); + return true; +} // heading (#, ##, ...) + + +function heading(state, startLine, endLine, silent) { + var ch, + level, + tmp, + pos = state.bMarks[startLine] + state.tShift[startLine], + max = state.eMarks[startLine]; + + if (pos >= max) { + return false; + } + + ch = state.src.charCodeAt(pos); + + if (ch !== 0x23 + /* # */ + || pos >= max) { + return false; + } // count heading level + + + level = 1; + ch = state.src.charCodeAt(++pos); + + while (ch === 0x23 + /* # */ + && pos < max && level <= 6) { + level++; + ch = state.src.charCodeAt(++pos); + } + + if (level > 6 || pos < max && ch !== 0x20 + /* space */ + ) { + return false; + } + + if (silent) { + return true; + } // Let's cut tails like ' ### ' from the end of string + + + max = state.skipCharsBack(max, 0x20, pos); // space + + tmp = state.skipCharsBack(max, 0x23, pos); // # + + if (tmp > pos && state.src.charCodeAt(tmp - 1) === 0x20 + /* space */ + ) { + max = tmp; + } + + state.line = startLine + 1; + state.tokens.push({ + type: 'heading_open', + hLevel: level, + lines: [startLine, state.line], + level: state.level + }); // only if header is not empty + + if (pos < max) { + state.tokens.push({ + type: 'inline', + content: state.src.slice(pos, max).trim(), + level: state.level + 1, + lines: [startLine, state.line], + children: [] + }); + } + + state.tokens.push({ + type: 'heading_close', + hLevel: level, + level: state.level + }); + return true; +} // lheading (---, ===) + + +function lheading(state, startLine, endLine +/*, silent*/ +) { + var marker, + pos, + max, + next = startLine + 1; + + if (next >= endLine) { + return false; + } + + if (state.tShift[next] < state.blkIndent) { + return false; + } // Scan next line + + + if (state.tShift[next] - state.blkIndent > 3) { + return false; + } + + pos = state.bMarks[next] + state.tShift[next]; + max = state.eMarks[next]; + + if (pos >= max) { + return false; + } + + marker = state.src.charCodeAt(pos); + + if (marker !== 0x2D + /* - */ + && marker !== 0x3D + /* = */ + ) { + return false; + } + + pos = state.skipChars(pos, marker); + pos = state.skipSpaces(pos); + + if (pos < max) { + return false; + } + + pos = state.bMarks[startLine] + state.tShift[startLine]; + state.line = next + 1; + state.tokens.push({ + type: 'heading_open', + hLevel: marker === 0x3D + /* = */ + ? 1 : 2, + lines: [startLine, state.line], + level: state.level + }); + state.tokens.push({ + type: 'inline', + content: state.src.slice(pos, state.eMarks[startLine]).trim(), + level: state.level + 1, + lines: [startLine, state.line - 1], + children: [] + }); + state.tokens.push({ + type: 'heading_close', + hLevel: marker === 0x3D + /* = */ + ? 1 : 2, + level: state.level + }); + return true; +} // List of valid html blocks names, accorting to commonmark spec +// http://jgm.github.io/CommonMark/spec.html#html-blocks + + +var html_blocks = {}; +['article', 'aside', 'button', 'blockquote', 'body', 'canvas', 'caption', 'col', 'colgroup', 'dd', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'iframe', 'li', 'map', 'object', 'ol', 'output', 'p', 'pre', 'progress', 'script', 'section', 'style', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'tr', 'thead', 'ul', 'video'].forEach(function (name) { + html_blocks[name] = true; +}); // HTML block + +var HTML_TAG_OPEN_RE = /^<([a-zA-Z]{1,15})[\s\/>]/; +var HTML_TAG_CLOSE_RE = /^<\/([a-zA-Z]{1,15})[\s>]/; + +function isLetter$1(ch) { + /*eslint no-bitwise:0*/ + var lc = ch | 0x20; // to lower case + + return lc >= 0x61 + /* a */ + && lc <= 0x7a + /* z */ + ; +} + +function htmlblock(state, startLine, endLine, silent) { + var ch, + match, + nextLine, + pos = state.bMarks[startLine], + max = state.eMarks[startLine], + shift = state.tShift[startLine]; + pos += shift; + + if (!state.options.html) { + return false; + } + + if (shift > 3 || pos + 2 >= max) { + return false; + } + + if (state.src.charCodeAt(pos) !== 0x3C + /* < */ + ) { + return false; + } + + ch = state.src.charCodeAt(pos + 1); + + if (ch === 0x21 + /* ! */ + || ch === 0x3F + /* ? */ + ) { + // Directive start / comment start / processing instruction start + if (silent) { + return true; + } + } else if (ch === 0x2F + /* / */ + || isLetter$1(ch)) { + // Probably start or end of tag + if (ch === 0x2F + /* \ */ + ) { + // closing tag + match = state.src.slice(pos, max).match(HTML_TAG_CLOSE_RE); + + if (!match) { + return false; + } + } else { + // opening tag + match = state.src.slice(pos, max).match(HTML_TAG_OPEN_RE); + + if (!match) { + return false; + } + } // Make sure tag name is valid + + + if (html_blocks[match[1].toLowerCase()] !== true) { + return false; + } + + if (silent) { + return true; + } + } else { + return false; + } // If we are here - we detected HTML block. + // Let's roll down till empty line (block end). + + + nextLine = startLine + 1; + + while (nextLine < state.lineMax && !state.isEmpty(nextLine)) { + nextLine++; + } + + state.line = nextLine; + state.tokens.push({ + type: 'htmlblock', + level: state.level, + lines: [startLine, state.line], + content: state.getLines(startLine, nextLine, 0, true) + }); + return true; +} // GFM table, non-standard + + +function getLine(state, line) { + var pos = state.bMarks[line] + state.blkIndent, + max = state.eMarks[line]; + return state.src.substr(pos, max - pos); +} + +function table(state, startLine, endLine, silent) { + var ch, lineText, pos, i, nextLine, rows, cell, aligns, t, tableLines, tbodyLines; // should have at least three lines + + if (startLine + 2 > endLine) { + return false; + } + + nextLine = startLine + 1; + + if (state.tShift[nextLine] < state.blkIndent) { + return false; + } // first character of the second line should be '|' or '-' + + + pos = state.bMarks[nextLine] + state.tShift[nextLine]; + + if (pos >= state.eMarks[nextLine]) { + return false; + } + + ch = state.src.charCodeAt(pos); + + if (ch !== 0x7C + /* | */ + && ch !== 0x2D + /* - */ + && ch !== 0x3A + /* : */ + ) { + return false; + } + + lineText = getLine(state, startLine + 1); + + if (!/^[-:| ]+$/.test(lineText)) { + return false; + } + + rows = lineText.split('|'); + + if (rows <= 2) { + return false; + } + + aligns = []; + + for (i = 0; i < rows.length; i++) { + t = rows[i].trim(); + + if (!t) { + // allow empty columns before and after table, but not in between columns; + // e.g. allow ` |---| `, disallow ` ---||--- ` + if (i === 0 || i === rows.length - 1) { + continue; + } else { + return false; + } + } + + if (!/^:?-+:?$/.test(t)) { + return false; + } + + if (t.charCodeAt(t.length - 1) === 0x3A + /* : */ + ) { + aligns.push(t.charCodeAt(0) === 0x3A + /* : */ + ? 'center' : 'right'); + } else if (t.charCodeAt(0) === 0x3A + /* : */ + ) { + aligns.push('left'); + } else { + aligns.push(''); + } + } + + lineText = getLine(state, startLine).trim(); + + if (lineText.indexOf('|') === -1) { + return false; + } + + rows = lineText.replace(/^\||\|$/g, '').split('|'); + + if (aligns.length !== rows.length) { + return false; + } + + if (silent) { + return true; + } + + state.tokens.push({ + type: 'table_open', + lines: tableLines = [startLine, 0], + level: state.level++ + }); + state.tokens.push({ + type: 'thead_open', + lines: [startLine, startLine + 1], + level: state.level++ + }); + state.tokens.push({ + type: 'tr_open', + lines: [startLine, startLine + 1], + level: state.level++ + }); + + for (i = 0; i < rows.length; i++) { + state.tokens.push({ + type: 'th_open', + align: aligns[i], + lines: [startLine, startLine + 1], + level: state.level++ + }); + state.tokens.push({ + type: 'inline', + content: rows[i].trim(), + lines: [startLine, startLine + 1], + level: state.level, + children: [] + }); + state.tokens.push({ + type: 'th_close', + level: --state.level + }); + } + + state.tokens.push({ + type: 'tr_close', + level: --state.level + }); + state.tokens.push({ + type: 'thead_close', + level: --state.level + }); + state.tokens.push({ + type: 'tbody_open', + lines: tbodyLines = [startLine + 2, 0], + level: state.level++ + }); + + for (nextLine = startLine + 2; nextLine < endLine; nextLine++) { + if (state.tShift[nextLine] < state.blkIndent) { + break; + } + + lineText = getLine(state, nextLine).trim(); + + if (lineText.indexOf('|') === -1) { + break; + } + + rows = lineText.replace(/^\||\|$/g, '').split('|'); + state.tokens.push({ + type: 'tr_open', + level: state.level++ + }); + + for (i = 0; i < rows.length; i++) { + state.tokens.push({ + type: 'td_open', + align: aligns[i], + level: state.level++ + }); // 0x7c === '|' + + cell = rows[i].substring(rows[i].charCodeAt(0) === 0x7c ? 1 : 0, rows[i].charCodeAt(rows[i].length - 1) === 0x7c ? rows[i].length - 1 : rows[i].length).trim(); + state.tokens.push({ + type: 'inline', + content: cell, + level: state.level, + children: [] + }); + state.tokens.push({ + type: 'td_close', + level: --state.level + }); + } + + state.tokens.push({ + type: 'tr_close', + level: --state.level + }); + } + + state.tokens.push({ + type: 'tbody_close', + level: --state.level + }); + state.tokens.push({ + type: 'table_close', + level: --state.level + }); + tableLines[1] = tbodyLines[1] = nextLine; + state.line = nextLine; + return true; +} // Definition lists +// Search `[:~][\n ]`, returns next pos after marker on success +// or -1 on fail. + + +function skipMarker(state, line) { + var pos, + marker, + start = state.bMarks[line] + state.tShift[line], + max = state.eMarks[line]; + + if (start >= max) { + return -1; + } // Check bullet + + + marker = state.src.charCodeAt(start++); + + if (marker !== 0x7E + /* ~ */ + && marker !== 0x3A + /* : */ + ) { + return -1; + } + + pos = state.skipSpaces(start); // require space after ":" + + if (start === pos) { + return -1; + } // no empty definitions, e.g. " : " + + + if (pos >= max) { + return -1; + } + + return pos; +} + +function markTightParagraphs$1(state, idx) { + var i, + l, + level = state.level + 2; + + for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) { + if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') { + state.tokens[i + 2].tight = true; + state.tokens[i].tight = true; + i += 2; + } + } +} + +function deflist(state, startLine, endLine, silent) { + var contentStart, ddLine, dtLine, itemLines, listLines, listTokIdx, nextLine, oldIndent, oldDDIndent, oldParentType, oldTShift, oldTight, prevEmptyEnd, tight; + + if (silent) { + // quirk: validation mode validates a dd block only, not a whole deflist + if (state.ddIndent < 0) { + return false; + } + + return skipMarker(state, startLine) >= 0; + } + + nextLine = startLine + 1; + + if (state.isEmpty(nextLine)) { + if (++nextLine > endLine) { + return false; + } + } + + if (state.tShift[nextLine] < state.blkIndent) { + return false; + } + + contentStart = skipMarker(state, nextLine); + + if (contentStart < 0) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } // Start list + + + listTokIdx = state.tokens.length; + state.tokens.push({ + type: 'dl_open', + lines: listLines = [startLine, 0], + level: state.level++ + }); // + // Iterate list items + // + + dtLine = startLine; + ddLine = nextLine; // One definition list can contain multiple DTs, + // and one DT can be followed by multiple DDs. + // + // Thus, there is two loops here, and label is + // needed to break out of the second one + // + + /*eslint no-labels:0,block-scoped-var:0*/ + + OUTER: for (;;) { + tight = true; + prevEmptyEnd = false; + state.tokens.push({ + type: 'dt_open', + lines: [dtLine, dtLine], + level: state.level++ + }); + state.tokens.push({ + type: 'inline', + content: state.getLines(dtLine, dtLine + 1, state.blkIndent, false).trim(), + level: state.level + 1, + lines: [dtLine, dtLine], + children: [] + }); + state.tokens.push({ + type: 'dt_close', + level: --state.level + }); + + for (;;) { + state.tokens.push({ + type: 'dd_open', + lines: itemLines = [nextLine, 0], + level: state.level++ + }); + oldTight = state.tight; + oldDDIndent = state.ddIndent; + oldIndent = state.blkIndent; + oldTShift = state.tShift[ddLine]; + oldParentType = state.parentType; + state.blkIndent = state.ddIndent = state.tShift[ddLine] + 2; + state.tShift[ddLine] = contentStart - state.bMarks[ddLine]; + state.tight = true; + state.parentType = 'deflist'; + state.parser.tokenize(state, ddLine, endLine, true); // If any of list item is tight, mark list as tight + + if (!state.tight || prevEmptyEnd) { + tight = false; + } // Item become loose if finish with empty line, + // but we should filter last element, because it means list finish + + + prevEmptyEnd = state.line - ddLine > 1 && state.isEmpty(state.line - 1); + state.tShift[ddLine] = oldTShift; + state.tight = oldTight; + state.parentType = oldParentType; + state.blkIndent = oldIndent; + state.ddIndent = oldDDIndent; + state.tokens.push({ + type: 'dd_close', + level: --state.level + }); + itemLines[1] = nextLine = state.line; + + if (nextLine >= endLine) { + break OUTER; + } + + if (state.tShift[nextLine] < state.blkIndent) { + break OUTER; + } + + contentStart = skipMarker(state, nextLine); + + if (contentStart < 0) { + break; + } + + ddLine = nextLine; // go to the next loop iteration: + // insert DD tag and repeat checking + } + + if (nextLine >= endLine) { + break; + } + + dtLine = nextLine; + + if (state.isEmpty(dtLine)) { + break; + } + + if (state.tShift[dtLine] < state.blkIndent) { + break; + } + + ddLine = dtLine + 1; + + if (ddLine >= endLine) { + break; + } + + if (state.isEmpty(ddLine)) { + ddLine++; + } + + if (ddLine >= endLine) { + break; + } + + if (state.tShift[ddLine] < state.blkIndent) { + break; + } + + contentStart = skipMarker(state, ddLine); + + if (contentStart < 0) { + break; + } // go to the next loop iteration: + // insert DT and DD tags and repeat checking + + } // Finilize list + + + state.tokens.push({ + type: 'dl_close', + level: --state.level + }); + listLines[1] = nextLine; + state.line = nextLine; // mark paragraphs tight if needed + + if (tight) { + markTightParagraphs$1(state, listTokIdx); + } + + return true; +} // Paragraph + + +function paragraph(state, startLine +/*, endLine*/ +) { + var endLine, + content, + terminate, + i, + l, + nextLine = startLine + 1, + terminatorRules; + endLine = state.lineMax; // jump line-by-line until empty one or EOF + + if (nextLine < endLine && !state.isEmpty(nextLine)) { + terminatorRules = state.parser.ruler.getRules('paragraph'); + + for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { + // this would be a code block normally, but after paragraph + // it's considered a lazy continuation regardless of what's there + if (state.tShift[nextLine] - state.blkIndent > 3) { + continue; + } // Some tags can terminate paragraph without empty line. + + + terminate = false; + + for (i = 0, l = terminatorRules.length; i < l; i++) { + if (terminatorRules[i](state, nextLine, endLine, true)) { + terminate = true; + break; + } + } + + if (terminate) { + break; + } + } + } + + content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); + state.line = nextLine; + + if (content.length) { + state.tokens.push({ + type: 'paragraph_open', + tight: false, + lines: [startLine, state.line], + level: state.level + }); + state.tokens.push({ + type: 'inline', + content: content, + level: state.level + 1, + lines: [startLine, state.line], + children: [] + }); + state.tokens.push({ + type: 'paragraph_close', + tight: false, + level: state.level + }); + } + + return true; +} +/** + * Parser rules + */ + + +var _rules$1 = [['code', code], ['fences', fences, ['paragraph', 'blockquote', 'list']], ['blockquote', blockquote, ['paragraph', 'blockquote', 'list']], ['hr', hr, ['paragraph', 'blockquote', 'list']], ['list', list, ['paragraph', 'blockquote']], ['footnote', footnote, ['paragraph']], ['heading', heading, ['paragraph', 'blockquote']], ['lheading', lheading], ['htmlblock', htmlblock, ['paragraph', 'blockquote']], ['table', table, ['paragraph']], ['deflist', deflist, ['paragraph']], ['paragraph', paragraph]]; +/** + * Block Parser class + * + * @api private + */ + +function ParserBlock() { + this.ruler = new Ruler(); + + for (var i = 0; i < _rules$1.length; i++) { + this.ruler.push(_rules$1[i][0], _rules$1[i][1], { + alt: (_rules$1[i][2] || []).slice() + }); + } +} +/** + * Generate tokens for the given input range. + * + * @param {Object} `state` Has properties like `src`, `parser`, `options` etc + * @param {Number} `startLine` + * @param {Number} `endLine` + * @api private + */ + + +ParserBlock.prototype.tokenize = function (state, startLine, endLine) { + var rules = this.ruler.getRules(''); + var len = rules.length; + var line = startLine; + var hasEmptyLines = false; + var ok, i; + + while (line < endLine) { + state.line = line = state.skipEmptyLines(line); + + if (line >= endLine) { + break; + } // Termination condition for nested calls. + // Nested calls currently used for blockquotes & lists + + + if (state.tShift[line] < state.blkIndent) { + break; + } // Try all possible rules. + // On success, rule should: + // + // - update `state.line` + // - update `state.tokens` + // - return true + + + for (i = 0; i < len; i++) { + ok = rules[i](state, line, endLine, false); + + if (ok) { + break; + } + } // set state.tight iff we had an empty line before current tag + // i.e. latest empty line should not count + + + state.tight = !hasEmptyLines; // paragraph might "eat" one newline after it in nested lists + + if (state.isEmpty(state.line - 1)) { + hasEmptyLines = true; + } + + line = state.line; + + if (line < endLine && state.isEmpty(line)) { + hasEmptyLines = true; + line++; // two empty lines should stop the parser in list mode + + if (line < endLine && state.parentType === 'list' && state.isEmpty(line)) { + break; + } + + state.line = line; + } + } +}; + +var TABS_SCAN_RE = /[\n\t]/g; +var NEWLINES_RE = /\r[\n\u0085]|[\u2424\u2028\u0085]/g; +var SPACES_RE = /\u00a0/g; +/** + * Tokenize the given `str`. + * + * @param {String} `str` Source string + * @param {Object} `options` + * @param {Object} `env` + * @param {Array} `outTokens` + * @api private + */ + +ParserBlock.prototype.parse = function (str, options, env, outTokens) { + var state, + lineStart = 0, + lastTabPos = 0; + + if (!str) { + return []; + } // Normalize spaces + + + str = str.replace(SPACES_RE, ' '); // Normalize newlines + + str = str.replace(NEWLINES_RE, '\n'); // Replace tabs with proper number of spaces (1..4) + + if (str.indexOf('\t') >= 0) { + str = str.replace(TABS_SCAN_RE, function (match, offset) { + var result; + + if (str.charCodeAt(offset) === 0x0A) { + lineStart = offset + 1; + lastTabPos = 0; + return match; + } + + result = ' '.slice((offset - lineStart - lastTabPos) % 4); + lastTabPos = offset - lineStart + 1; + return result; + }); + } + + state = new StateBlock(str, this, options, env, outTokens); + this.tokenize(state, state.line, state.lineMax); +}; // Skip text characters for text token, place those to pending buffer +// and increment current pos +// Rule to skip pure text +// '{}$%@~+=:' reserved for extentions + + +function isTerminatorChar(ch) { + switch (ch) { + case 0x0A + /* \n */ + : + case 0x5C + /* \ */ + : + case 0x60 + /* ` */ + : + case 0x2A + /* * */ + : + case 0x5F + /* _ */ + : + case 0x5E + /* ^ */ + : + case 0x5B + /* [ */ + : + case 0x5D + /* ] */ + : + case 0x21 + /* ! */ + : + case 0x26 + /* & */ + : + case 0x3C + /* < */ + : + case 0x3E + /* > */ + : + case 0x7B + /* { */ + : + case 0x7D + /* } */ + : + case 0x24 + /* $ */ + : + case 0x25 + /* % */ + : + case 0x40 + /* @ */ + : + case 0x7E + /* ~ */ + : + case 0x2B + /* + */ + : + case 0x3D + /* = */ + : + case 0x3A + /* : */ + : + return true; + + default: + return false; + } +} + +function text(state, silent) { + var pos = state.pos; + + while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) { + pos++; + } + + if (pos === state.pos) { + return false; + } + + if (!silent) { + state.pending += state.src.slice(state.pos, pos); + } + + state.pos = pos; + return true; +} // Proceess '\n' + + +function newline(state, silent) { + var pmax, + max, + pos = state.pos; + + if (state.src.charCodeAt(pos) !== 0x0A + /* \n */ + ) { + return false; + } + + pmax = state.pending.length - 1; + max = state.posMax; // ' \n' -> hardbreak + // Lookup in pending chars is bad practice! Don't copy to other rules! + // Pending string is stored in concat mode, indexed lookups will cause + // convertion to flat mode. + + if (!silent) { + if (pmax >= 0 && state.pending.charCodeAt(pmax) === 0x20) { + if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 0x20) { + // Strip out all trailing spaces on this line. + for (var i = pmax - 2; i >= 0; i--) { + if (state.pending.charCodeAt(i) !== 0x20) { + state.pending = state.pending.substring(0, i + 1); + break; + } + } + + state.push({ + type: 'hardbreak', + level: state.level + }); + } else { + state.pending = state.pending.slice(0, -1); + state.push({ + type: 'softbreak', + level: state.level + }); + } + } else { + state.push({ + type: 'softbreak', + level: state.level + }); + } + } + + pos++; // skip heading spaces for next line + + while (pos < max && state.src.charCodeAt(pos) === 0x20) { + pos++; + } + + state.pos = pos; + return true; +} // Proceess escaped chars and hardbreaks + + +var ESCAPED = []; + +for (var i = 0; i < 256; i++) { + ESCAPED.push(0); +} + +'\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-'.split('').forEach(function (ch) { + ESCAPED[ch.charCodeAt(0)] = 1; +}); + +function escape(state, silent) { + var ch, + pos = state.pos, + max = state.posMax; + + if (state.src.charCodeAt(pos) !== 0x5C + /* \ */ + ) { + return false; + } + + pos++; + + if (pos < max) { + ch = state.src.charCodeAt(pos); + + if (ch < 256 && ESCAPED[ch] !== 0) { + if (!silent) { + state.pending += state.src[pos]; + } + + state.pos += 2; + return true; + } + + if (ch === 0x0A) { + if (!silent) { + state.push({ + type: 'hardbreak', + level: state.level + }); + } + + pos++; // skip leading whitespaces from next line + + while (pos < max && state.src.charCodeAt(pos) === 0x20) { + pos++; + } + + state.pos = pos; + return true; + } + } + + if (!silent) { + state.pending += '\\'; + } + + state.pos++; + return true; +} // Parse backticks + + +function backticks(state, silent) { + var start, + max, + marker, + matchStart, + matchEnd, + pos = state.pos, + ch = state.src.charCodeAt(pos); + + if (ch !== 0x60 + /* ` */ + ) { + return false; + } + + start = pos; + pos++; + max = state.posMax; + + while (pos < max && state.src.charCodeAt(pos) === 0x60 + /* ` */ + ) { + pos++; + } + + marker = state.src.slice(start, pos); + matchStart = matchEnd = pos; + + while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) { + matchEnd = matchStart + 1; + + while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60 + /* ` */ + ) { + matchEnd++; + } + + if (matchEnd - matchStart === marker.length) { + if (!silent) { + state.push({ + type: 'code', + content: state.src.slice(pos, matchStart).replace(/[ \n]+/g, ' ').trim(), + block: false, + level: state.level + }); + } + + state.pos = matchEnd; + return true; + } + } + + if (!silent) { + state.pending += marker; + } + + state.pos += marker.length; + return true; +} // Process ~~deleted text~~ + + +function del(state, silent) { + var found, + pos, + stack, + max = state.posMax, + start = state.pos, + lastChar, + nextChar; + + if (state.src.charCodeAt(start) !== 0x7E + /* ~ */ + ) { + return false; + } + + if (silent) { + return false; + } // don't run any pairs in validation mode + + + if (start + 4 >= max) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x7E + /* ~ */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; + nextChar = state.src.charCodeAt(start + 2); + + if (lastChar === 0x7E + /* ~ */ + ) { + return false; + } + + if (nextChar === 0x7E + /* ~ */ + ) { + return false; + } + + if (nextChar === 0x20 || nextChar === 0x0A) { + return false; + } + + pos = start + 2; + + while (pos < max && state.src.charCodeAt(pos) === 0x7E + /* ~ */ + ) { + pos++; + } + + if (pos > start + 3) { + // sequence of 4+ markers taking as literal, same as in a emphasis + state.pos += pos - start; + + if (!silent) { + state.pending += state.src.slice(start, pos); + } + + return true; + } + + state.pos = start + 2; + stack = 1; + + while (state.pos + 1 < max) { + if (state.src.charCodeAt(state.pos) === 0x7E + /* ~ */ + ) { + if (state.src.charCodeAt(state.pos + 1) === 0x7E + /* ~ */ + ) { + lastChar = state.src.charCodeAt(state.pos - 1); + nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; + + if (nextChar !== 0x7E + /* ~ */ + && lastChar !== 0x7E + /* ~ */ + ) { + if (lastChar !== 0x20 && lastChar !== 0x0A) { + // closing '~~' + stack--; + } else if (nextChar !== 0x20 && nextChar !== 0x0A) { + // opening '~~' + stack++; + } // else { + // // standalone ' ~~ ' indented with spaces + // } + + + if (stack <= 0) { + found = true; + break; + } + } + } + } + + state.parser.skipToken(state); + } + + if (!found) { + // parser failed to find ending tag, so it's not valid emphasis + state.pos = start; + return false; + } // found! + + + state.posMax = state.pos; + state.pos = start + 2; + + if (!silent) { + state.push({ + type: 'del_open', + level: state.level++ + }); + state.parser.tokenize(state); + state.push({ + type: 'del_close', + level: --state.level + }); + } + + state.pos = state.posMax + 2; + state.posMax = max; + return true; +} // Process ++inserted text++ + + +function ins(state, silent) { + var found, + pos, + stack, + max = state.posMax, + start = state.pos, + lastChar, + nextChar; + + if (state.src.charCodeAt(start) !== 0x2B + /* + */ + ) { + return false; + } + + if (silent) { + return false; + } // don't run any pairs in validation mode + + + if (start + 4 >= max) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x2B + /* + */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; + nextChar = state.src.charCodeAt(start + 2); + + if (lastChar === 0x2B + /* + */ + ) { + return false; + } + + if (nextChar === 0x2B + /* + */ + ) { + return false; + } + + if (nextChar === 0x20 || nextChar === 0x0A) { + return false; + } + + pos = start + 2; + + while (pos < max && state.src.charCodeAt(pos) === 0x2B + /* + */ + ) { + pos++; + } + + if (pos !== start + 2) { + // sequence of 3+ markers taking as literal, same as in a emphasis + state.pos += pos - start; + + if (!silent) { + state.pending += state.src.slice(start, pos); + } + + return true; + } + + state.pos = start + 2; + stack = 1; + + while (state.pos + 1 < max) { + if (state.src.charCodeAt(state.pos) === 0x2B + /* + */ + ) { + if (state.src.charCodeAt(state.pos + 1) === 0x2B + /* + */ + ) { + lastChar = state.src.charCodeAt(state.pos - 1); + nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; + + if (nextChar !== 0x2B + /* + */ + && lastChar !== 0x2B + /* + */ + ) { + if (lastChar !== 0x20 && lastChar !== 0x0A) { + // closing '++' + stack--; + } else if (nextChar !== 0x20 && nextChar !== 0x0A) { + // opening '++' + stack++; + } // else { + // // standalone ' ++ ' indented with spaces + // } + + + if (stack <= 0) { + found = true; + break; + } + } + } + } + + state.parser.skipToken(state); + } + + if (!found) { + // parser failed to find ending tag, so it's not valid emphasis + state.pos = start; + return false; + } // found! + + + state.posMax = state.pos; + state.pos = start + 2; + + if (!silent) { + state.push({ + type: 'ins_open', + level: state.level++ + }); + state.parser.tokenize(state); + state.push({ + type: 'ins_close', + level: --state.level + }); + } + + state.pos = state.posMax + 2; + state.posMax = max; + return true; +} // Process ==highlighted text== + + +function mark(state, silent) { + var found, + pos, + stack, + max = state.posMax, + start = state.pos, + lastChar, + nextChar; + + if (state.src.charCodeAt(start) !== 0x3D + /* = */ + ) { + return false; + } + + if (silent) { + return false; + } // don't run any pairs in validation mode + + + if (start + 4 >= max) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x3D + /* = */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; + nextChar = state.src.charCodeAt(start + 2); + + if (lastChar === 0x3D + /* = */ + ) { + return false; + } + + if (nextChar === 0x3D + /* = */ + ) { + return false; + } + + if (nextChar === 0x20 || nextChar === 0x0A) { + return false; + } + + pos = start + 2; + + while (pos < max && state.src.charCodeAt(pos) === 0x3D + /* = */ + ) { + pos++; + } + + if (pos !== start + 2) { + // sequence of 3+ markers taking as literal, same as in a emphasis + state.pos += pos - start; + + if (!silent) { + state.pending += state.src.slice(start, pos); + } + + return true; + } + + state.pos = start + 2; + stack = 1; + + while (state.pos + 1 < max) { + if (state.src.charCodeAt(state.pos) === 0x3D + /* = */ + ) { + if (state.src.charCodeAt(state.pos + 1) === 0x3D + /* = */ + ) { + lastChar = state.src.charCodeAt(state.pos - 1); + nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; + + if (nextChar !== 0x3D + /* = */ + && lastChar !== 0x3D + /* = */ + ) { + if (lastChar !== 0x20 && lastChar !== 0x0A) { + // closing '==' + stack--; + } else if (nextChar !== 0x20 && nextChar !== 0x0A) { + // opening '==' + stack++; + } // else { + // // standalone ' == ' indented with spaces + // } + + + if (stack <= 0) { + found = true; + break; + } + } + } + } + + state.parser.skipToken(state); + } + + if (!found) { + // parser failed to find ending tag, so it's not valid emphasis + state.pos = start; + return false; + } // found! + + + state.posMax = state.pos; + state.pos = start + 2; + + if (!silent) { + state.push({ + type: 'mark_open', + level: state.level++ + }); + state.parser.tokenize(state); + state.push({ + type: 'mark_close', + level: --state.level + }); + } + + state.pos = state.posMax + 2; + state.posMax = max; + return true; +} // Process *this* and _that_ + + +function isAlphaNum(code) { + return code >= 0x30 + /* 0 */ + && code <= 0x39 + /* 9 */ + || code >= 0x41 + /* A */ + && code <= 0x5A + /* Z */ + || code >= 0x61 + /* a */ + && code <= 0x7A + /* z */ + ; +} // parse sequence of emphasis markers, +// "start" should point at a valid marker + + +function scanDelims(state, start) { + var pos = start, + lastChar, + nextChar, + count, + can_open = true, + can_close = true, + max = state.posMax, + marker = state.src.charCodeAt(start); + lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; + + while (pos < max && state.src.charCodeAt(pos) === marker) { + pos++; + } + + if (pos >= max) { + can_open = false; + } + + count = pos - start; + + if (count >= 4) { + // sequence of four or more unescaped markers can't start/end an emphasis + can_open = can_close = false; + } else { + nextChar = pos < max ? state.src.charCodeAt(pos) : -1; // check whitespace conditions + + if (nextChar === 0x20 || nextChar === 0x0A) { + can_open = false; + } + + if (lastChar === 0x20 || lastChar === 0x0A) { + can_close = false; + } + + if (marker === 0x5F + /* _ */ + ) { + // check if we aren't inside the word + if (isAlphaNum(lastChar)) { + can_open = false; + } + + if (isAlphaNum(nextChar)) { + can_close = false; + } + } + } + + return { + can_open: can_open, + can_close: can_close, + delims: count + }; +} + +function emphasis(state, silent) { + var startCount, + count, + found, + oldCount, + newCount, + stack, + res, + max = state.posMax, + start = state.pos, + marker = state.src.charCodeAt(start); + + if (marker !== 0x5F + /* _ */ + && marker !== 0x2A + /* * */ + ) { + return false; + } + + if (silent) { + return false; + } // don't run any pairs in validation mode + + + res = scanDelims(state, start); + startCount = res.delims; + + if (!res.can_open) { + state.pos += startCount; + + if (!silent) { + state.pending += state.src.slice(start, state.pos); + } + + return true; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + state.pos = start + startCount; + stack = [startCount]; + + while (state.pos < max) { + if (state.src.charCodeAt(state.pos) === marker) { + res = scanDelims(state, state.pos); + count = res.delims; + + if (res.can_close) { + oldCount = stack.pop(); + newCount = count; + + while (oldCount !== newCount) { + if (newCount < oldCount) { + stack.push(oldCount - newCount); + break; + } // assert(newCount > oldCount) + + + newCount -= oldCount; + + if (stack.length === 0) { + break; + } + + state.pos += oldCount; + oldCount = stack.pop(); + } + + if (stack.length === 0) { + startCount = oldCount; + found = true; + break; + } + + state.pos += count; + continue; + } + + if (res.can_open) { + stack.push(count); + } + + state.pos += count; + continue; + } + + state.parser.skipToken(state); + } + + if (!found) { + // parser failed to find ending tag, so it's not valid emphasis + state.pos = start; + return false; + } // found! + + + state.posMax = state.pos; + state.pos = start + startCount; + + if (!silent) { + if (startCount === 2 || startCount === 3) { + state.push({ + type: 'strong_open', + level: state.level++ + }); + } + + if (startCount === 1 || startCount === 3) { + state.push({ + type: 'em_open', + level: state.level++ + }); + } + + state.parser.tokenize(state); + + if (startCount === 1 || startCount === 3) { + state.push({ + type: 'em_close', + level: --state.level + }); + } + + if (startCount === 2 || startCount === 3) { + state.push({ + type: 'strong_close', + level: --state.level + }); + } + } + + state.pos = state.posMax + startCount; + state.posMax = max; + return true; +} // Process ~subscript~ +// same as UNESCAPE_MD_RE plus a space + + +var UNESCAPE_RE = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g; + +function sub(state, silent) { + var found, + content, + max = state.posMax, + start = state.pos; + + if (state.src.charCodeAt(start) !== 0x7E + /* ~ */ + ) { + return false; + } + + if (silent) { + return false; + } // don't run any pairs in validation mode + + + if (start + 2 >= max) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + state.pos = start + 1; + + while (state.pos < max) { + if (state.src.charCodeAt(state.pos) === 0x7E + /* ~ */ + ) { + found = true; + break; + } + + state.parser.skipToken(state); + } + + if (!found || start + 1 === state.pos) { + state.pos = start; + return false; + } + + content = state.src.slice(start + 1, state.pos); // don't allow unescaped spaces/newlines inside + + if (content.match(/(^|[^\\])(\\\\)*\s/)) { + state.pos = start; + return false; + } // found! + + + state.posMax = state.pos; + state.pos = start + 1; + + if (!silent) { + state.push({ + type: 'sub', + level: state.level, + content: content.replace(UNESCAPE_RE, '$1') + }); + } + + state.pos = state.posMax + 1; + state.posMax = max; + return true; +} // Process ^superscript^ +// same as UNESCAPE_MD_RE plus a space + + +var UNESCAPE_RE$1 = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g; + +function sup(state, silent) { + var found, + content, + max = state.posMax, + start = state.pos; + + if (state.src.charCodeAt(start) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (silent) { + return false; + } // don't run any pairs in validation mode + + + if (start + 2 >= max) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + state.pos = start + 1; + + while (state.pos < max) { + if (state.src.charCodeAt(state.pos) === 0x5E + /* ^ */ + ) { + found = true; + break; + } + + state.parser.skipToken(state); + } + + if (!found || start + 1 === state.pos) { + state.pos = start; + return false; + } + + content = state.src.slice(start + 1, state.pos); // don't allow unescaped spaces/newlines inside + + if (content.match(/(^|[^\\])(\\\\)*\s/)) { + state.pos = start; + return false; + } // found! + + + state.posMax = state.pos; + state.pos = start + 1; + + if (!silent) { + state.push({ + type: 'sup', + level: state.level, + content: content.replace(UNESCAPE_RE$1, '$1') + }); + } + + state.pos = state.posMax + 1; + state.posMax = max; + return true; +} // Process [links]( "stuff") + + +function links(state, silent) { + var labelStart, + labelEnd, + label, + href, + title, + pos, + ref, + code, + isImage = false, + oldPos = state.pos, + max = state.posMax, + start = state.pos, + marker = state.src.charCodeAt(start); + + if (marker === 0x21 + /* ! */ + ) { + isImage = true; + marker = state.src.charCodeAt(++start); + } + + if (marker !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + labelStart = start + 1; + labelEnd = parseLinkLabel(state, start); // parser failed to find ']', so it's not a valid link + + if (labelEnd < 0) { + return false; + } + + pos = labelEnd + 1; + + if (pos < max && state.src.charCodeAt(pos) === 0x28 + /* ( */ + ) { + // + // Inline link + // + // [link]( "title" ) + // ^^ skipping these spaces + pos++; + + for (; pos < max; pos++) { + code = state.src.charCodeAt(pos); + + if (code !== 0x20 && code !== 0x0A) { + break; + } + } + + if (pos >= max) { + return false; + } // [link]( "title" ) + // ^^^^^^ parsing link destination + + + start = pos; + + if (parseLinkDestination(state, pos)) { + href = state.linkContent; + pos = state.pos; + } else { + href = ''; + } // [link]( "title" ) + // ^^ skipping these spaces + + + start = pos; + + for (; pos < max; pos++) { + code = state.src.charCodeAt(pos); + + if (code !== 0x20 && code !== 0x0A) { + break; + } + } // [link]( "title" ) + // ^^^^^^^ parsing link title + + + if (pos < max && start !== pos && parseLinkTitle(state, pos)) { + title = state.linkContent; + pos = state.pos; // [link]( "title" ) + // ^^ skipping these spaces + + for (; pos < max; pos++) { + code = state.src.charCodeAt(pos); + + if (code !== 0x20 && code !== 0x0A) { + break; + } + } + } else { + title = ''; + } + + if (pos >= max || state.src.charCodeAt(pos) !== 0x29 + /* ) */ + ) { + state.pos = oldPos; + return false; + } + + pos++; + } else { + // + // Link reference + // + // do not allow nested reference links + if (state.linkLevel > 0) { + return false; + } // [foo] [bar] + // ^^ optional whitespace (can include newlines) + + + for (; pos < max; pos++) { + code = state.src.charCodeAt(pos); + + if (code !== 0x20 && code !== 0x0A) { + break; + } + } + + if (pos < max && state.src.charCodeAt(pos) === 0x5B + /* [ */ + ) { + start = pos + 1; + pos = parseLinkLabel(state, pos); + + if (pos >= 0) { + label = state.src.slice(start, pos++); + } else { + pos = start - 1; + } + } // covers label === '' and label === undefined + // (collapsed reference link and shortcut reference link respectively) + + + if (!label) { + if (typeof label === 'undefined') { + pos = labelEnd + 1; + } + + label = state.src.slice(labelStart, labelEnd); + } + + ref = state.env.references[normalizeReference(label)]; + + if (!ref) { + state.pos = oldPos; + return false; + } + + href = ref.href; + title = ref.title; + } // + // We found the end of the link, and know for a fact it's a valid link; + // so all that's left to do is to call tokenizer. + // + + + if (!silent) { + state.pos = labelStart; + state.posMax = labelEnd; + + if (isImage) { + state.push({ + type: 'image', + src: href, + title: title, + alt: state.src.substr(labelStart, labelEnd - labelStart), + level: state.level + }); + } else { + state.push({ + type: 'link_open', + href: href, + title: title, + level: state.level++ + }); + state.linkLevel++; + state.parser.tokenize(state); + state.linkLevel--; + state.push({ + type: 'link_close', + level: --state.level + }); + } + } + + state.pos = pos; + state.posMax = max; + return true; +} // Process inline footnotes (^[...]) + + +function footnote_inline(state, silent) { + var labelStart, + labelEnd, + footnoteId, + oldLength, + max = state.posMax, + start = state.pos; + + if (start + 2 >= max) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + labelStart = start + 2; + labelEnd = parseLinkLabel(state, start + 1); // parser failed to find ']', so it's not a valid note + + if (labelEnd < 0) { + return false; + } // We found the end of the link, and know for a fact it's a valid link; + // so all that's left to do is to call tokenizer. + // + + + if (!silent) { + if (!state.env.footnotes) { + state.env.footnotes = {}; + } + + if (!state.env.footnotes.list) { + state.env.footnotes.list = []; + } + + footnoteId = state.env.footnotes.list.length; + state.pos = labelStart; + state.posMax = labelEnd; + state.push({ + type: 'footnote_ref', + id: footnoteId, + level: state.level + }); + state.linkLevel++; + oldLength = state.tokens.length; + state.parser.tokenize(state); + state.env.footnotes.list[footnoteId] = { + tokens: state.tokens.splice(oldLength) + }; + state.linkLevel--; + } + + state.pos = labelEnd + 1; + state.posMax = max; + return true; +} // Process footnote references ([^...]) + + +function footnote_ref(state, silent) { + var label, + pos, + footnoteId, + footnoteSubId, + max = state.posMax, + start = state.pos; // should be at least 4 chars - "[^x]" + + if (start + 3 > max) { + return false; + } + + if (!state.env.footnotes || !state.env.footnotes.refs) { + return false; + } + + if (state.src.charCodeAt(start) !== 0x5B + /* [ */ + ) { + return false; + } + + if (state.src.charCodeAt(start + 1) !== 0x5E + /* ^ */ + ) { + return false; + } + + if (state.level >= state.options.maxNesting) { + return false; + } + + for (pos = start + 2; pos < max; pos++) { + if (state.src.charCodeAt(pos) === 0x20) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x0A) { + return false; + } + + if (state.src.charCodeAt(pos) === 0x5D + /* ] */ + ) { + break; + } + } + + if (pos === start + 2) { + return false; + } // no empty footnote labels + + + if (pos >= max) { + return false; + } + + pos++; + label = state.src.slice(start + 2, pos - 1); + + if (typeof state.env.footnotes.refs[':' + label] === 'undefined') { + return false; + } + + if (!silent) { + if (!state.env.footnotes.list) { + state.env.footnotes.list = []; + } + + if (state.env.footnotes.refs[':' + label] < 0) { + footnoteId = state.env.footnotes.list.length; + state.env.footnotes.list[footnoteId] = { + label: label, + count: 0 + }; + state.env.footnotes.refs[':' + label] = footnoteId; + } else { + footnoteId = state.env.footnotes.refs[':' + label]; + } + + footnoteSubId = state.env.footnotes.list[footnoteId].count; + state.env.footnotes.list[footnoteId].count++; + state.push({ + type: 'footnote_ref', + id: footnoteId, + subId: footnoteSubId, + level: state.level + }); + } + + state.pos = pos; + state.posMax = max; + return true; +} // List of valid url schemas, accorting to commonmark spec +// http://jgm.github.io/CommonMark/spec.html#autolinks + + +var url_schemas = ['coap', 'doi', 'javascript', 'aaa', 'aaas', 'about', 'acap', 'cap', 'cid', 'crid', 'data', 'dav', 'dict', 'dns', 'file', 'ftp', 'geo', 'go', 'gopher', 'h323', 'http', 'https', 'iax', 'icap', 'im', 'imap', 'info', 'ipp', 'iris', 'iris.beep', 'iris.xpc', 'iris.xpcs', 'iris.lwz', 'ldap', 'mailto', 'mid', 'msrp', 'msrps', 'mtqp', 'mupdate', 'news', 'nfs', 'ni', 'nih', 'nntp', 'opaquelocktoken', 'pop', 'pres', 'rtsp', 'service', 'session', 'shttp', 'sieve', 'sip', 'sips', 'sms', 'snmp', 'soap.beep', 'soap.beeps', 'tag', 'tel', 'telnet', 'tftp', 'thismessage', 'tn3270', 'tip', 'tv', 'urn', 'vemmi', 'ws', 'wss', 'xcon', 'xcon-userid', 'xmlrpc.beep', 'xmlrpc.beeps', 'xmpp', 'z39.50r', 'z39.50s', 'adiumxtra', 'afp', 'afs', 'aim', 'apt', 'attachment', 'aw', 'beshare', 'bitcoin', 'bolo', 'callto', 'chrome', 'chrome-extension', 'com-eventbrite-attendee', 'content', 'cvs', 'dlna-playsingle', 'dlna-playcontainer', 'dtn', 'dvb', 'ed2k', 'facetime', 'feed', 'finger', 'fish', 'gg', 'git', 'gizmoproject', 'gtalk', 'hcp', 'icon', 'ipn', 'irc', 'irc6', 'ircs', 'itms', 'jar', 'jms', 'keyparc', 'lastfm', 'ldaps', 'magnet', 'maps', 'market', 'message', 'mms', 'ms-help', 'msnim', 'mumble', 'mvn', 'notes', 'oid', 'palm', 'paparazzi', 'platform', 'proxy', 'psyc', 'query', 'res', 'resource', 'rmi', 'rsync', 'rtmp', 'secondlife', 'sftp', 'sgn', 'skype', 'smb', 'soldat', 'spotify', 'ssh', 'steam', 'svn', 'teamspeak', 'things', 'udp', 'unreal', 'ut2004', 'ventrilo', 'view-source', 'webcal', 'wtai', 'wyciwyg', 'xfire', 'xri', 'ymsgr']; // Process autolinks '' + +/*eslint max-len:0*/ + +var EMAIL_RE = /^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/; +var AUTOLINK_RE = /^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/; + +function autolink(state, silent) { + var tail, + linkMatch, + emailMatch, + url, + fullUrl, + pos = state.pos; + + if (state.src.charCodeAt(pos) !== 0x3C + /* < */ + ) { + return false; + } + + tail = state.src.slice(pos); + + if (tail.indexOf('>') < 0) { + return false; + } + + linkMatch = tail.match(AUTOLINK_RE); + + if (linkMatch) { + if (url_schemas.indexOf(linkMatch[1].toLowerCase()) < 0) { + return false; + } + + url = linkMatch[0].slice(1, -1); + fullUrl = normalizeLink(url); + + if (!state.parser.validateLink(url)) { + return false; + } + + if (!silent) { + state.push({ + type: 'link_open', + href: fullUrl, + level: state.level + }); + state.push({ + type: 'text', + content: url, + level: state.level + 1 + }); + state.push({ + type: 'link_close', + level: state.level + }); + } + + state.pos += linkMatch[0].length; + return true; + } + + emailMatch = tail.match(EMAIL_RE); + + if (emailMatch) { + url = emailMatch[0].slice(1, -1); + fullUrl = normalizeLink('mailto:' + url); + + if (!state.parser.validateLink(fullUrl)) { + return false; + } + + if (!silent) { + state.push({ + type: 'link_open', + href: fullUrl, + level: state.level + }); + state.push({ + type: 'text', + content: url, + level: state.level + 1 + }); + state.push({ + type: 'link_close', + level: state.level + }); + } + + state.pos += emailMatch[0].length; + return true; + } + + return false; +} // Regexps to match html elements + + +function replace$1(regex, options) { + regex = regex.source; + options = options || ''; + return function self(name, val) { + if (!name) { + return new RegExp(regex, options); + } + + val = val.source || val; + regex = regex.replace(name, val); + return self; + }; +} + +var attr_name = /[a-zA-Z_:][a-zA-Z0-9:._-]*/; +var unquoted = /[^"'=<>`\x00-\x20]+/; +var single_quoted = /'[^']*'/; +var double_quoted = /"[^"]*"/; +/*eslint no-spaced-func:0*/ + +var attr_value = replace$1(/(?:unquoted|single_quoted|double_quoted)/)('unquoted', unquoted)('single_quoted', single_quoted)('double_quoted', double_quoted)(); +var attribute = replace$1(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)('attr_name', attr_name)('attr_value', attr_value)(); +var open_tag = replace$1(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)('attribute', attribute)(); +var close_tag = /<\/[A-Za-z][A-Za-z0-9]*\s*>/; +var comment = /|/; +var processing = /<[?].*?[?]>/; +var declaration = /]*>/; +var cdata = //; +var HTML_TAG_RE = replace$1(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)('open_tag', open_tag)('close_tag', close_tag)('comment', comment)('processing', processing)('declaration', declaration)('cdata', cdata)(); // Process html tags + +function isLetter$2(ch) { + /*eslint no-bitwise:0*/ + var lc = ch | 0x20; // to lower case + + return lc >= 0x61 + /* a */ + && lc <= 0x7a + /* z */ + ; +} + +function htmltag(state, silent) { + var ch, + match, + max, + pos = state.pos; + + if (!state.options.html) { + return false; + } // Check start + + + max = state.posMax; + + if (state.src.charCodeAt(pos) !== 0x3C + /* < */ + || pos + 2 >= max) { + return false; + } // Quick fail on second char + + + ch = state.src.charCodeAt(pos + 1); + + if (ch !== 0x21 + /* ! */ + && ch !== 0x3F + /* ? */ + && ch !== 0x2F + /* / */ + && !isLetter$2(ch)) { + return false; + } + + match = state.src.slice(pos).match(HTML_TAG_RE); + + if (!match) { + return false; + } + + if (!silent) { + state.push({ + type: 'htmltag', + content: state.src.slice(pos, pos + match[0].length), + level: state.level + }); + } + + state.pos += match[0].length; + return true; +} // Process html entity - {, ¯, ", ... + + +var DIGITAL_RE = /^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i; +var NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i; + +function entity(state, silent) { + var ch, + code, + match, + pos = state.pos, + max = state.posMax; + + if (state.src.charCodeAt(pos) !== 0x26 + /* & */ + ) { + return false; + } + + if (pos + 1 < max) { + ch = state.src.charCodeAt(pos + 1); + + if (ch === 0x23 + /* # */ + ) { + match = state.src.slice(pos).match(DIGITAL_RE); + + if (match) { + if (!silent) { + code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10); + state.pending += isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD); + } + + state.pos += match[0].length; + return true; + } + } else { + match = state.src.slice(pos).match(NAMED_RE); + + if (match) { + var decoded = decodeEntity(match[1]); + + if (match[1] !== decoded) { + if (!silent) { + state.pending += decoded; + } + + state.pos += match[0].length; + return true; + } + } + } + } + + if (!silent) { + state.pending += '&'; + } + + state.pos++; + return true; +} +/** + * Inline Parser `rules` + */ + + +var _rules$2 = [['text', text], ['newline', newline], ['escape', escape], ['backticks', backticks], ['del', del], ['ins', ins], ['mark', mark], ['emphasis', emphasis], ['sub', sub], ['sup', sup], ['links', links], ['footnote_inline', footnote_inline], ['footnote_ref', footnote_ref], ['autolink', autolink], ['htmltag', htmltag], ['entity', entity]]; +/** + * Inline Parser class. Note that link validation is stricter + * in Remarkable than what is specified by CommonMark. If you + * want to change this you can use a custom validator. + * + * @api private + */ + +function ParserInline() { + this.ruler = new Ruler(); + + for (var i = 0; i < _rules$2.length; i++) { + this.ruler.push(_rules$2[i][0], _rules$2[i][1]); + } // Can be overridden with a custom validator + + + this.validateLink = validateLink; +} +/** + * Skip a single token by running all rules in validation mode. + * Returns `true` if any rule reports success. + * + * @param {Object} `state` + * @api privage + */ + + +ParserInline.prototype.skipToken = function (state) { + var rules = this.ruler.getRules(''); + var len = rules.length; + var pos = state.pos; + var i, cached_pos; + + if ((cached_pos = state.cacheGet(pos)) > 0) { + state.pos = cached_pos; + return; + } + + for (i = 0; i < len; i++) { + if (rules[i](state, true)) { + state.cacheSet(pos, state.pos); + return; + } + } + + state.pos++; + state.cacheSet(pos, state.pos); +}; +/** + * Generate tokens for the given input range. + * + * @param {Object} `state` + * @api private + */ + + +ParserInline.prototype.tokenize = function (state) { + var rules = this.ruler.getRules(''); + var len = rules.length; + var end = state.posMax; + var ok, i; + + while (state.pos < end) { + // Try all possible rules. + // On success, the rule should: + // + // - update `state.pos` + // - update `state.tokens` + // - return true + for (i = 0; i < len; i++) { + ok = rules[i](state, false); + + if (ok) { + break; + } + } + + if (ok) { + if (state.pos >= end) { + break; + } + + continue; + } + + state.pending += state.src[state.pos++]; + } + + if (state.pending) { + state.pushPending(); + } +}; +/** + * Parse the given input string. + * + * @param {String} `str` + * @param {Object} `options` + * @param {Object} `env` + * @param {Array} `outTokens` + * @api private + */ + + +ParserInline.prototype.parse = function (str, options, env, outTokens) { + var state = new StateInline(str, this, options, env, outTokens); + this.tokenize(state); +}; +/** + * Validate the given `url` by checking for bad protocols. + * + * @param {String} `url` + * @return {Boolean} + */ + + +function validateLink(url) { + var BAD_PROTOCOLS = ['vbscript', 'javascript', 'file', 'data']; + var str = url.trim().toLowerCase(); // Care about digital entities "javascript:alert(1)" + + str = replaceEntities(str); + + if (str.indexOf(':') !== -1 && BAD_PROTOCOLS.indexOf(str.split(':')[0]) !== -1) { + return false; + } + + return true; +} // Remarkable default options + + +var defaultConfig = { + options: { + html: false, + // Enable HTML tags in source + xhtmlOut: false, + // Use '/' to close single tags (
    ) + breaks: false, + // Convert '\n' in paragraphs into
    + langPrefix: 'language-', + // CSS language prefix for fenced blocks + linkTarget: '', + // set target to open link in + // Enable some language-neutral replacements + quotes beautification + typographer: false, + // Double + single quotes replacement pairs, when typographer enabled, + // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German. + quotes: '“”‘’', + // Highlighter function. Should return escaped HTML, + // or '' if input not changed + // + // function (/*str, lang*/) { return ''; } + // + highlight: null, + maxNesting: 20 // Internal protection, recursion limit + + }, + components: { + core: { + rules: ['block', 'inline', 'references', 'replacements', 'smartquotes', 'references', 'abbr2', 'footnote_tail'] + }, + block: { + rules: ['blockquote', 'code', 'fences', 'footnote', 'heading', 'hr', 'htmlblock', 'lheading', 'list', 'paragraph', 'table'] + }, + inline: { + rules: ['autolink', 'backticks', 'del', 'emphasis', 'entity', 'escape', 'footnote_ref', 'htmltag', 'links', 'newline', 'text'] + } + } +}; // Remarkable default options + +var fullConfig = { + options: { + html: false, + // Enable HTML tags in source + xhtmlOut: false, + // Use '/' to close single tags (
    ) + breaks: false, + // Convert '\n' in paragraphs into
    + langPrefix: 'language-', + // CSS language prefix for fenced blocks + linkTarget: '', + // set target to open link in + // Enable some language-neutral replacements + quotes beautification + typographer: false, + // Double + single quotes replacement pairs, when typographer enabled, + // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German. + quotes: '“”‘’', + // Highlighter function. Should return escaped HTML, + // or '' if input not changed + // + // function (/*str, lang*/) { return ''; } + // + highlight: null, + maxNesting: 20 // Internal protection, recursion limit + + }, + components: { + // Don't restrict core/block/inline rules + core: {}, + block: {}, + inline: {} + } +}; // Commonmark default options + +var commonmarkConfig = { + options: { + html: true, + // Enable HTML tags in source + xhtmlOut: true, + // Use '/' to close single tags (
    ) + breaks: false, + // Convert '\n' in paragraphs into
    + langPrefix: 'language-', + // CSS language prefix for fenced blocks + linkTarget: '', + // set target to open link in + // Enable some language-neutral replacements + quotes beautification + typographer: false, + // Double + single quotes replacement pairs, when typographer enabled, + // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German. + quotes: '“”‘’', + // Highlighter function. Should return escaped HTML, + // or '' if input not changed + // + // function (/*str, lang*/) { return ''; } + // + highlight: null, + maxNesting: 20 // Internal protection, recursion limit + + }, + components: { + core: { + rules: ['block', 'inline', 'references', 'abbr2'] + }, + block: { + rules: ['blockquote', 'code', 'fences', 'heading', 'hr', 'htmlblock', 'lheading', 'list', 'paragraph'] + }, + inline: { + rules: ['autolink', 'backticks', 'emphasis', 'entity', 'escape', 'htmltag', 'links', 'newline', 'text'] + } + } +}; +/** + * Preset configs + */ + +var config = { + 'default': defaultConfig, + 'full': fullConfig, + 'commonmark': commonmarkConfig +}; +/** + * The `StateCore` class manages state. + * + * @param {Object} `instance` Remarkable instance + * @param {String} `str` Markdown string + * @param {Object} `env` + */ + +function StateCore(instance, str, env) { + this.src = str; + this.env = env; + this.options = instance.options; + this.tokens = []; + this.inlineMode = false; + this.inline = instance.inline; + this.block = instance.block; + this.renderer = instance.renderer; + this.typographer = instance.typographer; +} +/** + * The main `Remarkable` class. Create an instance of + * `Remarkable` with a `preset` and/or `options`. + * + * @param {String} `preset` If no preset is given, `default` is used. + * @param {Object} `options` + */ + + +function Remarkable(preset, options) { + if (typeof preset !== 'string') { + options = preset; + preset = 'default'; + } + + if (options && options.linkify != null) { + console.warn('linkify option is removed. Use linkify plugin instead:\n\n' + 'import Remarkable from \'remarkable\';\n' + 'import linkify from \'remarkable/linkify\';\n' + 'new Remarkable().use(linkify)\n'); + } + + this.inline = new ParserInline(); + this.block = new ParserBlock(); + this.core = new Core(); + this.renderer = new Renderer(); + this.ruler = new Ruler(); + this.options = {}; + this.configure(config[preset]); + this.set(options || {}); +} +/** + * Set options as an alternative to passing them + * to the constructor. + * + * ```js + * md.set({typographer: true}); + * ``` + * @param {Object} `options` + * @api public + */ + + +Remarkable.prototype.set = function (options) { + assign(this.options, options); +}; +/** + * Batch loader for components rules states, and options + * + * @param {Object} `presets` + */ + + +Remarkable.prototype.configure = function (presets) { + var self = this; + + if (!presets) { + throw new Error('Wrong `remarkable` preset, check name/content'); + } + + if (presets.options) { + self.set(presets.options); + } + + if (presets.components) { + Object.keys(presets.components).forEach(function (name) { + if (presets.components[name].rules) { + self[name].ruler.enable(presets.components[name].rules, true); + } + }); + } +}; +/** + * Use a plugin. + * + * ```js + * var md = new Remarkable(); + * + * md.use(plugin1) + * .use(plugin2, opts) + * .use(plugin3); + * ``` + * + * @param {Function} `plugin` + * @param {Object} `options` + * @return {Object} `Remarkable` for chaining + */ + + +Remarkable.prototype.use = function (plugin, options) { + plugin(this, options); + return this; +}; +/** + * Parse the input `string` and return a tokens array. + * Modifies `env` with definitions data. + * + * @param {String} `string` + * @param {Object} `env` + * @return {Array} Array of tokens + */ + + +Remarkable.prototype.parse = function (str, env) { + var state = new StateCore(this, str, env); + this.core.process(state); + return state.tokens; +}; +/** + * The main `.render()` method that does all the magic :) + * + * @param {String} `string` + * @param {Object} `env` + * @return {String} Rendered HTML. + */ + + +Remarkable.prototype.render = function (str, env) { + env = env || {}; + return this.renderer.render(this.parse(str, env), this.options, env); +}; +/** + * Parse the given content `string` as a single string. + * + * @param {String} `string` + * @param {Object} `env` + * @return {Array} Array of tokens + */ + + +Remarkable.prototype.parseInline = function (str, env) { + var state = new StateCore(this, str, env); + state.inlineMode = true; + this.core.process(state); + return state.tokens; +}; +/** + * Render a single content `string`, without wrapping it + * to paragraphs + * + * @param {String} `str` + * @param {Object} `env` + * @return {String} + */ + + +Remarkable.prototype.renderInline = function (str, env) { + env = env || {}; + return this.renderer.render(this.parseInline(str, env), this.options, env); +}; + +/** + * Plugin for Remarkable Markdown processor which transforms $..$ and $$..$$ sequences into math HTML using the + * Katex package. + */ + +var rkatex = function rkatex(md, options) { + var dollar = '$'; + var opts = options || {}; + var delimiter = opts.delimiter || dollar; + + if (delimiter.length !== 1) { + throw new Error('invalid delimiter'); + } + + var katex = require$$0__default; + /** + * Render the contents as KaTeX + */ + + + var renderKatex = function renderKatex(source, displayMode) { + return katex.renderToString(source, { + displayMode: displayMode, + throwOnError: false + }); + }; + /** + * Parse '$$' as a block. Based off of similar method in remarkable. + */ + + + var parseBlockKatex = function parseBlockKatex(state, startLine, endLine) { + var haveEndMarker = false; + var pos = state.bMarks[startLine] + state.tShift[startLine]; + var max = state.eMarks[startLine]; + + if (pos + 1 > max) { + return false; + } + + var marker = state.src.charAt(pos); + + if (marker !== delimiter) { + return false; + } // scan marker length + + + var mem = pos; + pos = state.skipChars(pos, marker); + var len = pos - mem; + + if (len !== 2) { + return false; + } // search end of block + + + var nextLine = startLine; + + for (;;) { + ++nextLine; + + if (nextLine >= endLine) { + break; + } + + pos = mem = state.bMarks[nextLine] + state.tShift[nextLine]; + max = state.eMarks[nextLine]; + + if (pos < max && state.tShift[nextLine] < state.blkIndent) { + break; + } + + if (state.src.charAt(pos) !== delimiter) { + continue; + } + + if (state.tShift[nextLine] - state.blkIndent >= 4) { + continue; + } + + pos = state.skipChars(pos, marker); + + if (pos - mem < len) { + continue; + } + + pos = state.skipSpaces(pos); + + if (pos < max) { + continue; + } + + haveEndMarker = true; + break; + } // If a fence has heading spaces, they should be removed from its inner block + + + len = state.tShift[startLine]; + state.line = nextLine + (haveEndMarker ? 1 : 0); + var content = state.getLines(startLine + 1, nextLine, len, true).replace(/[ \n]+/g, ' ').trim(); + state.tokens.push({ + type: 'katex', + params: null, + content: content, + lines: [startLine, state.line], + level: state.level, + block: true + }); + return true; + }; + /** + * Look for '$' or '$$' spans in Markdown text. Based off of the 'fenced' parser in remarkable. + */ + + + var parseInlineKatex = function parseInlineKatex(state, silent) { + var start = state.pos; + var max = state.posMax; + var pos = start; // Unexpected starting character + + if (state.src.charAt(pos) !== delimiter) { + return false; + } + + ++pos; + + while (pos < max && state.src.charAt(pos) === delimiter) { + ++pos; + } // Capture the length of the starting delimiter -- closing one must match in size + + + var marker = state.src.slice(start, pos); + + if (marker.length > 2) { + return false; + } + + var spanStart = pos; + var escapedDepth = 0; + + while (pos < max) { + var _char = state.src.charAt(pos); + + if (_char === '{') { + escapedDepth += 1; + } else if (_char === '}') { + escapedDepth -= 1; + + if (escapedDepth < 0) { + return false; + } + } else if (_char === delimiter && escapedDepth === 0) { + var matchStart = pos; + var matchEnd = pos + 1; + + while (matchEnd < max && state.src.charAt(matchEnd) === delimiter) { + ++matchEnd; + } + + if (matchEnd - matchStart === marker.length) { + if (!silent) { + var content = state.src.slice(spanStart, matchStart).replace(/[ \n]+/g, ' ').trim(); + state.push({ + type: 'katex', + content: content, + block: marker.length > 1, + level: state.level + }); + } + + state.pos = matchEnd; + return true; + } + } + + pos += 1; + } + + if (!silent) { + state.pending += marker; + } + + state.pos += marker.length; + return true; + }; + + md.inline.ruler.push('katex', parseInlineKatex, options); + md.block.ruler.push('katex', parseBlockKatex, options); + + md.renderer.rules.katex = function (tokens, idx) { + return renderKatex(tokens[idx].content, tokens[idx].block); + }; + + md.renderer.rules.katex.delimiter = delimiter; +}; + +var remarkableKatex = rkatex; + +let loading$1; + +const autoload$1 = () => { + loading$1 = loading$1 || loadJS([{ + type: 'script', + data: { + src: 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js' + } + }]); + return loading$1; +}; + +const name$1 = 'katex'; +function transform$1(transformHooks) { + transformHooks.parser.tap((md, features) => { + md.use(remarkableKatex); + + const renderKatex = (source, displayMode) => { + const { + katex + } = window; + if (katex) return katex.renderToString(source, { + displayMode, + throwOnError: false + }); + autoload$1().then(() => { + transformHooks.retransform.call(); + }); + return source; + }; + + md.renderer.rules.katex = (tokens, idx) => { + const result = renderKatex(tokens[idx].content, tokens[idx].block); + features[name$1] = true; + return result; + }; + }); + return { + styles: [{ + type: 'stylesheet', + data: { + href: 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css' + } + }], + scripts: [{ + type: 'iife', + data: { + fn: getMarkmap => { + window.WebFontConfig = { + custom: { + families: ['KaTeX_AMS', 'KaTeX_Caligraphic:n4,n7', 'KaTeX_Fraktur:n4,n7', 'KaTeX_Main:n4,n7,i4,i7', 'KaTeX_Math:i4,i7', 'KaTeX_Script', 'KaTeX_SansSerif:n4,n7,i4', 'KaTeX_Size1', 'KaTeX_Size2', 'KaTeX_Size3', 'KaTeX_Size4', 'KaTeX_Typewriter'] + }, + active: () => { + getMarkmap().refreshHook.call(); + } + }; + }, + + getParams({ + getMarkmap + }) { + return [getMarkmap]; + } + + } + }, { + type: 'script', + data: { + src: 'https://cdn.jsdelivr.net/npm/webfontloader@1.6.28/webfontloader.js', + defer: true + } + }] + }; +} + +var katex = /*#__PURE__*/Object.freeze({ +__proto__: null, +name: name$1, +transform: transform$1 +}); + +let loading; + +const autoload = () => { + loading = loading || loadJS([{ + type: 'script', + data: { + src: `https://cdn.jsdelivr.net/npm/prismjs@${"1.23.0"}/components/prism-core.min.js` + } + }, { + type: 'script', + data: { + src: `https://cdn.jsdelivr.net/npm/prismjs@${"1.23.0"}/plugins/autoloader/prism-autoloader.min.js` + } + }]); + return loading; +}; + +function loadLanguageAndRefresh(lang, transformHooks) { + autoload().then(() => { + window.Prism.plugins.autoloader.loadLanguages([lang], () => { + transformHooks.retransform.call(); + }); + }); +} + +const name = 'prism'; +function transform(transformHooks) { + transformHooks.parser.tap((md, features) => { + md.set({ + highlight: (str, lang) => { + var _Prism$languages; + + features[name] = true; + const { + Prism + } = window; + const grammar = Prism == null ? void 0 : (_Prism$languages = Prism.languages) == null ? void 0 : _Prism$languages[lang]; + + if (!grammar) { + loadLanguageAndRefresh(lang, transformHooks); + return ''; + } + + return Prism.highlight(str, grammar, lang); + } + }); + }); + return { + styles: [{ + type: 'stylesheet', + data: { + href: `https://cdn.jsdelivr.net/npm/prismjs@${"1.23.0"}/themes/prism.css` + } + }] + }; +} + +var prism = /*#__PURE__*/Object.freeze({ +__proto__: null, +name: name, +transform: transform +}); + +function createTransformHooks() { + return { + parser: new Hook(), + htmltag: new Hook(), + + /** + * Indicate that the last transformation is not complete for reasons like + * lack of resources and is called when it is ready for a new transformation. + */ + retransform: new Hook() + }; +} + +const plugins = [katex, prism]; + +function cleanNode(node, depth = 0) { + if (node.t === 'heading') { + // drop all paragraphs + node.c = node.c.filter(item => item.t !== 'paragraph'); + } else if (node.t === 'list_item') { + var _node$p; + + // keep first paragraph as content of list_item, drop others + node.c = node.c.filter(item => { + if (['paragraph', 'fence'].includes(item.t)) { + if (!node.v) { + node.v = item.v; + node.p = _extends$1({}, node.p, item.p); + } + + return false; + } + + return true; + }); + + if (((_node$p = node.p) == null ? void 0 : _node$p.index) != null) { + node.v = `${node.p.index}. ${node.v}`; + } + } else if (node.t === 'ordered_list') { + var _node$p$start, _node$p2; + + let index = (_node$p$start = (_node$p2 = node.p) == null ? void 0 : _node$p2.start) != null ? _node$p$start : 1; + node.c.forEach(item => { + if (item.t === 'list_item') { + item.p = _extends$1({}, item.p, { + index + }); + index += 1; + } + }); + } + + if (node.c.length === 0) { + delete node.c; + } else { + node.c.forEach(child => cleanNode(child, depth + 1)); + + if (node.c.length === 1 && !node.c[0].v) { + node.c = node.c[0].c; + } + } + + node.d = depth; +} + +class Transformer { + constructor(plugins$1 = plugins) { + this.plugins = void 0; + this.hooks = void 0; + this.md = void 0; + this.assetsMap = void 0; + this.plugins = plugins$1; + this.hooks = createTransformHooks(); + const md = new Remarkable({ + html: true, + breaks: true, + maxNesting: Infinity + }); + md.block.ruler.enable(['deflist']); + md.renderer.rules.htmltag = wrapFunction(md.renderer.rules.htmltag, { + after: ctx => { + this.hooks.htmltag.call(ctx); + } + }); + this.md = md; + const assetsMap = {}; + + for (const { + name, + transform + } of plugins$1) { + assetsMap[name] = transform(this.hooks); + } + + this.assetsMap = assetsMap; + } + + buildTree(tokens) { + + const root = { + t: 'root', + d: 0, + v: '', + c: [], + p: {} + }; + const stack = [root]; + let depth = 0; + + for (const token of tokens) { + let current = stack[stack.length - 1]; + + if (token.type.endsWith('_open')) { + const type = token.type.slice(0, -5); + const payload = {}; + + if (token.lines) { + payload.lines = token.lines; + } + + if (type === 'heading') { + depth = token.hLevel; + + while (((_current = current) == null ? void 0 : _current.d) >= depth) { + var _current; + + stack.pop(); + current = stack[stack.length - 1]; + } + } else { + var _current2; + + depth = Math.max(depth, ((_current2 = current) == null ? void 0 : _current2.d) || 0) + 1; + + if (type === 'ordered_list') { + payload.start = token.order; + } + } + + const item = { + t: type, + d: depth, + p: payload, + v: '', + c: [] + }; + current.c.push(item); + stack.push(item); + } else if (!current) { + continue; + } else if (token.type === `${current.t}_close`) { + if (current.t === 'heading') { + depth = current.d; + } else { + stack.pop(); + depth = 0; + } + } else if (token.type === 'inline') { + const revoke = this.hooks.htmltag.tap(ctx => { + const comment = ctx.result.match(/^$/); + const data = comment == null ? void 0 : comment[1].trim(); + + if (data === 'fold') { + current.p.f = true; + ctx.result = ''; + } + }); + // const text = md.renderer.render([token], md.options, {}); + let text=''; + if(token.children&&token.children.length==1){ + if(token.children[0].type&&token.children[0].type=='link_open'){ + text = `[${token.children[1].content}](${token.children[0].href})`; + }else { + text = token.content.trim(); + // text = text.replace(/\n/g,"
    "); + } + }else { + text = token.content.trim(); + // text = text.replace(/\n/g,"
    "); + } + revoke(); + current.v = `${current.v || ''}${text}`; + } else if (token.type === 'fence') { + // let result = md.renderer.render([token], md.options, {}); // Remarkable only adds className to `` but not `
    `, copy it to make PrismJS style work.
    +
    +        // const matches = result.match(//);
    +        // if (matches) result = result.replace('
    ', ``);
    +        let result = '```'+ token.params + '\n';
    +        result = result + token.content;
    +        result = result+'```\n';
    +
    +        current.c.push({
    +          t: token.type,
    +          d: depth + 1,
    +          v: result,
    +          c: []
    +        });
    +      } else ;
    +    }
    +
    +    return root;
    +  }
    +
    +  transform(content) {
    +    var _root$c;
    +
    +    const features = {};
    +    this.hooks.parser.call(this.md, features);
    +    const tokens = this.md.parse(content || '', {});
    +    let root = this.buildTree(tokens);
    +    cleanNode(root);
    +    if (((_root$c = root.c) == null ? void 0 : _root$c.length) === 1) root = root.c[0];
    +    return {
    +      root,
    +      features
    +    };
    +  }
    +  /**
    +   * Get all assets from enabled plugins or filter them by plugin names as keys.
    +   */
    +
    +
    +  getAssets(keys) {
    +    var _keys;
    +
    +    const styles = [];
    +    const scripts = [];
    +    (_keys = keys) != null ? _keys : keys = Object.keys(this.assetsMap);
    +
    +    for (const assets of keys.map(key => this.assetsMap[key])) {
    +      if (assets) {
    +        if (assets.styles) styles.push(...assets.styles);
    +        if (assets.scripts) scripts.push(...assets.scripts);
    +      }
    +    }
    +
    +    return {
    +      styles,
    +      scripts
    +    };
    +  }
    +  /**
    +   * Get used assets by features object returned by `transform`.
    +   */
    +
    +
    +  getUsedAssets(features) {
    +    return this.getAssets(Object.keys(features).filter(key => features[key]));
    +  }
    +
    +}
    +
    +exports.Transformer = Transformer;
    +exports.builtInPlugins = plugins;
    +exports.fillTemplate = fillTemplate;
    +
    +})));
    +});
    +
    +var domtoimage = createCommonjsModule(function (module) {
    +(function (global) {
    +
    +    var util = newUtil();
    +    var inliner = newInliner();
    +    var fontFaces = newFontFaces();
    +    var images = newImages();
    +
    +    // Default impl options
    +    var defaultOptions = {
    +        // Default is to fail on error, no placeholder
    +        imagePlaceholder: undefined,
    +        // Default cache bust is false, it will use the cache
    +        cacheBust: false
    +    };
    +
    +    var domtoimage = {
    +        toSvg: toSvg,
    +        toPng: toPng,
    +        toJpeg: toJpeg,
    +        toBlob: toBlob,
    +        toPixelData: toPixelData,
    +        impl: {
    +            fontFaces: fontFaces,
    +            images: images,
    +            util: util,
    +            inliner: inliner,
    +            options: {}
    +        }
    +    };
    +
    +    module.exports = domtoimage;
    +
    +
    +    /**
    +     * @param {Node} node - The DOM Node object to render
    +     * @param {Object} options - Rendering options
    +     * @param {Function} options.filter - Should return true if passed node should be included in the output
    +     *          (excluding node means excluding it's children as well). Not called on the root node.
    +     * @param {String} options.bgcolor - color for the background, any valid CSS color value.
    +     * @param {Number} options.width - width to be applied to node before rendering.
    +     * @param {Number} options.height - height to be applied to node before rendering.
    +     * @param {Object} options.style - an object whose properties to be copied to node's style before rendering.
    +     * @param {Number} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only),
    +                defaults to 1.0.
    +     * @param {String} options.imagePlaceholder - dataURL to use as a placeholder for failed images, default behaviour is to fail fast on images we can't fetch
    +     * @param {Boolean} options.cacheBust - set to true to cache bust by appending the time to the request url
    +     * @return {Promise} - A promise that is fulfilled with a SVG image data URL
    +     * */
    +    function toSvg(node, options) {
    +        options = options || {};
    +        copyOptions(options);
    +        return Promise.resolve(node)
    +            .then(function (node) {
    +                return cloneNode(node, options.filter, true);
    +            })
    +            .then(embedFonts)
    +            .then(inlineImages)
    +            .then(applyOptions)
    +            .then(function (clone) {
    +                return makeSvgDataUri(clone,
    +                    options.width || util.width(node),
    +                    options.height || util.height(node)
    +                );
    +            });
    +
    +        function applyOptions(clone) {
    +            if (options.bgcolor) clone.style.backgroundColor = options.bgcolor;
    +
    +            if (options.width) clone.style.width = options.width + 'px';
    +            if (options.height) clone.style.height = options.height + 'px';
    +
    +            if (options.style)
    +                Object.keys(options.style).forEach(function (property) {
    +                    clone.style[property] = options.style[property];
    +                });
    +
    +            return clone;
    +        }
    +    }
    +
    +    /**
    +     * @param {Node} node - The DOM Node object to render
    +     * @param {Object} options - Rendering options, @see {@link toSvg}
    +     * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data.
    +     * */
    +    function toPixelData(node, options) {
    +        return draw(node, options || {})
    +            .then(function (canvas) {
    +                return canvas.getContext('2d').getImageData(
    +                    0,
    +                    0,
    +                    util.width(node),
    +                    util.height(node)
    +                ).data;
    +            });
    +    }
    +
    +    /**
    +     * @param {Node} node - The DOM Node object to render
    +     * @param {Object} options - Rendering options, @see {@link toSvg}
    +     * @return {Promise} - A promise that is fulfilled with a PNG image data URL
    +     * */
    +    function toPng(node, options) {
    +        return draw(node, options || {})
    +            .then(function (canvas) {
    +                return canvas.toDataURL();
    +            });
    +    }
    +
    +    /**
    +     * @param {Node} node - The DOM Node object to render
    +     * @param {Object} options - Rendering options, @see {@link toSvg}
    +     * @return {Promise} - A promise that is fulfilled with a JPEG image data URL
    +     * */
    +    function toJpeg(node, options) {
    +        options = options || {};
    +        return draw(node, options)
    +            .then(function (canvas) {
    +                return canvas.toDataURL('image/jpeg', options.quality || 1.0);
    +            });
    +    }
    +
    +    /**
    +     * @param {Node} node - The DOM Node object to render
    +     * @param {Object} options - Rendering options, @see {@link toSvg}
    +     * @return {Promise} - A promise that is fulfilled with a PNG image blob
    +     * */
    +    function toBlob(node, options) {
    +        return draw(node, options || {})
    +            .then(util.canvasToBlob);
    +    }
    +
    +    function copyOptions(options) {
    +        // Copy options to impl options for use in impl
    +        if(typeof(options.imagePlaceholder) === 'undefined') {
    +            domtoimage.impl.options.imagePlaceholder = defaultOptions.imagePlaceholder;
    +        } else {
    +            domtoimage.impl.options.imagePlaceholder = options.imagePlaceholder;
    +        }
    +
    +        if(typeof(options.cacheBust) === 'undefined') {
    +            domtoimage.impl.options.cacheBust = defaultOptions.cacheBust;
    +        } else {
    +            domtoimage.impl.options.cacheBust = options.cacheBust;
    +        }
    +    }
    +
    +    function draw(domNode, options) {
    +        return toSvg(domNode, options)
    +            .then(util.makeImage)
    +            .then(util.delay(100))
    +            .then(function (image) {
    +                var canvas = newCanvas(domNode);
    +                canvas.getContext('2d').drawImage(image, 0, 0);
    +                return canvas;
    +            });
    +
    +        function newCanvas(domNode) {
    +            var canvas = document.createElement('canvas');
    +            canvas.width = options.width || util.width(domNode);
    +            canvas.height = options.height || util.height(domNode);
    +
    +            if (options.bgcolor) {
    +                var ctx = canvas.getContext('2d');
    +                ctx.fillStyle = options.bgcolor;
    +                ctx.fillRect(0, 0, canvas.width, canvas.height);
    +            }
    +
    +            return canvas;
    +        }
    +    }
    +
    +    function cloneNode(node, filter, root) {
    +        if (!root && filter && !filter(node)) return Promise.resolve();
    +
    +        return Promise.resolve(node)
    +            .then(makeNodeCopy)
    +            .then(function (clone) {
    +                return cloneChildren(node, clone, filter);
    +            })
    +            .then(function (clone) {
    +                return processClone(node, clone);
    +            });
    +
    +        function makeNodeCopy(node) {
    +            if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL());
    +            return node.cloneNode(false);
    +        }
    +
    +        function cloneChildren(original, clone, filter) {
    +            var children = original.childNodes;
    +            if (children.length === 0) return Promise.resolve(clone);
    +
    +            return cloneChildrenInOrder(clone, util.asArray(children), filter)
    +                .then(function () {
    +                    return clone;
    +                });
    +
    +            function cloneChildrenInOrder(parent, children, filter) {
    +                var done = Promise.resolve();
    +                children.forEach(function (child) {
    +                    done = done
    +                        .then(function () {
    +                            return cloneNode(child, filter);
    +                        })
    +                        .then(function (childClone) {
    +                            if (childClone) parent.appendChild(childClone);
    +                        });
    +                });
    +                return done;
    +            }
    +        }
    +
    +        function processClone(original, clone) {
    +            if (!(clone instanceof Element)) return clone;
    +            if(!clone.style) return clone;
    +
    +            return Promise.resolve()
    +                .then(cloneStyle)
    +                .then(clonePseudoElements)
    +                .then(copyUserInput)
    +                .then(fixSvg)
    +                .then(function () {
    +                    return clone;
    +                });
    +
    +            function cloneStyle() {
    +
    +                copyStyle(window.getComputedStyle(original), clone.style);
    +
    +                function copyStyle(source, target) {
    +                    if (source.cssText) target.cssText = source.cssText;
    +                    else copyProperties(source, target);
    +
    +                    function copyProperties(source, target) {
    +                        if(target.setProperty){
    +                            util.asArray(source).forEach(function (name) {
    +                                if(!source) return;
    +                                target.setProperty(
    +                                    name,
    +                                    source.getPropertyValue(name),
    +                                    source.getPropertyPriority(name)
    +                                );
    +                            });
    +                        }
    +                    }
    +                }
    +            }
    +
    +            function clonePseudoElements() {
    +                [':before', ':after'].forEach(function (element) {
    +                    clonePseudoElement(element);
    +                });
    +
    +                function clonePseudoElement(element) {
    +                    var style = window.getComputedStyle(original, element);
    +                    var content = style.getPropertyValue('content');
    +
    +                    if (content === '' || content === 'none') return;
    +
    +                    var className = util.uid();
    +                    clone.className = clone.className + ' ' + className;
    +                    var styleElement = document.createElement('style');
    +                    styleElement.appendChild(formatPseudoElementStyle(className, element, style));
    +                    clone.appendChild(styleElement);
    +
    +                    function formatPseudoElementStyle(className, element, style) {
    +                        var selector = '.' + className + ':' + element;
    +                        var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style);
    +                        return document.createTextNode(selector + '{' + cssText + '}');
    +
    +                        function formatCssText(style) {
    +                            var content = style.getPropertyValue('content');
    +                            return style.cssText + ' content: ' + content + ';';
    +                        }
    +
    +                        function formatCssProperties(style) {
    +
    +                            return util.asArray(style)
    +                                .map(formatProperty)
    +                                .join('; ') + ';';
    +
    +                            function formatProperty(name) {
    +                                return name + ': ' +
    +                                    style.getPropertyValue(name) +
    +                                    (style.getPropertyPriority(name) ? ' !important' : '');
    +                            }
    +                        }
    +                    }
    +                }
    +            }
    +
    +            function copyUserInput() {
    +                if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value;
    +                if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value);
    +            }
    +
    +            function fixSvg() {
    +                if (!(clone instanceof SVGElement)) return;
    +                clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
    +
    +                if (!(clone instanceof SVGRectElement)) return;
    +                ['width', 'height'].forEach(function (attribute) {
    +                    var value = clone.getAttribute(attribute);
    +                    if (!value) return;
    +                     if(clone.style&&clone.style.setProperty){
    +                         clone.style.setProperty(attribute, value);
    +                     }
    +                });
    +            }
    +        }
    +    }
    +
    +    function embedFonts(node) {
    +        return fontFaces.resolveAll()
    +            .then(function (cssText) {
    +                var styleNode = document.createElement('style');
    +                node.appendChild(styleNode);
    +                styleNode.appendChild(document.createTextNode(cssText));
    +                return node;
    +            });
    +    }
    +
    +    function inlineImages(node) {
    +        return images.inlineAll(node)
    +            .then(function () {
    +                return node;
    +            });
    +    }
    +
    +    function makeSvgDataUri(node, width, height) {
    +        return Promise.resolve(node)
    +            .then(function (node) {
    +                node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
    +                return new XMLSerializer().serializeToString(node);
    +            })
    +            .then(util.escapeXhtml)
    +            .then(function (xhtml) {
    +                return '' + xhtml + '';
    +            })
    +            .then(function (foreignObject) {
    +                return '' +
    +                    foreignObject + '';
    +            })
    +            .then(function (svg) {
    +                return 'data:image/svg+xml;charset=utf-8,' + svg;
    +            });
    +    }
    +
    +    function newUtil() {
    +        return {
    +            escape: escape,
    +            parseExtension: parseExtension,
    +            mimeType: mimeType,
    +            dataAsUrl: dataAsUrl,
    +            isDataUrl: isDataUrl,
    +            canvasToBlob: canvasToBlob,
    +            resolveUrl: resolveUrl,
    +            getAndEncode: getAndEncode,
    +            uid: uid(),
    +            delay: delay,
    +            asArray: asArray,
    +            escapeXhtml: escapeXhtml,
    +            makeImage: makeImage,
    +            width: width,
    +            height: height
    +        };
    +
    +        function mimes() {
    +            /*
    +             * Only WOFF and EOT mime types for fonts are 'real'
    +             * see http://www.iana.org/assignments/media-types/media-types.xhtml
    +             */
    +            var WOFF = 'application/font-woff';
    +            var JPEG = 'image/jpeg';
    +
    +            return {
    +                'woff': WOFF,
    +                'woff2': WOFF,
    +                'ttf': 'application/font-truetype',
    +                'eot': 'application/vnd.ms-fontobject',
    +                'png': 'image/png',
    +                'jpg': JPEG,
    +                'jpeg': JPEG,
    +                'gif': 'image/gif',
    +                'tiff': 'image/tiff',
    +                'svg': 'image/svg+xml'
    +            };
    +        }
    +
    +        function parseExtension(url) {
    +            var match = /\.([^\.\/]*?)$/g.exec(url);
    +            if (match) return match[1];
    +            else return '';
    +        }
    +
    +        function mimeType(url) {
    +            var extension = parseExtension(url).toLowerCase();
    +            return mimes()[extension] || '';
    +        }
    +
    +        function isDataUrl(url) {
    +            return url.search(/^(data:)/) !== -1;
    +        }
    +
    +        function toBlob(canvas) {
    +            return new Promise(function (resolve) {
    +                var binaryString = window.atob(canvas.toDataURL().split(',')[1]);
    +                var length = binaryString.length;
    +                var binaryArray = new Uint8Array(length);
    +
    +                for (var i = 0; i < length; i++)
    +                    binaryArray[i] = binaryString.charCodeAt(i);
    +
    +                resolve(new Blob([binaryArray], {
    +                    type: 'image/png'
    +                }));
    +            });
    +        }
    +
    +        function canvasToBlob(canvas) {
    +            if (canvas.toBlob)
    +                return new Promise(function (resolve) {
    +                    canvas.toBlob(resolve);
    +                });
    +
    +            return toBlob(canvas);
    +        }
    +
    +        function resolveUrl(url, baseUrl) {
    +            var doc = document.implementation.createHTMLDocument();
    +            var base = doc.createElement('base');
    +            doc.head.appendChild(base);
    +            var a = doc.createElement('a');
    +            doc.body.appendChild(a);
    +            base.href = baseUrl;
    +            a.href = url;
    +            return a.href;
    +        }
    +
    +        function uid() {
    +            var index = 0;
    +
    +            return function () {
    +                return 'u' + fourRandomChars() + index++;
    +
    +                function fourRandomChars() {
    +                    /* see http://stackoverflow.com/a/6248722/2519373 */
    +                    return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4);
    +                }
    +            };
    +        }
    +
    +        function makeImage(uri) {
    +            return new Promise(function (resolve, reject) {
    +                var image = new Image();
    +                image.onload = function () {
    +                    resolve(image);
    +                };
    +                image.onerror = reject;
    +                image.src = uri;
    +            });
    +        }
    +
    +        function getAndEncode(url) {
    +            var TIMEOUT = 30000;
    +            if(domtoimage.impl.options.cacheBust) {
    +                // Cache bypass so we dont have CORS issues with cached images
    +                // Source: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
    +                url += ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
    +            }
    +
    +            return new Promise(function (resolve) {
    +                var request = new XMLHttpRequest();
    +
    +                request.onreadystatechange = done;
    +                request.ontimeout = timeout;
    +                request.responseType = 'blob';
    +                request.timeout = TIMEOUT;
    +                request.open('GET', url, true);
    +                request.send();
    +
    +                var placeholder;
    +                if(domtoimage.impl.options.imagePlaceholder) {
    +                    var split = domtoimage.impl.options.imagePlaceholder.split(/,/);
    +                    if(split && split[1]) {
    +                        placeholder = split[1];
    +                    }
    +                }
    +
    +                function done() {
    +                    if (request.readyState !== 4) return;
    +
    +                    if (request.status !== 200) {
    +                        if(placeholder) {
    +                            resolve(placeholder);
    +                        } else {
    +                            fail('cannot fetch resource: ' + url + ', status: ' + request.status);
    +                        }
    +
    +                        return;
    +                    }
    +
    +                    var encoder = new FileReader();
    +                    encoder.onloadend = function () {
    +                        var content = encoder.result.split(/,/)[1];
    +                        resolve(content);
    +                    };
    +                    encoder.readAsDataURL(request.response);
    +                }
    +
    +                function timeout() {
    +                    if(placeholder) {
    +                        resolve(placeholder);
    +                    } else {
    +                        fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url);
    +                    }
    +                }
    +
    +                function fail(message) {
    +                    console.error(message);
    +                    resolve('');
    +                }
    +            });
    +        }
    +
    +        function dataAsUrl(content, type) {
    +            return 'data:' + type + ';base64,' + content;
    +        }
    +
    +        function escape(string) {
    +            return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1');
    +        }
    +
    +        function delay(ms) {
    +            return function (arg) {
    +                return new Promise(function (resolve) {
    +                    setTimeout(function () {
    +                        resolve(arg);
    +                    }, ms);
    +                });
    +            };
    +        }
    +
    +        function asArray(arrayLike) {
    +            var array = [];
    +            var length = arrayLike.length;
    +            for (var i = 0; i < length; i++) array.push(arrayLike[i]);
    +            return array;
    +        }
    +
    +        function escapeXhtml(string) {
    +            return string.replace(/#/g, '%23').replace(/\n/g, '%0A');
    +        }
    +
    +        function width(node) {
    +            var leftBorder = px(node, 'border-left-width');
    +            var rightBorder = px(node, 'border-right-width');
    +            return node.scrollWidth + leftBorder + rightBorder;
    +        }
    +
    +        function height(node) {
    +            var topBorder = px(node, 'border-top-width');
    +            var bottomBorder = px(node, 'border-bottom-width');
    +            return node.scrollHeight + topBorder + bottomBorder;
    +        }
    +
    +        function px(node, styleProperty) {
    +            var value = window.getComputedStyle(node).getPropertyValue(styleProperty);
    +            return parseFloat(value.replace('px', ''));
    +        }
    +    }
    +
    +    function newInliner() {
    +        var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g;
    +
    +        return {
    +            inlineAll: inlineAll,
    +            shouldProcess: shouldProcess,
    +            impl: {
    +                readUrls: readUrls,
    +                inline: inline
    +            }
    +        };
    +
    +        function shouldProcess(string) {
    +            return string.search(URL_REGEX) !== -1;
    +        }
    +
    +        function readUrls(string) {
    +            var result = [];
    +            var match;
    +            while ((match = URL_REGEX.exec(string)) !== null) {
    +                result.push(match[1]);
    +            }
    +            return result.filter(function (url) {
    +                return !util.isDataUrl(url);
    +            });
    +        }
    +
    +        function inline(string, url, baseUrl, get) {
    +            return Promise.resolve(url)
    +                .then(function (url) {
    +                    return baseUrl ? util.resolveUrl(url, baseUrl) : url;
    +                })
    +                .then(get || util.getAndEncode)
    +                .then(function (data) {
    +                    return util.dataAsUrl(data, util.mimeType(url));
    +                })
    +                .then(function (dataUrl) {
    +                    return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3');
    +                });
    +
    +            function urlAsRegex(url) {
    +                return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g');
    +            }
    +        }
    +
    +        function inlineAll(string, baseUrl, get) {
    +            if (nothingToInline()) return Promise.resolve(string);
    +
    +            return Promise.resolve(string)
    +                .then(readUrls)
    +                .then(function (urls) {
    +                    var done = Promise.resolve(string);
    +                    urls.forEach(function (url) {
    +                        done = done.then(function (string) {
    +                            return inline(string, url, baseUrl, get);
    +                        });
    +                    });
    +                    return done;
    +                });
    +
    +            function nothingToInline() {
    +                return !shouldProcess(string);
    +            }
    +        }
    +    }
    +
    +    function newFontFaces() {
    +        return {
    +            resolveAll: resolveAll,
    +            impl: {
    +                readAll: readAll
    +            }
    +        };
    +
    +        function resolveAll() {
    +            return readAll()
    +                .then(function (webFonts) {
    +                    return Promise.all(
    +                        webFonts.map(function (webFont) {
    +                            return webFont.resolve();
    +                        })
    +                    );
    +                })
    +                .then(function (cssStrings) {
    +                    return cssStrings.join('\n');
    +                });
    +        }
    +
    +        function readAll() {
    +            return Promise.resolve(util.asArray(document.styleSheets))
    +                .then(getCssRules)
    +                .then(selectWebFontRules)
    +                .then(function (rules) {
    +                    return rules.map(newWebFont);
    +                });
    +
    +            function selectWebFontRules(cssRules) {
    +                return cssRules
    +                    .filter(function (rule) {
    +                        return rule.type === CSSRule.FONT_FACE_RULE;
    +                    })
    +                    .filter(function (rule) {
    +                        return inliner.shouldProcess(rule.style.getPropertyValue('src'));
    +                    });
    +            }
    +
    +            function getCssRules(styleSheets) {
    +                var cssRules = [];
    +                styleSheets.forEach(function (sheet) {
    +                    try {
    +                        util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules));
    +                    } catch (e) {
    +                        console.log('Error while reading CSS rules from ' + sheet.href, e.toString());
    +                    }
    +                });
    +                return cssRules;
    +            }
    +
    +            function newWebFont(webFontRule) {
    +                return {
    +                    resolve: function resolve() {
    +                        var baseUrl = (webFontRule.parentStyleSheet || {}).href;
    +                        return inliner.inlineAll(webFontRule.cssText, baseUrl);
    +                    },
    +                    src: function () {
    +                        return webFontRule.style.getPropertyValue('src');
    +                    }
    +                };
    +            }
    +        }
    +    }
    +
    +    function newImages() {
    +        return {
    +            inlineAll: inlineAll,
    +            impl: {
    +                newImage: newImage
    +            }
    +        };
    +
    +        function newImage(element) {
    +            return {
    +                inline: inline
    +            };
    +
    +            function inline(get) {
    +                if (util.isDataUrl(element.src)) return Promise.resolve();
    +
    +                return Promise.resolve(element.src)
    +                    .then(get || util.getAndEncode)
    +                    .then(function (data) {
    +                        return util.dataAsUrl(data, util.mimeType(element.src));
    +                    })
    +                    .then(function (dataUrl) {
    +                        return new Promise(function (resolve, reject) {
    +                            element.onload = resolve;
    +                            element.onerror = reject;
    +                            element.src = dataUrl;
    +                        });
    +                    });
    +            }
    +        }
    +
    +        function inlineAll(node) {
    +            if (!(node instanceof Element)) return Promise.resolve(node);
    +
    +            return inlineBackground(node)
    +                .then(function () {
    +                    if (node instanceof HTMLImageElement)
    +                        return newImage(node).inline();
    +                    else
    +                        return Promise.all(
    +                            util.asArray(node.childNodes).map(function (child) {
    +                                return inlineAll(child);
    +                            })
    +                        );
    +                });
    +
    +            function inlineBackground(node) {
    +                if(!node.style){
    +                    return Promise.resolve(node);
    +                }
    +                var background = node.style.getPropertyValue('background');
    +
    +                if (!background) return Promise.resolve(node);
    +
    +                return inliner.inlineAll(background)
    +                    .then(function (inlined) {
    +                        if(node.style&&node.style.setProperty){
    +                            node.style.setProperty(
    +                                'background',
    +                                inlined,
    +                                node.style.getPropertyPriority('background')
    +                            );
    +                        }
    +                    })
    +                    .then(function () {
    +                        return node;
    +                    });
    +            }
    +        }
    +    }
    +})();
    +});
    +
    +function uuid() {
    +    function S4() {
    +        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    +    }
    +    return (S4() + S4() + '-' + S4() + '-' + S4());
    +}
    +const transformer = new browser.Transformer();
    +const mindmapViewType = "mindmapView";
    +const mindmapIcon = "blocks";
    +class MindMapView extends obsidian.TextFileView {
    +    getViewType() {
    +        return mindmapViewType;
    +    }
    +    getIcon() {
    +        return mindmapIcon;
    +    }
    +    getDisplayText() {
    +        var _a;
    +        return ((_a = this.file) === null || _a === void 0 ? void 0 : _a.basename) || "mindmap";
    +    }
    +    setColors() {
    +        var colors = [];
    +        try {
    +            if (this.plugin.settings.strokeArray) {
    +                colors = this.plugin.settings.strokeArray.split(',');
    +            }
    +        }
    +        catch (err) {
    +            console.log(err, 'stroke array is error');
    +        }
    +        this.colors = this.colors.concat(colors);
    +        for (var i = 0; i < 50; i++) {
    +            this.colors.push(randomColor());
    +        }
    +    }
    +    exportToSvg() {
    +        if (!this.mindmap) {
    +            return;
    +        }
    +        // this.mindmap.contentEL.style.visibility='hidden';
    +        var nodes = [];
    +        this.mindmap.traverseDF((n) => {
    +            if (n.isShow()) {
    +                nodes.push(n);
    +            }
    +        });
    +        var oldScrollLeft = this.mindmap.containerEL.scrollLeft;
    +        var oldScrollTop = this.mindmap.containerEL.scrollTop;
    +        var box = this.mindmap.getBoundingRect(nodes);
    +        var rootBox = this.mindmap.root.getPosition();
    +        var disX = 0, disY = 0;
    +        if (box.x > 60) {
    +            disX = box.x - 60;
    +        }
    +        if (box.y > 60) {
    +            disY = box.y - 60;
    +        }
    +        this.mindmap.root.setPosition(rootBox.x - disX, rootBox.y - disY);
    +        this.mindmap.refresh();
    +        var w = box.width + 120;
    +        var h = box.height + 120;
    +        this.mindmap.contentEL.style.width = w + 'px';
    +        this.mindmap.contentEL.style.height = h + 'px';
    +        setTimeout(() => {
    +            domtoimage.toPng(this.mindmap.contentEL).then(dataUrl => {
    +                var img = new Image();
    +                img.src = dataUrl;
    +                var str = img.outerHTML;
    +                var p = this.mindmap.path.substr(0, this.mindmap.path.length - 2);
    +                try {
    +                    new obsidian.Notice(p + 'html');
    +                    this.app.vault.adapter.write(p + 'html', str);
    +                    this.restoreMindmap(rootBox, oldScrollLeft, oldScrollTop);
    +                }
    +                catch (err) {
    +                    this.restoreMindmap(rootBox, oldScrollLeft, oldScrollTop);
    +                    new obsidian.Notice(err);
    +                }
    +            }).catch(err => {
    +                this.restoreMindmap(rootBox, oldScrollLeft, oldScrollTop);
    +                new obsidian.Notice(err);
    +            });
    +        }, 200);
    +    }
    +    restoreMindmap(rootBox, left, top) {
    +        if (this.mindmap) {
    +            var size = this.plugin.settings.canvasSize;
    +            this.mindmap.contentEL.style.width = size + 'px';
    +            this.mindmap.contentEL.style.height = size + 'px';
    +            this.mindmap.containerEL.scrollTop = top;
    +            this.mindmap.containerEL.scrollLeft = left;
    +            this.mindmap.root.setPosition(rootBox.x, rootBox.y);
    +            this.mindmap.refresh();
    +            //   this.mindmap.contentEL.style.visibility='visible';
    +        }
    +    }
    +    mindMapChange() {
    +        if (this.mindmap) {
    +            var md = this.mindmap.getMarkdown();
    +            //  var matchArray: string[] = []
    +            // var collapsedIds: string[] = []
    +            // const idRegexMultiline = /.+ \^([a-z0-9\-]+)$/gim
    +            // while ((matchArray = idRegexMultiline.exec(md)) != null) {
    +            //   collapsedIds = [...collapsedIds, ...matchArray.slice(1, 2)];
    +            // }
    +            // this.fileCache.frontmatter.collapsedIds='';
    +            // if (collapsedIds.length > 0) {
    +            //   this.fileCache.frontmatter.collapsedIds = collapsedIds;
    +            // }
    +            //var frontMatter = this.getFrontMatter();
    +            this.data = this.yamlString + md;
    +            // console.log(this.mindmap.path);
    +            // this.app.vault.adapter.write(this.mindmap.path, this.data);
    +            try {
    +                this.requestSave();
    +                //new Notice(`${t("Save success")}`);
    +            }
    +            catch (err) {
    +                console.log(err);
    +                new obsidian.Notice(`${t("Save fail")}`);
    +            }
    +        }
    +    }
    +    getFrontMatter() {
    +        var frontMatter = '---\n\n';
    +        //  var v: any = '';
    +        if (this.fileCache.frontmatter) {
    +            // for (var k in this.fileCache.frontmatter) {
    +            //   if (k != 'position') {
    +            //     if (Object.prototype.toString.call(this.fileCache.frontmatter[k]) == '[object Array]' || Object.prototype.toString.call(this.fileCache.frontmatter[k]) == '[object Object]') {
    +            //       v = JSON.stringify(this.fileCache.frontmatter[k]);
    +            //     } else if (Object.prototype.toString.call(this.fileCache.frontmatter[k]) == '[object Number]' || Object.prototype.toString.call(this.fileCache.frontmatter[k]) == "[object String]") {
    +            //       v = this.fileCache.frontmatter[k];
    +            //     }
    +            //     if (v) {
    +            //       frontMatter += `${k}: ${v}\n`;
    +            //     }
    +            //   }
    +            // }
    +            var position = this.fileCache.frontmatterPosition;
    +            var end = position['end'].offset;
    +            frontMatter = this.data.substr(0, end);
    +        }
    +        frontMatter += '\n\n';
    +        //frontMatter += `\n---\n\n`;
    +        return frontMatter;
    +    }
    +    constructor(leaf, plugin) {
    +        super(leaf);
    +        this.id = this.leaf.id;
    +        this.colors = [];
    +        this.timeOut = null;
    +        this.firstInit = true;
    +        this.yamlString = '';
    +        this.plugin = plugin;
    +        this.setColors();
    +        this.fileCache = {
    +            'frontmatter': {
    +                'mindmap-plugin': 'basic'
    +            }
    +        };
    +    }
    +    onClose() {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            // Remove draggables from render, as the DOM has already detached
    +            //this.plugin.removeView(this);
    +            if (this.mindmap) {
    +                this.mindmap.clear();
    +                this.contentEl.innerHTML = '';
    +                this.mindmap = null;
    +            }
    +        });
    +    }
    +    clear() {
    +    }
    +    getViewData() {
    +        return this.data;
    +    }
    +    setViewData(data) {
    +        if (this.mindmap) {
    +            this.mindmap.clear();
    +            this.contentEl.innerHTML = '';
    +        }
    +        this.data = data;
    +        var mdText = this.getMdText(this.data);
    +        var mindData = this.mdToData(mdText);
    +        mindData.isRoot = true;
    +        // const frontmatterContentRegExResult = /^---$(.+?)^---$.+?/mis.exec(data)
    +        // if (frontmatterContentRegExResult != null && frontmatterContentRegExResult[1]) {
    +        //   frontmatterContentRegExResult[1].split('\n').forEach((frontmatterLine) => {
    +        //     const keyValue = frontmatterLine.split(': ')
    +        //     if (keyValue.length === 2) {
    +        //       const value = /^[{\[].+[}\]]$/.test(keyValue[1]) ? JSON.parse(keyValue[1]) : keyValue[1]
    +        //       this.fileCache.frontmatter[keyValue[0]] = value
    +        //     }
    +        //   });
    +        // }
    +        this.mindmap = new MindMap(mindData, this.contentEl, this.plugin.settings);
    +        this.mindmap.colors = this.colors;
    +        if (this.firstInit) {
    +            setTimeout(() => {
    +                var leaf = this.leaf;
    +                if (leaf) {
    +                    var view = leaf.view;
    +                    this.mindmap.path = view === null || view === void 0 ? void 0 : view.file.path;
    +                    if (view.file) {
    +                        this.fileCache = this.app.metadataCache.getFileCache(view.file);
    +                        this.yamlString = this.getFrontMatter();
    +                    }
    +                }
    +                this.mindmap.init();
    +                this.mindmap.refresh();
    +                this.mindmap.view = this;
    +                this.firstInit = false;
    +            }, 100);
    +        }
    +        else {
    +            var view = this.leaf.view;
    +            this.fileCache = this.app.metadataCache.getFileCache(view.file);
    +            this.yamlString = this.getFrontMatter();
    +            this.mindmap.path = view === null || view === void 0 ? void 0 : view.file.path;
    +            this.mindmap.init();
    +            this.mindmap.refresh();
    +            this.mindmap.view = this;
    +        }
    +    }
    +    onunload() {
    +        this.app.workspace.offref("quick-preview");
    +        this.app.workspace.offref("resize");
    +        if (this.mindmap) {
    +            this.mindmap.clear();
    +            this.contentEl.innerHTML = '';
    +            this.mindmap = null;
    +        }
    +        this.plugin.setMarkdownView(this.leaf);
    +    }
    +    onload() {
    +        super.onload();
    +        this.registerEvent(this.app.workspace.on("quick-preview", () => this.onQuickPreview, this));
    +        this.registerEvent(this.app.workspace.on('resize', () => this.updateMindMap(), this));
    +    }
    +    onQuickPreview(file, data) {
    +        if (file === this.file && data !== this.data) {
    +            this.setViewData(data);
    +            this.fileCache = this.app.metadataCache.getFileCache(file);
    +        }
    +    }
    +    updateMindMap() {
    +        if (this.mindmap) {
    +            if (obsidian.Platform.isDesktopApp) {
    +                this.mindmap.center();
    +            }
    +        }
    +    }
    +    onFileMetadataChange(file) {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            var path = file.path;
    +            let md = yield this.app.vault.adapter.read(path);
    +            this.onQuickPreview(file, md);
    +        });
    +    }
    +    getMdText(str) {
    +        var md = str.trim().replace(FRONT_MATTER_REGEX, '');
    +        return md.trim();
    +    }
    +    mdToData(str) {
    +        var _a;
    +        function transformData(mapData) {
    +            var flag = true;
    +            if (mapData.t == 'blockquote') {
    +                mapData = mapData.c[0];
    +                flag = false;
    +                mapData.v = '> ' + mapData.v;
    +            }
    +            const regexResult = /^.+ \^([a-z0-9\-]+)$/gim.exec(mapData.v);
    +            const id = regexResult != null ? regexResult[1] : null;
    +            // console.log(id);
    +            var map = {
    +                id: id || uuid(),
    +                text: id ? mapData.v.replace(` ^${id}`, '') : mapData.v,
    +                children: [],
    +                expanded: id ? false : true
    +            };
    +            if (flag && mapData.c && mapData.c.length) {
    +                mapData.c.forEach((data) => {
    +                    map.children.push(transformData(data));
    +                });
    +            }
    +            return map;
    +        }
    +        if (str) {
    +            const { root } = transformer.transform(str);
    +            const data = transformData(root);
    +            return data;
    +        }
    +        else {
    +            return {
    +                id: uuid(),
    +                text: ((_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.basename) || `${t('Untitled mindmap')}`
    +            };
    +        }
    +    }
    +    onMoreOptionsMenu(menu) {
    +        // Add a menu item to force the board to markdown view
    +        menu
    +            .addItem((item) => {
    +            item
    +                .setTitle(`${t("Open as markdown")}`)
    +                .setIcon("document")
    +                .onClick(() => {
    +                this.plugin.mindmapFileModes[this.id || this.file.path] = "markdown";
    +                this.plugin.setMarkdownView(this.leaf);
    +            });
    +        });
    +        // .addItem((item)=>{
    +        //    item
    +        //    .setTitle(`${t("Export to opml")}`)
    +        //    .setIcon('image-file')
    +        //    .onClick(()=>{
    +        //       const targetFolder = this.plugin.app.fileManager.getNewFileParent(
    +        //        this.plugin.app.workspace.getActiveFile()?.path || ""
    +        //       );
    +        //       if(targetFolder){
    +        //         console.log(targetFolder,this.plugin.app.fileManager);
    +        //       }
    +        //    })
    +        // })
    +        super.onMoreOptionsMenu(menu);
    +    }
    +}
    +
    +class MindMapSettingsTab extends obsidian.PluginSettingTab {
    +    constructor(app, plugin) {
    +        super(app, plugin);
    +        this.plugin = plugin;
    +    }
    +    display() {
    +        const { containerEl } = this;
    +        containerEl.empty();
    +        new obsidian.Setting(containerEl)
    +            .setName(`${t('Canvas size')}`)
    +            .setDesc(`${t('Canvas size desc')}`)
    +            .addDropdown(dropDown => dropDown
    +            .addOption('4000', '4000')
    +            .addOption('6000', '6000')
    +            .addOption('8000', '8000')
    +            .addOption('10000', '10000')
    +            .addOption('12000', '12000')
    +            .addOption('16000', '16000')
    +            .addOption('20000', '20000')
    +            .addOption('30000', '30000')
    +            .addOption('36000', '36000')
    +            .setValue(this.plugin.settings.canvasSize.toString() || '8000')
    +            .onChange((value) => {
    +            var _v = Number.parseInt(value);
    +            this.plugin.settings.canvasSize = _v;
    +            this.plugin.saveData(this.plugin.settings);
    +            const mindmapLeaves = this.app.workspace.getLeavesOfType(mindmapViewType);
    +            mindmapLeaves.forEach((leaf) => {
    +                var v = leaf.view;
    +                v.mindmap.setting.canvasSize = _v;
    +                v.mindmap.setAppSetting();
    +                var box = v.mindmap.root.getBox();
    +                v.mindmap.root.setPosition(_v / 2 - box.width / 2, _v / 2 - box.height / 2);
    +                v.mindmap.refresh();
    +                v.mindmap.center();
    +            });
    +        }));
    +        new obsidian.Setting(containerEl)
    +            .setName(`${t('Canvas background')}`)
    +            .setDesc(`${t('Canvas background desc')}`)
    +            .addText(text => text
    +            .setValue(this.plugin.settings.background || 'transparent')
    +            .setPlaceholder('Example: black|white|#ccc')
    +            .onChange((value) => {
    +            this.plugin.settings.background = value;
    +            this.plugin.saveData(this.plugin.settings);
    +            const mindmapLeaves = this.app.workspace.getLeavesOfType(mindmapViewType);
    +            mindmapLeaves.forEach((leaf) => {
    +                var v = leaf.view;
    +                v.mindmap.setting.background = this.plugin.settings.background;
    +                v.mindmap.setAppSetting();
    +            });
    +        }));
    +        new obsidian.Setting(containerEl)
    +            .setName(`${t('Max level of node to markdown head')}`)
    +            .setDesc(`${t('Max level of node to markdown head desc')}`)
    +            .addDropdown(dropDown => dropDown
    +            .addOption('0', '0')
    +            .addOption('1', '1')
    +            .addOption('2', '2')
    +            .addOption('3', '3')
    +            .addOption('4', '4')
    +            .addOption('5', '5')
    +            .addOption('6', '6')
    +            .setValue(this.plugin.settings.headLevel.toString() || '2')
    +            .onChange((value) => {
    +            this.plugin.settings.headLevel = Number.parseInt(value);
    +            this.plugin.saveData(this.plugin.settings);
    +            const mindmapLeaves = this.app.workspace.getLeavesOfType(mindmapViewType);
    +            mindmapLeaves.forEach((leaf) => {
    +                var v = leaf.view;
    +                v.mindmap.setting.headLevel = this.plugin.settings.headLevel;
    +            });
    +        }));
    +        new obsidian.Setting(containerEl)
    +            .setName(`${t('Font size')}`)
    +            .setDesc(`${t('Font size desc')}`)
    +            .addText(text => {
    +            var _a;
    +            return text
    +                .setValue(((_a = this.plugin.settings.fontSize) === null || _a === void 0 ? void 0 : _a.toString()) || '16')
    +                .setPlaceholder('Example: 16')
    +                .onChange((value) => {
    +                this.plugin.settings.fontSize = Number.parseInt(value);
    +                this.plugin.saveData(this.plugin.settings);
    +                const mindmapLeaves = this.app.workspace.getLeavesOfType(mindmapViewType);
    +                mindmapLeaves.forEach((leaf) => {
    +                    var v = leaf.view;
    +                    v.mindmap.setting.fontSize = this.plugin.settings.fontSize;
    +                    v.mindmap.setAppSetting();
    +                    v.mindmap.traverseBF((n) => {
    +                        n.boundingRect = null;
    +                        n.refreshBox();
    +                    });
    +                    v.mindmap.refresh();
    +                });
    +            });
    +        });
    +        new obsidian.Setting(containerEl)
    +            .setName(`${t('Mind map layout direct')}`)
    +            .setDesc(`${t('Mind map layout direct desc')}`)
    +            .addDropdown(dropDown => dropDown
    +            .addOption('mind map', t('Centered'))
    +            .addOption('right', t('Right'))
    +            .addOption('left', t('Left'))
    +            .addOption('clockwise', t('Clockwise'))
    +            .setValue(this.plugin.settings.layoutDirect.toString() || 'mind map')
    +            .onChange((value) => {
    +            this.plugin.settings.layoutDirect = value;
    +            this.plugin.saveData(this.plugin.settings);
    +            const mindmapLeaves = this.app.workspace.getLeavesOfType(mindmapViewType);
    +            mindmapLeaves.forEach((leaf) => {
    +                var v = leaf.view;
    +                v.mindmap.setting.layoutDirect = this.plugin.settings.layoutDirect;
    +                v.mindmap.refresh();
    +            });
    +        }));
    +        new obsidian.Setting(containerEl)
    +            .setName(`${t('Stroke Array')}`)
    +            .setDesc(`${t('Stroke Array Desc')}`)
    +            .addText(text => {
    +            var _a;
    +            return text
    +                .setValue(((_a = this.plugin.settings.strokeArray) === null || _a === void 0 ? void 0 : _a.toString()) || '')
    +                .setPlaceholder('Example: red,orange,blue ...')
    +                .onChange((value) => {
    +                this.plugin.settings.strokeArray = value;
    +                this.plugin.saveData(this.plugin.settings);
    +                const mindmapLeaves = this.app.workspace.getLeavesOfType(mindmapViewType);
    +                mindmapLeaves.forEach((leaf) => {
    +                    var v = leaf.view;
    +                    v.mindmap.setting.strokeArray = this.plugin.settings.strokeArray.split(',');
    +                    if (v.mindmap.mmLayout) {
    +                        v.mindmap.mmLayout.colors = v.mindmap.setting.strokeArray;
    +                    }
    +                    v.mindmap.traverseBF((n) => {
    +                        n.boundingRect = null;
    +                        n.refreshBox();
    +                    });
    +                    v.mindmap.refresh();
    +                });
    +            });
    +        });
    +    }
    +}
    +
    +class MindMapPlugin extends obsidian.Plugin {
    +    constructor() {
    +        super(...arguments);
    +        this.mindmapFileModes = {};
    +        this._loaded = false;
    +        this.timeOut = null;
    +    }
    +    onload() {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            yield this.loadSettings();
    +            this.addCommand({
    +                id: 'Create New MindMap',
    +                name: `${t('Create new mindmap')}`,
    +                checkCallback: (checking) => {
    +                    var _a;
    +                    let leaf = this.app.workspace.activeLeaf;
    +                    if (leaf) {
    +                        if (!checking) {
    +                            const targetFolder = this.app.fileManager.getNewFileParent(((_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path) || "");
    +                            if (targetFolder) {
    +                                this.newMindMap(targetFolder);
    +                            }
    +                        }
    +                        return true;
    +                    }
    +                    return false;
    +                }
    +            });
    +            this.addCommand({
    +                id: 'Toggle to markdown or mindmap',
    +                name: `${t('Toggle markdown/mindmap')}`,
    +                mobileOnly: false,
    +                callback: () => {
    +                    const mindmapView = this.app.workspace.getActiveViewOfType(MindMapView);
    +                    const markdownView = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
    +                    if (mindmapView != null) {
    +                        this.mindmapFileModes[mindmapView.leaf.id || mindmapView.file.path] = 'markdown';
    +                        this.setMarkdownView(mindmapView.leaf);
    +                    }
    +                    else if (markdownView != null) {
    +                        this.mindmapFileModes[markdownView.leaf.id || markdownView.file.path] = mindmapViewType;
    +                        this.setMarkdownView(markdownView.leaf);
    +                    }
    +                }
    +            });
    +            this.addCommand({
    +                id: 'Copy Node',
    +                name: `${t('Copy node')}`,
    +                callback: () => {
    +                    const mindmapView = this.app.workspace.getActiveViewOfType(MindMapView);
    +                    if (mindmapView) {
    +                        var mindmap = mindmapView.mindmap;
    +                        navigator.clipboard.writeText('');
    +                        var node = mindmap.selectNode;
    +                        if (node) {
    +                            var text = mindmap.copyNode(node);
    +                            navigator.clipboard.writeText(text);
    +                        }
    +                    }
    +                }
    +            });
    +            this.addCommand({
    +                id: 'Paste Node',
    +                name: `${t('Paste node')}`,
    +                callback: () => {
    +                    const mindmapView = this.app.workspace.getActiveViewOfType(MindMapView);
    +                    if (mindmapView) {
    +                        var mindmap = mindmapView.mindmap;
    +                        navigator.clipboard.readText().then(text => {
    +                            mindmap.pasteNode(text);
    +                        });
    +                    }
    +                }
    +            });
    +            this.addCommand({
    +                id: 'Export to html',
    +                name: `${t('Export to html')}`,
    +                callback: () => {
    +                    const mindmapView = this.app.workspace.getActiveViewOfType(MindMapView);
    +                    if (mindmapView) {
    +                        mindmapView.exportToSvg();
    +                    }
    +                }
    +            });
    +            this.registerView(mindmapViewType, (leaf) => new MindMapView(leaf, this));
    +            this.registerEvents();
    +            this.registerMonkeyAround();
    +            this.addSettingTab(new MindMapSettingsTab(this.app, this));
    +        });
    +    }
    +    onunload() {
    +        this.app.workspace.detachLeavesOfType(mindmapViewType);
    +        //this.app.workspace.unregisterHoverLinkSource(frontMatterKey);
    +    }
    +    newMindMap(folder) {
    +        var _a;
    +        return __awaiter(this, void 0, void 0, function* () {
    +            const targetFolder = folder
    +                ? folder
    +                : this.app.fileManager.getNewFileParent(((_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path) || "");
    +            try {
    +                // @ts-ignore
    +                const mindmap = yield this.app.fileManager.createNewMarkdownFile(targetFolder, `${t('Untitled mindmap')}`);
    +                yield this.app.vault.modify(mindmap, basicFrontmatter);
    +                setTimeout(() => __awaiter(this, void 0, void 0, function* () {
    +                    yield this.app.workspace.getLeaf().setViewState({
    +                        type: mindmapViewType,
    +                        state: { file: mindmap.path },
    +                    });
    +                }), 100);
    +            }
    +            catch (e) {
    +                console.error("Error creating mindmap board:", e);
    +            }
    +        });
    +    }
    +    loadSettings() {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            this.settings = Object.assign({
    +                canvasSize: 8000,
    +                headLevel: 2,
    +                fontSize: 16,
    +                background: 'transparent',
    +                layout: 'mindmap',
    +                layoutDirect: 'mindmap'
    +            }, yield this.loadData());
    +        });
    +    }
    +    saveSettings() {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            yield this.saveData(this.settings);
    +        });
    +    }
    +    setMarkdownView(leaf) {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            yield leaf.setViewState({
    +                type: "markdown",
    +                state: leaf.view.getState(),
    +                popstate: true,
    +            }, { focus: true });
    +        });
    +    }
    +    setMindMapView(leaf) {
    +        return __awaiter(this, void 0, void 0, function* () {
    +            yield leaf.setViewState({
    +                type: mindmapViewType,
    +                state: leaf.view.getState(),
    +                popstate: true,
    +            });
    +        });
    +    }
    +    registerEvents() {
    +        this.registerEvent(this.app.workspace.on("file-menu", (menu, file, source, leaf) => {
    +            // Add a menu item to the folder context menu to create a board
    +            if (file instanceof obsidian.TFolder) {
    +                menu.addItem((item) => {
    +                    item
    +                        .setTitle(`${t('New mindmap board')}`)
    +                        .setIcon('document')
    +                        .onClick(() => this.newMindMap(file));
    +                });
    +            }
    +            //add markdown view menu  open as mind map view
    +            if (leaf && this.mindmapFileModes[leaf.id || file.path] == 'markdown') {
    +                const cache = this.app.metadataCache.getFileCache(file);
    +                if ((cache === null || cache === void 0 ? void 0 : cache.frontmatter) && cache.frontmatter[frontMatterKey]) {
    +                    menu.addItem((item) => {
    +                        item
    +                            .setTitle(`${t('Open as mindmap board')}`)
    +                            .setIcon("document")
    +                            .onClick(() => {
    +                            this.mindmapFileModes[leaf.id || file.path] = mindmapViewType;
    +                            this.setMindMapView(leaf);
    +                        });
    +                    }).addSeparator();
    +                }
    +            }
    +        }));
    +        this.registerEvent(this.app.metadataCache.on("changed", (file) => {
    +            this.app.workspace.getLeavesOfType(mindmapViewType).forEach((leaf) => {
    +                const view = leaf.view;
    +                view.onFileMetadataChange(file);
    +            });
    +        }));
    +        // @ts-ignore
    +        // this.app.workspace.registerHoverLinkSource(frontMatterKey, {
    +        //   display: mindmapViewType,
    +        //   defaultMod: true,
    +        // });
    +    }
    +    registerMonkeyAround() {
    +        const self = this;
    +        this.register(around(obsidian.WorkspaceLeaf.prototype, {
    +            // Kanbans can be viewed as markdown or kanban, and we keep track of the mode
    +            // while the file is open. When the file closes, we no longer need to keep track of it.
    +            detach(next) {
    +                return function () {
    +                    var _a;
    +                    const state = (_a = this.view) === null || _a === void 0 ? void 0 : _a.getState();
    +                    if ((state === null || state === void 0 ? void 0 : state.file) && self.mindmapFileModes[this.id || state.file]) {
    +                        delete self.mindmapFileModes[this.id || state.file];
    +                    }
    +                    return next.apply(this);
    +                };
    +            },
    +            setViewState(next) {
    +                return function (state, ...rest) {
    +                    var _a;
    +                    // new Notice( state.type);
    +                    if (self._loaded &&
    +                        state.type === "markdown" &&
    +                        ((_a = state.state) === null || _a === void 0 ? void 0 : _a.file) &&
    +                        // And the current mode of the file is not set to markdown
    +                        self.mindmapFileModes[this.id || state.state.file] !== "markdown") {
    +                        // Then check for the kanban frontMatterKey
    +                        const cache = self.app.metadataCache.getCache(state.state.file);
    +                        //   new Notice(cache.frontmatter[frontMatterKey]);
    +                        if ((cache === null || cache === void 0 ? void 0 : cache.frontmatter) && cache.frontmatter[frontMatterKey]) {
    +                            // If we have it, force the view type to kanban
    +                            const newState = Object.assign(Object.assign({}, state), { type: mindmapViewType });
    +                            self.mindmapFileModes[state.state.file] = mindmapViewType;
    +                            return next.apply(this, [newState, ...rest]);
    +                        }
    +                    }
    +                    return next.apply(this, [state, ...rest]);
    +                };
    +            },
    +        }));
    +        // this.register(
    +        //   around(MarkdownView.prototype, {
    +        //     onMoreOptionsMenu(next) {
    +        //       return function (menu: Menu) {
    +        //         const file = this.file;
    +        //         const cache = file
    +        //           ? self.app.metadataCache.getFileCache(file)
    +        //           : null;
    +        //         if (
    +        //           !file ||
    +        //           !cache?.frontmatter ||
    +        //           !cache.frontmatter[frontMatterKey]
    +        //         ) {
    +        //           return next.call(this, menu);
    +        //         }
    +        //         menu
    +        //           .addItem((item) => {
    +        //             item
    +        //               .setTitle(`${t('Open as mindmap board')}`)
    +        //               .setIcon("document")
    +        //               .onClick(() => {
    +        //                 self.mindmapFileModes[this.leaf.id || file.path] =
    +        //                   mindmapViewType;
    +        //                 self.setMindMapView(this.leaf);
    +        //               });
    +        //           })
    +        //           .addSeparator();
    +        //         next.call(this, menu);
    +        //       };
    +        //     },
    +        //   })
    +        // );
    +    }
    +}
    +
    +module.exports = MindMapPlugin;
    diff --git a/.obsidian/plugins/obsidian-enhancing-mindmap/manifest.json b/.obsidian/plugins/obsidian-enhancing-mindmap/manifest.json
    new file mode 100644
    index 000000000..380a209be
    --- /dev/null
    +++ b/.obsidian/plugins/obsidian-enhancing-mindmap/manifest.json
    @@ -0,0 +1,10 @@
    +{
    +	"id": "obsidian-enhancing-mindmap",
    +	"name": "Enhancing Mindmap",
    +	"version": "0.2.5",
    +	"minAppVersion": "0.9.12",
    +	"description": "This is a enhancing mindmap plugin for Obsidian. You can edit mindmap on markdown.",
    +	"author": "Mark",
    +	"authorUrl": "https://github.com/MarkMindCkm/obsidian-enhancing-mindmap",
    +	"isDesktopOnly": false
    +}
    diff --git a/.obsidian/plugins/obsidian-enhancing-mindmap/styles.css b/.obsidian/plugins/obsidian-enhancing-mindmap/styles.css
    new file mode 100644
    index 000000000..ad9973a03
    --- /dev/null
    +++ b/.obsidian/plugins/obsidian-enhancing-mindmap/styles.css
    @@ -0,0 +1,175 @@
    +.mm-mindmap {
    +  color: #666;
    +  font-size: 16px;
    +  width: 8000px;
    +  height: 8000px;
    +}
    +
    +.theme-dark .mm-node {
    +  color: #f5f5f5;
    +}
    +
    +.theme-dark .mm-node.mm-root {
    +  color: #333;
    +}
    +
    +.theme-light .mm-node.mm-root .mm-node-content {
    +  color: #fff;
    +  background-color: rgb(0, 170, 255);
    +}
    +
    +.mm-node {
    +  position: absolute;
    +  cursor: pointer;
    +  box-sizing: border-box;
    +}
    +.mm-node .mm-node-content {
    +  padding: 2px 4px;
    +  max-width: 800px;
    +  word-break: break-word;
    +}
    +
    +.mm-node-content > p,
    +.mm-node-content > h1,
    +.mm-node-content > h2,
    +.mm-node-content > h3,
    +.mm-node-content > h4,
    +.mm-node-content > h5,
    +.mm-node-content > h6 {
    +  padding: 0;
    +  margin: 0;
    +}
    +
    +.mm-node.mm-root .mm-node-content {
    +  font-size: 1.6em;
    +  padding: 14px 20px;
    +  border-radius: 0.25rem;
    +  background: white;
    +}
    +
    +.mm-node.mm-node-second .mm-node-content {
    +  padding: 8px 10px;
    +  font-size: 1.2em;
    +}
    +
    +.mm-node.mm-node-select {
    +  border: 2px solid var(--interactive-accent);
    +  border-radius: 0.25rem;
    +}
    +
    +.mm-node-bar {
    +  position: absolute;
    +  height: 12px;
    +  width: 12px;
    +  border-radius: 50%;
    +  padding: 0 3px;
    +  bottom: -8px;
    +  box-sizing: border-box;
    +}
    +
    +.mm-node-bar:hover {
    +  transform: scale(1.2);
    +}
    +
    +.mm-node .mm-node-bar {}
    +
    +.mm-node-right .mm-node-bar,
    +.mm-node.mm-root .mm-node-bar {
    +  right: -12px;
    +}
    +
    +.mm-root .mm-node-bar,
    +.mm-node-second .mm-node-bar {
    +  top: 50%;
    +  margin-top: -5px;
    +  bottom: inherit;
    +}
    +
    +.mm-node-left .mm-node-bar {
    +  left: -12px;
    +}
    +
    +.mm-root .mm-node-bar,
    +.mm-node-leaf .mm-node-bar {
    +  display: none;
    +}
    +
    +.mm-node-collapse .mm-node-bar {
    +  display: block !important;
    +  box-sizing: border-box;
    +  border: 0px;
    +  background-color: #fff !important;
    +  border: 2px solid #ccc;
    +}
    +
    +/* node indicate */
    +.mm-node-layout-indicate {
    +  position: absolute;
    +  left:0;
    +  top:0;
    +  width: 0;
    +  height: 0;
    +  border: 20px solid transparent;
    +  border-bottom: 40px solid  var(--interactive-accent);
    +  transform-origin: center center;
    +  z-index:100;
    +}
    +
    +.mm-node-layout-indicate.mm-arrow-left{
    +    transform: rotate(-90deg)
    +} 
    +.mm-node-layout-indicate.mm-arrow-down{
    +  transform: rotate(180deg)
    +} 
    +.mm-node-layout-indicate.mm-arrow-right{
    +  transform: rotate(-270deg)
    +} 
    +
    +
    +/* edit node style */
    +.mm-node.mm-edit-node{
    +    z-index:50;
    +}
    +.mm-node.mm-edit-node .mm-node-content{
    +    background-color: #333;
    +    color:white;
    +}
    +
    +.theme-light .mm-node.mm-edit-node .mm-node-content{
    +  background-color: white;
    +  color:#333
    +}
    +
    +/* menu */
    +.mm-node-menu{
    +  position:absolute;
    +  background:#333;
    +  border:1px solid #000;
    +  width:56px;
    +  border-radius: 0.25rem;
    +  z-index: 60;
    +}
    +
    +.theme-light .mm-node-menu{
    +    background:white;
    +    border:1px solid #666;
    +}
    +
    +.mm-node-menu span {
    +  vertical-align: middle;
    +  cursor: pointer;
    +  margin:0 5px
    +}
    +
    +.mm-node-menu span svg{
    +   fill:#ccc;
    +}
    +
    +.mm-node-menu span svg:hover{
    +  opacity: 0.8;
    +}
    +
    +.theme-light .mm-node-menu svg{
    +  fill: #333;
    +}
    +
    diff --git a/.obsidian/plugins/obsidian-plugin-toc/main.js b/.obsidian/plugins/obsidian-plugin-toc/main.js
    new file mode 100644
    index 000000000..0994e6b14
    --- /dev/null
    +++ b/.obsidian/plugins/obsidian-plugin-toc/main.js
    @@ -0,0 +1,20 @@
    +var J=Object.create,d=Object.defineProperty,z=Object.getPrototypeOf,Z=Object.prototype.hasOwnProperty,K=Object.getOwnPropertyNames,Q=Object.getOwnPropertyDescriptor;var T=u=>d(u,"__esModule",{value:!0});var B=(u,D)=>()=>(D||(D={exports:{}},u(D.exports,D)),D.exports),X=(u,D)=>{for(var F in D)d(u,F,{get:D[F],enumerable:!0})},Y=(u,D,F)=>{if(D&&typeof D=="object"||typeof D=="function")for(let C of K(D))!Z.call(u,C)&&C!=="default"&&d(u,C,{get:()=>D[C],enumerable:!(F=Q(D,C))||F.enumerable});return u},p=u=>Y(T(d(u!=null?J(z(u)):{},"default",u&&u.__esModule&&"default"in u?{get:()=>u.default,enumerable:!0}:{value:u,enumerable:!0})),u);var k=B((cD,f)=>{"use strict";function DD(u){var D=void 0;typeof u=="string"?D=[u]:D=u.raw;for(var F="",C=0;C{y.exports=u=>u!=null&&typeof u=="object"&&u.constructor!==RegExp});var M=B((hD,L)=>{"use strict";function m(u){if(!(this instanceof m))return new m(u);this.err=null,this.value=null;try{this.value=JSON.parse(u)}catch(D){this.err=D}}L.exports=m});var _=B(g=>{"use strict";var A=g&&g.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(g,"__esModule",{value:!0});var uD=A(k()),FD=A(S()),P=A(M()),h="twhZNwxI1aFG3r4";function O(u,...D){let F="";for(let C=0;C0?" ".repeat(s):"";(t?JSON.stringify(e,null,2):e[h]).split(`
    +`).forEach((i,o)=>{o>0?F+=`
    +`+n+i:F+=i})}else if(typeof e=="string"&&e.includes(`
    +`)){let E=F.match(/(?:^|\n)( *)$/);if(typeof e=="string"){let s=E?E[1]:"";F+=e.split(`
    +`).map((n,a)=>(n=h+n,a===0?n:`${s}${n}`)).join(`
    +`)}else F+=e}else F+=e}return F=uD.default(F),F.split(h).join("")}O.pretty=u=>FD.default(u)?{[h]:JSON.stringify(u,null,2)}:u;g.default=O});var H=B((pD,x)=>{x.exports=()=>/(?:[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC3\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDD-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF6](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7C\uDE80-\uDE86\uDE90-\uDEAC\uDEB0-\uDEBA\uDEC0-\uDEC2\uDED0-\uDED9\uDEE0-\uDEE7]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?))/g});var j=B((fD,I)=>{I.exports=function(u,D){D=D||{},D.listUnicodeChar=D.hasOwnProperty("listUnicodeChar")?D.listUnicodeChar:!1,D.stripListLeaders=D.hasOwnProperty("stripListLeaders")?D.stripListLeaders:!0,D.gfm=D.hasOwnProperty("gfm")?D.gfm:!0,D.useImgAltText=D.hasOwnProperty("useImgAltText")?D.useImgAltText:!0,D.abbr=D.hasOwnProperty("abbr")?D.abbr:!1,D.replaceLinksWithURL=D.hasOwnProperty("replaceLinksWithURL")?D.replaceLinksWithURL:!1,D.htmlTagsToSkip=D.hasOwnProperty("htmlTagsToSkip")?D.htmlTagsToSkip:[];var F=u||"";F=F.replace(/^(-\s*?|\*\s*?|_\s*?){3,}\s*/gm,"");try{D.stripListLeaders&&(D.listUnicodeChar?F=F.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm,D.listUnicodeChar+" $1"):F=F.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm,"$1")),D.gfm&&(F=F.replace(/\n={2,}/g,`
    +`).replace(/~{3}.*\n/g,"").replace(/~~/g,"").replace(/`{3}.*\n/g,"")),D.abbr&&(F=F.replace(/\*\[.*\]:.*\n/,"")),F=F.replace(/<[^>]*>/g,"");var C=new RegExp("<[^>]*>","g");if(D.htmlTagsToSkip.length>0){var e="(?!"+D.htmlTagsToSkip.join("|")+")";C=new RegExp("<"+e+"[^>]*>","ig")}F=F.replace(C,"").replace(/^[=\-]{2,}\s*$/g,"").replace(/\[\^.+?\](\: .*?$)?/g,"").replace(/\s{0,2}\[.*?\]: .*?$/g,"").replace(/\!\[(.*?)\][\[\(].*?[\]\)]/g,D.useImgAltText?"$1":"").replace(/\[([^\]]*?)\][\[\(].*?[\]\)]/g,D.replaceLinksWithURL?"$2":"$1").replace(/^\s{0,3}>\s?/gm,"").replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g,"").replace(/^(\n)?\s{0,}#{1,6}\s+| {0,}(\n)?\s{0,}#{0,} #{0,}(\n)?\s{0,}$/gm,"$1$2$3").replace(/([\*]+)(\S)(.*?\S)??\1/g,"$2$3").replace(/(^|\W)([_]+)(\S)(.*?\S)??\2($|\W)/g,"$1$3$4$5").replace(/(`{3,})(.*?)\1/gm,"$2").replace(/`(.+?)`/g,"$1").replace(/~(.*?)~/g,"$1")}catch(t){return console.error(t),u}return F}});var R=B((mD,N)=>{"use strict";var eD=H(),tD=j();function CD(u,D){return u=u.replace(/[^a-z0-9]+/g,"_"),u=u.replace(/^_+|_+$/,""),u=u.replace(/^([^a-z])/,"_$1"),D&&(u+="_"+D),u}function U(u){return u.replace(/ /g,"-").replace(/%([abcdef]|\d){2,2}/ig,"").replace(/[\/?!:\[\]`.,()*"';{}+=<>~\$|#@&–—]/g,"").replace(/[。?!,、;:“”【】()〔〕[]﹃﹄“ ”‘’﹁﹂—…-~《》〈〉「」]/g,"")}function nD(u,D){return u=U(u),D&&(u+="-"+D),u=u.replace(eD(),""),u=tD(u),u}function ED(u,D){return u="markdown-header-"+U(u),u=u.replace(/--+/g,"-"),D&&(u+="_"+D),u}function aD(u){return u.replace(/ /g,"").replace(/[\/?:\[\]`.,()*"';{}\-+=<>!@#%^&\\\|]/g,"").replace(/\$/g,"d").replace(/~/g,"t")}function rD(u){return u=aD(u),u}function iD(u,D){return u=u.replace(/<(.*)>(.*)<\/\1>/g,"$2").replace(/!\[.*\]\(.*\)/g,"").replace(/\[(.*)\]\(.*\)/,"$1").replace(/\s+/g,"-").replace(/[\/?!:\[\]`.,()*"';{}+=<>~\$|#@]/g,"").replace(/[。?!,、;:“”【】()〔〕[]﹃﹄“ ”‘’﹁﹂—…-~《》〈〉「」]/g,"").replace(/[-]+/g,"-").replace(/^-/,"").replace(/-$/,""),D&&(u+="-"+D),u}N.exports=function(D,F,C,e){F=F||"github.com";var t,E=encodeURI;switch(F){case"github.com":t=nD,E=function(a){var l=encodeURI(a);return l.replace(/%E2%80%8D/g,"\u200D")};break;case"bitbucket.org":t=ED;break;case"gitlab.com":t=iD;break;case"nodejs.org":if(!e)throw new Error("Need module name to generate proper anchor for "+F);t=function(a,l){return CD(e+"."+a,l)};break;case"ghost.org":t=rD;break;default:throw new Error("Unknown mode: "+F)}function s(a){for(var l="",i=0;i="A"&&a[i]<="Z"?l+=a[i].toLowerCase():l+=a[i];return l}var n=t(s(D.trim()),C);return"["+D+"](#"+E(n)+")"}});T(exports);X(exports,{default:()=>BD});var r=p(require("obsidian"));var b=p(_()),G=p(require("obsidian")),V=p(R()),w=(u,D)=>{let F=u.filter(C=>C.position.end.lineu.filter(F=>F.position.end.line>D.line),lD=(u,D)=>{let F=u.indexOf(D);return u.slice(0,F).reverse().find((e,t,E)=>e.level==D.level-1)},q=({headings:u=[]},D,F)=>{let C=w(u,D),e=sD(u,D),t=[];for(let n of e){if(n.level<=C)break;n.level>=F.minimumDepth&&n.level<=F.maximumDepth&&t.push(n)}if(!t.length){new G.Notice(b.default`
    +        No headings below cursor matched settings 
    +        (min: ${F.minimumDepth}) (max: ${F.maximumDepth})
    +      `);return}let E=t[0].level,s=t.map(n=>{let a=F.listStyle==="number"&&"1."||"-",l=new Array(Math.max(0,n.level-E)).fill("	").join(""),i=lD(t,n),o=`${l}${a}`,$=n.heading,c;return F.useMarkdown&&F.githubCompat?`${o} ${(0,V.default)(n.heading)}`:(F.useMarkdown?c=encodeURI(n.heading):typeof i=="undefined"?c=n.heading:c=`${i.heading}#${n.heading}`,F.useMarkdown?`${o} [${$}](#${c})`:`${o} [[#${c}|${$}]]`)});return b.default`
    +    ${F.title?`${F.title}
    +`:""}
    +    ${`${s.join(`
    +`)}
    +`}
    +  `};var W=class extends r.PluginSettingTab{constructor(D,F){super(D,F);this.plugin=F}display(){let{containerEl:D}=this;D.empty(),D.createEl("h2",{text:"Table of Contents - Settings"}),new r.Setting(D).setName("List Style").setDesc("The type of list to render the table of contents as.").addDropdown(e=>e.setValue(this.plugin.settings.listStyle).addOption("bullet","Bullet").addOption("number","Number").onChange(t=>{this.plugin.settings.listStyle=t,this.plugin.saveData(this.plugin.settings),this.display()})),new r.Setting(D).setName("Title").setDesc("Optional title to put before the table of contents").addText(e=>e.setPlaceholder("**Table of Contents**").setValue(this.plugin.settings.title||"").onChange(t=>{this.plugin.settings.title=t,this.plugin.saveData(this.plugin.settings)})),new r.Setting(D).setName("Minimum Header Depth").setDesc("The lowest header depth to add to the table of contents. Defaults to 2").addSlider(e=>e.setValue(this.plugin.settings.minimumDepth).setDynamicTooltip().setLimits(1,6,1).onChange(t=>{this.plugin.settings.minimumDepth=t,this.plugin.saveData(this.plugin.settings)})),new r.Setting(D).setName("Maximum Header Depth").setDesc("The highest header depth to add to the table of contents. Defaults to 6").addSlider(e=>e.setValue(this.plugin.settings.maximumDepth).setDynamicTooltip().setLimits(1,6,1).onChange(t=>{this.plugin.settings.maximumDepth=t,this.plugin.saveData(this.plugin.settings)})),new r.Setting(D).setName("Use Markdown links").setDesc("Auto-generate Markdown links, instead of the default WikiLinks").addToggle(e=>e.setValue(this.plugin.settings.useMarkdown).onChange(t=>{this.plugin.settings.useMarkdown=t,this.plugin.saveData(this.plugin.settings),t||C.components[0].setValue(!1),C.setDisabled(!t)}));let F=new DocumentFragment;F.appendText("Github generates section links differently than Obsidian, this setting uses "),F.createEl("a",{href:"https://github.com/thlorenz/anchor-markdown-header",text:"anchor-markdown-header"}),F.appendText(" to generate the proper links.");let C=new r.Setting(D).setName("Github compliant Markdown section links").setDesc(F).setDisabled(!this.plugin.settings.useMarkdown).addToggle(e=>e.setValue(this.plugin.settings.githubCompat??!1).setDisabled(!this.plugin.settings.useMarkdown).onChange(t=>{this.plugin.settings.githubCompat=t,this.plugin.saveData(this.plugin.settings)}))}},v=class extends r.Plugin{constructor(){super(...arguments);this.settings={minimumDepth:2,maximumDepth:6,listStyle:"bullet",useMarkdown:!1};this.createTocForActiveFile=(D=this.settings)=>()=>{let F=this.app.workspace.getActiveViewOfType(r.MarkdownView);if(F&&F.file){let C=F.sourceMode.cmEditor,e=C.getCursor(),t=this.app.metadataCache.getFileCache(F.file)||{},E=q(t,e,typeof D=="function"?D(t,e):D);E&&C.replaceRange(E,e)}}}async onload(){console.log("Load Table of Contents plugin"),this.settings={...this.settings,...await this.loadData()},this.addCommand({id:"create-toc",name:"Create table of contents",callback:this.createTocForActiveFile()}),this.addCommand({id:"create-toc-next-level",name:"Create table of contents for next heading level",callback:this.createTocForActiveFile((D,F)=>{let C=w(D.headings||[],F),e=Math.max(C+1,this.settings.minimumDepth);return{...this.settings,minimumDepth:e,maximumDepth:e}})}),this.addSettingTab(new W(this.app,this))}},BD=v;
    diff --git a/.obsidian/plugins/obsidian-plugin-toc/manifest.json b/.obsidian/plugins/obsidian-plugin-toc/manifest.json
    new file mode 100644
    index 000000000..8d39a3d20
    --- /dev/null
    +++ b/.obsidian/plugins/obsidian-plugin-toc/manifest.json
    @@ -0,0 +1,10 @@
    +{
    +  "id": "obsidian-plugin-toc",
    +  "name": "Table of Contents",
    +  "author": "Andrew Lisowski",
    +  "authorUrl": "https://twitter.com/hipstersmoothie",
    +  "description": "Create a table of contents for a note.",
    +  "isDesktopOnly": false,
    +  "minAppVersion": "0.10.12",
    +  "version": "0.2.0"
    +}
    \ No newline at end of file
    diff --git a/.obsidian/plugins/table-editor-obsidian/data.json b/.obsidian/plugins/table-editor-obsidian/data.json
    new file mode 100644
    index 000000000..90094659b
    --- /dev/null
    +++ b/.obsidian/plugins/table-editor-obsidian/data.json
    @@ -0,0 +1,6 @@
    +{
    +  "formatType": "normal",
    +  "showRibbonIcon": true,
    +  "bindEnter": true,
    +  "bindTab": true
    +}
    \ No newline at end of file
    diff --git a/.obsidian/plugins/table-editor-obsidian/main.js b/.obsidian/plugins/table-editor-obsidian/main.js
    new file mode 100644
    index 000000000..a3dfb9aa5
    --- /dev/null
    +++ b/.obsidian/plugins/table-editor-obsidian/main.js
    @@ -0,0 +1,28989 @@
    +'use strict';
    +
    +var obsidian = require('obsidian');
    +var state = require('@codemirror/state');
    +var view = require('@codemirror/view');
    +
    +/*! *****************************************************************************
    +Copyright (c) Microsoft Corporation.
    +
    +Permission to use, copy, modify, and/or distribute this software for any
    +purpose with or without fee is hereby granted.
    +
    +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    +PERFORMANCE OF THIS SOFTWARE.
    +***************************************************************************** */
    +/* global Reflect, Promise */
    +
    +var extendStatics = function(d, b) {
    +    extendStatics = Object.setPrototypeOf ||
    +        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
    +        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
    +    return extendStatics(d, b);
    +};
    +
    +function __extends(d, b) {
    +    extendStatics(d, b);
    +    function __() { this.constructor = d; }
    +    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    +}
    +
    +var __assign = function() {
    +    __assign = Object.assign || function __assign(t) {
    +        for (var s, i = 1, n = arguments.length; i < n; i++) {
    +            s = arguments[i];
    +            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
    +        }
    +        return t;
    +    };
    +    return __assign.apply(this, arguments);
    +};
    +
    +function __awaiter(thisArg, _arguments, P, generator) {
    +    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    +    return new (P || (P = Promise))(function (resolve, reject) {
    +        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
    +        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
    +        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
    +        step((generator = generator.apply(thisArg, _arguments || [])).next());
    +    });
    +}
    +
    +function __generator(thisArg, body) {
    +    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    +    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    +    function verb(n) { return function (v) { return step([n, v]); }; }
    +    function step(op) {
    +        if (f) throw new TypeError("Generator is already executing.");
    +        while (_) try {
    +            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
    +            if (y = 0, t) op = [op[0] & 2, t.value];
    +            switch (op[0]) {
    +                case 0: case 1: t = op; break;
    +                case 4: _.label++; return { value: op[1], done: false };
    +                case 5: _.label++; y = op[1]; op = [0]; continue;
    +                case 7: op = _.ops.pop(); _.trys.pop(); continue;
    +                default:
    +                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
    +                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
    +                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
    +                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
    +                    if (t[2]) _.ops.pop();
    +                    _.trys.pop(); continue;
    +            }
    +            op = body.call(thisArg, _);
    +        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
    +        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    +    }
    +}
    +
    +var icons = {
    +    spreadsheet: "\n\n  \n",
    +    alignLeft: "\n\n  \n    \n    \n    \n    \n  \n",
    +    alignCenter: "\n\n  \n    \n    \n    \n    \n  \n",
    +    alignRight: "\n\n  \n  \n  \n  \n",
    +    deleteColumn: "\n\n  \n  \n",
    +    deleteRow: "\n\n  \n  \n  \n",
    +    insertColumn: "\n\n  \n  \n  \n  \n  \n  \n",
    +    insertRow: "\n\n  \n  \n  \n  \n  \n  \n",
    +    moveColumnLeft: "\n\n  \n  \n  \n",
    +    moveColumnRight: "\n\n  \n  \n  \n",
    +    moveRowDown: "\n\n  \n  \n  \n",
    +    moveRowUp: "\n\n  \n  \n  \n",
    +    sortAsc: "\n\n  \n    \n    \n  \n  \n  \n",
    +    sortDesc: "\n\n  \n    \n    \n  \n  \n  \n",
    +    formula: "\n\n  \n  \n",
    +    help: "\n\n  \n  \n  \n",
    +    csv: "\n\n \n",
    +    arrowenter: "\n\n  \n",
    +    arrowtab: "\n\n  \n",
    +};
    +var addIcons = function () {
    +    Object.keys(icons).forEach(function (key) {
    +        // Don't add the 'help' icon here as it will overwrite the native one.
    +        if (key !== 'help') {
    +            obsidian.addIcon(key, icons[key]);
    +        }
    +    });
    +};
    +
    +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
    +
    +function createCommonjsModule(fn, basedir, module) {
    +	return module = {
    +		path: basedir,
    +		exports: {},
    +		require: function (path, base) {
    +			return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
    +		}
    +	}, fn(module, module.exports), module.exports;
    +}
    +
    +function getAugmentedNamespace(n) {
    +	if (n.__esModule) return n;
    +	var a = Object.defineProperty({}, '__esModule', {value: true});
    +	Object.keys(n).forEach(function (k) {
    +		var d = Object.getOwnPropertyDescriptor(n, k);
    +		Object.defineProperty(a, k, d.get ? d : {
    +			enumerable: true,
    +			get: function () {
    +				return n[k];
    +			}
    +		});
    +	});
    +	return a;
    +}
    +
    +function commonjsRequire () {
    +	throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
    +}
    +
    +var point = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.Point = void 0;
    +/**
    + * A `Point` represents a point in the text editor.
    + */
    +class Point {
    +    /**
    +     * Creates a new `Point` object.
    +     *
    +     * @param row - Row of the point, starts from 0.
    +     * @param column - Column of the point, starts from 0.
    +     */
    +    constructor(row, column) {
    +        this.row = row;
    +        this.column = column;
    +    }
    +    /**
    +     * Checks if the point is equal to another point.
    +     */
    +    equals(point) {
    +        return this.row === point.row && this.column === point.column;
    +    }
    +}
    +exports.Point = Point;
    +});
    +
    +var range = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.Range = void 0;
    +/**
    + * A `Range` object represents a range in the text editor.
    + */
    +class Range {
    +    /**
    +     * Creates a new `Range` object.
    +     *
    +     * @param start - The start point of the range.
    +     * @param end - The end point of the range.
    +     */
    +    constructor(start, end) {
    +        this.start = start;
    +        this.end = end;
    +    }
    +}
    +exports.Range = Range;
    +});
    +
    +var focus = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.Focus = void 0;
    +/**
    + * A `Focus` object represents which cell is focused in the table.
    + *
    + * Note that `row` and `column` properties specifiy a cell's position in the
    + * table, not the cursor's position in the text editor as {@link Point} class.
    + *
    + * @private
    + */
    +class Focus {
    +    /**
    +     * Creates a new `Focus` object.
    +     *
    +     * @param row - Row of the focused cell.
    +     * @param column - Column of the focused cell.
    +     * @param offset - Raw offset in the cell.
    +     */
    +    constructor(row, column, offset) {
    +        this.row = row;
    +        this.column = column;
    +        this.offset = offset;
    +    }
    +    /**
    +     * Checks if two focuses point the same cell.
    +     * Offsets are ignored.
    +     */
    +    posEquals(focus) {
    +        return this.row === focus.row && this.column === focus.column;
    +    }
    +    /**
    +     * Creates a copy of the focus object by setting its row to the specified value.
    +     *
    +     * @param row - Row of the focused cell.
    +     * @returns A new focus object with the specified row.
    +     */
    +    setRow(row) {
    +        return new Focus(row, this.column, this.offset);
    +    }
    +    /**
    +     * Creates a copy of the focus object by setting its column to the specified value.
    +     *
    +     * @param column - Column of the focused cell.
    +     * @returns A new focus object with the specified column.
    +     */
    +    setColumn(column) {
    +        return new Focus(this.row, column, this.offset);
    +    }
    +    /**
    +     * Creates a copy of the focus object by setting its offset to the specified value.
    +     *
    +     * @param offset - Offset in the focused cell.
    +     * @returns A new focus object with the specified offset.
    +     */
    +    setOffset(offset) {
    +        return new Focus(this.row, this.column, offset);
    +    }
    +}
    +exports.Focus = Focus;
    +});
    +
    +var alignment = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.HeaderAlignment = exports.DefaultAlignment = exports.Alignment = void 0;
    +/**
    + * Represents column alignment.
    + *
    + * - `Alignment.NONE` - Use default alignment.
    + * - `Alignment.LEFT` - Align left.
    + * - `Alignment.RIGHT` - Align right.
    + * - `Alignment.CENTER` - Align center.
    + *
    + */
    +var Alignment;
    +(function (Alignment) {
    +    Alignment["NONE"] = "none";
    +    Alignment["LEFT"] = "left";
    +    Alignment["RIGHT"] = "right";
    +    Alignment["CENTER"] = "center";
    +})(Alignment = exports.Alignment || (exports.Alignment = {}));
    +/**
    + * Represents default column alignment
    + *
    + * - `DefaultAlignment.LEFT` - Align left.
    + * - `DefaultAlignment.RIGHT` - Align right.
    + * - `DefaultAlignment.CENTER` - Align center.
    + *
    + */
    +var DefaultAlignment;
    +(function (DefaultAlignment) {
    +    DefaultAlignment["LEFT"] = "left";
    +    DefaultAlignment["RIGHT"] = "right";
    +    DefaultAlignment["CENTER"] = "center";
    +})(DefaultAlignment = exports.DefaultAlignment || (exports.DefaultAlignment = {}));
    +/**
    + * Represents alignment of header cells.
    + *
    + * - `HeaderAlignment.FOLLOW` - Follow column's alignment.
    + * - `HeaderAlignment.LEFT` - Align left.
    + * - `HeaderAlignment.RIGHT` - Align right.
    + * - `HeaderAlignment.CENTER` - Align center.
    + *
    + */
    +var HeaderAlignment;
    +(function (HeaderAlignment) {
    +    HeaderAlignment["FOLLOW"] = "follow";
    +    HeaderAlignment["LEFT"] = "left";
    +    HeaderAlignment["RIGHT"] = "right";
    +    HeaderAlignment["CENTER"] = "center";
    +})(HeaderAlignment = exports.HeaderAlignment || (exports.HeaderAlignment = {}));
    +});
    +
    +var tableCell = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.TableCell = void 0;
    +
    +/**
    + * A `TableCell` object represents a table cell.
    + *
    + * @private
    + */
    +class TableCell {
    +    /**
    +     * Creates a new `TableCell` object.
    +     *
    +     * @param rawContent - Raw content of the cell.
    +     */
    +    constructor(rawContent) {
    +        this.rawContent = rawContent;
    +        this.content = rawContent.trim();
    +        this.paddingLeft =
    +            this.content === ''
    +                ? this.rawContent === ''
    +                    ? 0
    +                    : 1
    +                : this.rawContent.length - this.rawContent.trimLeft().length;
    +        this.paddingRight =
    +            this.rawContent.length - this.content.length - this.paddingLeft;
    +    }
    +    /**
    +     * Convers the cell to a text representation.
    +     *
    +     * @returns The raw content of the cell.
    +     */
    +    toText() {
    +        return this.rawContent;
    +    }
    +    /**
    +     * Checks if the cell is a delimiter i.e. it only contains hyphens `-` with optional one
    +     * leading and trailing colons `:`.
    +     *
    +     * @returns `true` if the cell is a delimiter.
    +     */
    +    isDelimiter() {
    +        return /^\s*:?-+:?\s*$/.test(this.rawContent);
    +    }
    +    /**
    +     * Returns the alignment the cell represents.
    +     *
    +     * @returns The alignment the cell represents; `undefined` if the cell is not a delimiter.
    +     */
    +    getAlignment() {
    +        if (!this.isDelimiter()) {
    +            return undefined;
    +        }
    +        if (this.content[0] === ':') {
    +            if (this.content[this.content.length - 1] === ':') {
    +                return alignment.Alignment.CENTER;
    +            }
    +            return alignment.Alignment.LEFT;
    +        }
    +        if (this.content[this.content.length - 1] === ':') {
    +            return alignment.Alignment.RIGHT;
    +        }
    +        return alignment.Alignment.NONE;
    +    }
    +    /**
    +     * Computes a relative position in the trimmed content from that in the raw content.
    +     *
    +     * @param rawOffset - Relative position in the raw content.
    +     * @returns - Relative position in the trimmed content.
    +     */
    +    computeContentOffset(rawOffset) {
    +        if (this.content === '') {
    +            return 0;
    +        }
    +        if (rawOffset < this.paddingLeft) {
    +            return 0;
    +        }
    +        if (rawOffset < this.paddingLeft + this.content.length) {
    +            return rawOffset - this.paddingLeft;
    +        }
    +        return this.content.length;
    +    }
    +    /**
    +     * Computes a relative position in the raw content from that in the trimmed content.
    +     *
    +     * @param contentOffset - Relative position in the trimmed content.
    +     * @returns - Relative position in the raw content.
    +     */
    +    computeRawOffset(contentOffset) {
    +        return contentOffset + this.paddingLeft;
    +    }
    +}
    +exports.TableCell = TableCell;
    +});
    +
    +var tableRow = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.TableRow = void 0;
    +
    +/**
    + * A `TableRow` object represents a table row.
    + *
    + * @private
    + */
    +class TableRow {
    +    /**
    +     * Creates a new `TableRow` objec.
    +     *
    +     * @param cells - Cells that the row contains.
    +     * @param marginLeft - Margin string at the left of the row.
    +     * @param marginRight - Margin string at the right of the row.
    +     */
    +    constructor(cells, marginLeft, marginRight) {
    +        this._cells = cells.slice();
    +        this.marginLeft = marginLeft;
    +        this.marginRight = marginRight;
    +    }
    +    /**
    +     * Gets the number of the cells in the row.
    +     */
    +    getWidth() {
    +        return this._cells.length;
    +    }
    +    /**
    +     * Returns the cells that the row contains.
    +     */
    +    getCells() {
    +        return this._cells.slice();
    +    }
    +    /**
    +     * Gets a cell at the specified index.
    +     *
    +     * @param index - Index.
    +     * @returns The cell at the specified index if exists; `undefined` if no cell is found.
    +     */
    +    getCellAt(index) {
    +        return this._cells[index];
    +    }
    +    /**
    +     * Sets a cell in the row to a new value, returning a copy of the row
    +     * with the modified value.
    +     *
    +     * If an invalid index is provided, the row will be unchanged.
    +     */
    +    setCellAt(index, value) {
    +        const cells = this.getCells(); // a copy
    +        cells[index] = new tableCell.TableCell(value);
    +        return new TableRow(cells, this.marginLeft, this.marginRight);
    +    }
    +    /**
    +     * Convers the row to a text representation.
    +     */
    +    toText() {
    +        if (this._cells.length === 0) {
    +            return this.marginLeft;
    +        }
    +        const cells = this._cells.map((cell) => cell.toText()).join('|');
    +        return `${this.marginLeft}|${cells}|${this.marginRight}`;
    +    }
    +    /**
    +     * Checks if the row is a delimiter or not.
    +     *
    +     * @returns `true` if the row is a delimiter i.e. all the cells contained are delimiters.
    +     */
    +    isDelimiter() {
    +        return this._cells.every((cell) => cell.isDelimiter());
    +    }
    +}
    +exports.TableRow = TableRow;
    +});
    +
    +var neverthrow = createCommonjsModule(function (module, exports) {
    +/**
    + * Retrieved from
    + *   https://github.com/supermacro/neverthrow
    + *
    + * MIT License
    + * Copyright (c) 2019 Giorgio Delgado
    + */
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.Err = exports.Ok = exports.err = exports.ok = void 0;
    +const ok = (value) => new Ok(value);
    +exports.ok = ok;
    +const err = (err) => new Err(err);
    +exports.err = err;
    +class Ok {
    +    constructor(value) {
    +        this.value = value;
    +        this.match = (ok, _err) => ok(this.value);
    +    }
    +    isOk() {
    +        return true;
    +    }
    +    isErr() {
    +        return !this.isOk();
    +    }
    +    map(f) {
    +        return exports.ok(f(this.value));
    +    }
    +    mapErr(_f) {
    +        return exports.ok(this.value);
    +    }
    +    // add info on how this is really useful for converting a
    +    // Result, E1>
    +    // into a Result
    +    andThen(f) {
    +        return f(this.value);
    +    }
    +    unwrapOr(_v) {
    +        return this.value;
    +    }
    +    _unsafeUnwrap() {
    +        return this.value;
    +    }
    +    _unsafeUnwrapErr() {
    +        throw new Error('Called `_unsafeUnwrapErr` on an Ok');
    +    }
    +}
    +exports.Ok = Ok;
    +class Err {
    +    constructor(error) {
    +        this.error = error;
    +        this.match = (_ok, err) => err(this.error);
    +    }
    +    isOk() {
    +        return false;
    +    }
    +    isErr() {
    +        return !this.isOk();
    +    }
    +    map(_f) {
    +        return exports.err(this.error);
    +    }
    +    mapErr(f) {
    +        return exports.err(f(this.error));
    +    }
    +    andThen(_f) {
    +        return exports.err(this.error);
    +    }
    +    unwrapOr(v) {
    +        return v;
    +    }
    +    _unsafeUnwrap() {
    +        throw new Error('Called `_unsafeUnwrap` on an Err');
    +    }
    +    _unsafeUnwrapErr() {
    +        return this.error;
    +    }
    +}
    +exports.Err = Err;
    +});
    +
    +var ast_utils = createCommonjsModule(function (module, exports) {
    +Object.defineProperty(exports, "__esModule", { value: true });
    +exports.prettyPrintAST = exports.checkChildLength = exports.checkType = exports.errRelativeReferenceIndex = exports.errIndex0 = void 0;
    +exports.errIndex0 = new Error('Index 0 used to create a reference');
    +exports.errRelativeReferenceIndex = new Error('Can not use relative reference where absolute reference is required');
    +const checkType = (ast, ...expectedTypes) => {
    +    if (expectedTypes.indexOf(ast.type) >= 0) {
    +        return;
    +    }
    +    return new Error(`Formula element '${ast.text}' is a ${ast.type} but expected ` +
    +        `one of ${expectedTypes} in this position.`);
    +};
    +exports.checkType = checkType;
    +const checkChildLength = (ast, len) => {
    +    if (ast.children.length === len) {
    +        return;
    +    }
    +    return new Error(`Formula element '${ast.text}' was expected to have ${len} ` +
    +        `elements, but had ${ast.children.length}`);
    +};
    +exports.checkChildLength = checkChildLength;
    +const prettyPrintAST = (token, level = 0) => {
    +    console.log('  '.repeat(level) +
    +        `|-${token.type}${token.children.length === 0 ? '=' + token.text : ''}`);
    +    if (token.children) {
    +        token.children.forEach((c) => {
    +            exports.prettyPrintAST(c, level + 1);
    +        });
    +    }
    +};
    +exports.prettyPrintAST = prettyPrintAST;
    +});
    +
    +var decimal = createCommonjsModule(function (module) {
    +(function (globalScope) {
    +
    +
    +  /*!
    +   *  decimal.js v10.4.3
    +   *  An arbitrary-precision Decimal type for JavaScript.
    +   *  https://github.com/MikeMcl/decimal.js
    +   *  Copyright (c) 2022 Michael Mclaughlin 
    +   *  MIT Licence
    +   */
    +
    +
    +  // -----------------------------------  EDITABLE DEFAULTS  ------------------------------------ //
    +
    +
    +    // The maximum exponent magnitude.
    +    // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`.
    +  var EXP_LIMIT = 9e15,                      // 0 to 9e15
    +
    +    // The limit on the value of `precision`, and on the value of the first argument to
    +    // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`.
    +    MAX_DIGITS = 1e9,                        // 0 to 1e9
    +
    +    // Base conversion alphabet.
    +    NUMERALS = '0123456789abcdef',
    +
    +    // The natural logarithm of 10 (1025 digits).
    +    LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058',
    +
    +    // Pi (1025 digits).
    +    PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789',
    +
    +
    +    // The initial configuration properties of the Decimal constructor.
    +    DEFAULTS = {
    +
    +      // These values must be integers within the stated ranges (inclusive).
    +      // Most of these values can be changed at run-time using the `Decimal.config` method.
    +
    +      // The maximum number of significant digits of the result of a calculation or base conversion.
    +      // E.g. `Decimal.config({ precision: 20 });`
    +      precision: 20,                         // 1 to MAX_DIGITS
    +
    +      // The rounding mode used when rounding to `precision`.
    +      //
    +      // ROUND_UP         0 Away from zero.
    +      // ROUND_DOWN       1 Towards zero.
    +      // ROUND_CEIL       2 Towards +Infinity.
    +      // ROUND_FLOOR      3 Towards -Infinity.
    +      // ROUND_HALF_UP    4 Towards nearest neighbour. If equidistant, up.
    +      // ROUND_HALF_DOWN  5 Towards nearest neighbour. If equidistant, down.
    +      // ROUND_HALF_EVEN  6 Towards nearest neighbour. If equidistant, towards even neighbour.
    +      // ROUND_HALF_CEIL  7 Towards nearest neighbour. If equidistant, towards +Infinity.
    +      // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
    +      //
    +      // E.g.
    +      // `Decimal.rounding = 4;`
    +      // `Decimal.rounding = Decimal.ROUND_HALF_UP;`
    +      rounding: 4,                           // 0 to 8
    +
    +      // The modulo mode used when calculating the modulus: a mod n.
    +      // The quotient (q = a / n) is calculated according to the corresponding rounding mode.
    +      // The remainder (r) is calculated as: r = a - n * q.
    +      //
    +      // UP         0 The remainder is positive if the dividend is negative, else is negative.
    +      // DOWN       1 The remainder has the same sign as the dividend (JavaScript %).
    +      // FLOOR      3 The remainder has the same sign as the divisor (Python %).
    +      // HALF_EVEN  6 The IEEE 754 remainder function.
    +      // EUCLID     9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive.
    +      //
    +      // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian
    +      // division (9) are commonly used for the modulus operation. The other rounding modes can also
    +      // be used, but they may not give useful results.
    +      modulo: 1,                             // 0 to 9
    +
    +      // The exponent value at and beneath which `toString` returns exponential notation.
    +      // JavaScript numbers: -7
    +      toExpNeg: -7,                          // 0 to -EXP_LIMIT
    +
    +      // The exponent value at and above which `toString` returns exponential notation.
    +      // JavaScript numbers: 21
    +      toExpPos:  21,                         // 0 to EXP_LIMIT
    +
    +      // The minimum exponent value, beneath which underflow to zero occurs.
    +      // JavaScript numbers: -324  (5e-324)
    +      minE: -EXP_LIMIT,                      // -1 to -EXP_LIMIT
    +
    +      // The maximum exponent value, above which overflow to Infinity occurs.
    +      // JavaScript numbers: 308  (1.7976931348623157e+308)
    +      maxE: EXP_LIMIT,                       // 1 to EXP_LIMIT
    +
    +      // Whether to use cryptographically-secure random number generation, if available.
    +      crypto: false                          // true/false
    +    },
    +
    +
    +  // ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- //
    +
    +
    +    Decimal, inexact, noConflict, quadrant,
    +    external = true,
    +
    +    decimalError = '[DecimalError] ',
    +    invalidArgument = decimalError + 'Invalid argument: ',
    +    precisionLimitExceeded = decimalError + 'Precision limit exceeded',
    +    cryptoUnavailable = decimalError + 'crypto unavailable',
    +    tag = '[object Decimal]',
    +
    +    mathfloor = Math.floor,
    +    mathpow = Math.pow,
    +
    +    isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i,
    +    isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i,
    +    isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i,
    +    isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
    +
    +    BASE = 1e7,
    +    LOG_BASE = 7,
    +    MAX_SAFE_INTEGER = 9007199254740991,
    +
    +    LN10_PRECISION = LN10.length - 1,
    +    PI_PRECISION = PI.length - 1,
    +
    +    // Decimal.prototype object
    +    P = { toStringTag: tag };
    +
    +
    +  // Decimal prototype methods
    +
    +
    +  /*
    +   *  absoluteValue             abs
    +   *  ceil
    +   *  clampedTo                 clamp
    +   *  comparedTo                cmp
    +   *  cosine                    cos
    +   *  cubeRoot                  cbrt
    +   *  decimalPlaces             dp
    +   *  dividedBy                 div
    +   *  dividedToIntegerBy        divToInt
    +   *  equals                    eq
    +   *  floor
    +   *  greaterThan               gt
    +   *  greaterThanOrEqualTo      gte
    +   *  hyperbolicCosine          cosh
    +   *  hyperbolicSine            sinh
    +   *  hyperbolicTangent         tanh
    +   *  inverseCosine             acos
    +   *  inverseHyperbolicCosine   acosh
    +   *  inverseHyperbolicSine     asinh
    +   *  inverseHyperbolicTangent  atanh
    +   *  inverseSine               asin
    +   *  inverseTangent            atan
    +   *  isFinite
    +   *  isInteger                 isInt
    +   *  isNaN
    +   *  isNegative                isNeg
    +   *  isPositive                isPos
    +   *  isZero
    +   *  lessThan                  lt
    +   *  lessThanOrEqualTo         lte
    +   *  logarithm                 log
    +   *  [maximum]                 [max]
    +   *  [minimum]                 [min]
    +   *  minus                     sub
    +   *  modulo                    mod
    +   *  naturalExponential        exp
    +   *  naturalLogarithm          ln
    +   *  negated                   neg
    +   *  plus                      add
    +   *  precision                 sd
    +   *  round
    +   *  sine                      sin
    +   *  squareRoot                sqrt
    +   *  tangent                   tan
    +   *  times                     mul
    +   *  toBinary
    +   *  toDecimalPlaces           toDP
    +   *  toExponential
    +   *  toFixed
    +   *  toFraction
    +   *  toHexadecimal             toHex
    +   *  toNearest
    +   *  toNumber
    +   *  toOctal
    +   *  toPower                   pow
    +   *  toPrecision
    +   *  toSignificantDigits       toSD
    +   *  toString
    +   *  truncated                 trunc
    +   *  valueOf                   toJSON
    +   */
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the absolute value of this Decimal.
    +   *
    +   */
    +  P.absoluteValue = P.abs = function () {
    +    var x = new this.constructor(this);
    +    if (x.s < 0) x.s = 1;
    +    return finalise(x);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the
    +   * direction of positive Infinity.
    +   *
    +   */
    +  P.ceil = function () {
    +    return finalise(new this.constructor(this), this.e + 1, 2);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal clamped to the range
    +   * delineated by `min` and `max`.
    +   *
    +   * min {number|string|Decimal}
    +   * max {number|string|Decimal}
    +   *
    +   */
    +  P.clampedTo = P.clamp = function (min, max) {
    +    var k,
    +      x = this,
    +      Ctor = x.constructor;
    +    min = new Ctor(min);
    +    max = new Ctor(max);
    +    if (!min.s || !max.s) return new Ctor(NaN);
    +    if (min.gt(max)) throw Error(invalidArgument + max);
    +    k = x.cmp(min);
    +    return k < 0 ? min : x.cmp(max) > 0 ? max : new Ctor(x);
    +  };
    +
    +
    +  /*
    +   * Return
    +   *   1    if the value of this Decimal is greater than the value of `y`,
    +   *  -1    if the value of this Decimal is less than the value of `y`,
    +   *   0    if they have the same value,
    +   *   NaN  if the value of either Decimal is NaN.
    +   *
    +   */
    +  P.comparedTo = P.cmp = function (y) {
    +    var i, j, xdL, ydL,
    +      x = this,
    +      xd = x.d,
    +      yd = (y = new x.constructor(y)).d,
    +      xs = x.s,
    +      ys = y.s;
    +
    +    // Either NaN or ±Infinity?
    +    if (!xd || !yd) {
    +      return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1;
    +    }
    +
    +    // Either zero?
    +    if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0;
    +
    +    // Signs differ?
    +    if (xs !== ys) return xs;
    +
    +    // Compare exponents.
    +    if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1;
    +
    +    xdL = xd.length;
    +    ydL = yd.length;
    +
    +    // Compare digit by digit.
    +    for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) {
    +      if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1;
    +    }
    +
    +    // Compare lengths.
    +    return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1;
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the cosine of the value in radians of this Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-1, 1]
    +   *
    +   * cos(0)         = 1
    +   * cos(-0)        = 1
    +   * cos(Infinity)  = NaN
    +   * cos(-Infinity) = NaN
    +   * cos(NaN)       = NaN
    +   *
    +   */
    +  P.cosine = P.cos = function () {
    +    var pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.d) return new Ctor(NaN);
    +
    +    // cos(0) = cos(-0) = 1
    +    if (!x.d[0]) return new Ctor(1);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE;
    +    Ctor.rounding = 1;
    +
    +    x = cosine(Ctor, toLessThanHalfPi(Ctor, x));
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true);
    +  };
    +
    +
    +  /*
    +   *
    +   * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to
    +   * `precision` significant digits using rounding mode `rounding`.
    +   *
    +   *  cbrt(0)  =  0
    +   *  cbrt(-0) = -0
    +   *  cbrt(1)  =  1
    +   *  cbrt(-1) = -1
    +   *  cbrt(N)  =  N
    +   *  cbrt(-I) = -I
    +   *  cbrt(I)  =  I
    +   *
    +   * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3))
    +   *
    +   */
    +  P.cubeRoot = P.cbrt = function () {
    +    var e, m, n, r, rep, s, sd, t, t3, t3plusx,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite() || x.isZero()) return new Ctor(x);
    +    external = false;
    +
    +    // Initial estimate.
    +    s = x.s * mathpow(x.s * x, 1 / 3);
    +
    +     // Math.cbrt underflow/overflow?
    +     // Pass x to Math.pow as integer, then adjust the exponent of the result.
    +    if (!s || Math.abs(s) == 1 / 0) {
    +      n = digitsToString(x.d);
    +      e = x.e;
    +
    +      // Adjust n exponent so it is a multiple of 3 away from x exponent.
    +      if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00');
    +      s = mathpow(n, 1 / 3);
    +
    +      // Rarely, e may be one less than the result exponent value.
    +      e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2));
    +
    +      if (s == 1 / 0) {
    +        n = '5e' + e;
    +      } else {
    +        n = s.toExponential();
    +        n = n.slice(0, n.indexOf('e') + 1) + e;
    +      }
    +
    +      r = new Ctor(n);
    +      r.s = x.s;
    +    } else {
    +      r = new Ctor(s.toString());
    +    }
    +
    +    sd = (e = Ctor.precision) + 3;
    +
    +    // Halley's method.
    +    // TODO? Compare Newton's method.
    +    for (;;) {
    +      t = r;
    +      t3 = t.times(t).times(t);
    +      t3plusx = t3.plus(x);
    +      r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1);
    +
    +      // TODO? Replace with for-loop and checkRoundingDigits.
    +      if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) {
    +        n = n.slice(sd - 3, sd + 1);
    +
    +        // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999
    +        // , i.e. approaching a rounding boundary, continue the iteration.
    +        if (n == '9999' || !rep && n == '4999') {
    +
    +          // On the first iteration only, check to see if rounding up gives the exact result as the
    +          // nines may infinitely repeat.
    +          if (!rep) {
    +            finalise(t, e + 1, 0);
    +
    +            if (t.times(t).times(t).eq(x)) {
    +              r = t;
    +              break;
    +            }
    +          }
    +
    +          sd += 4;
    +          rep = 1;
    +        } else {
    +
    +          // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result.
    +          // If not, then there are further digits and m will be truthy.
    +          if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
    +
    +            // Truncate to the first rounding digit.
    +            finalise(r, e + 1, 1);
    +            m = !r.times(r).times(r).eq(x);
    +          }
    +
    +          break;
    +        }
    +      }
    +    }
    +
    +    external = true;
    +
    +    return finalise(r, e, Ctor.rounding, m);
    +  };
    +
    +
    +  /*
    +   * Return the number of decimal places of the value of this Decimal.
    +   *
    +   */
    +  P.decimalPlaces = P.dp = function () {
    +    var w,
    +      d = this.d,
    +      n = NaN;
    +
    +    if (d) {
    +      w = d.length - 1;
    +      n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE;
    +
    +      // Subtract the number of trailing zeros of the last word.
    +      w = d[w];
    +      if (w) for (; w % 10 == 0; w /= 10) n--;
    +      if (n < 0) n = 0;
    +    }
    +
    +    return n;
    +  };
    +
    +
    +  /*
    +   *  n / 0 = I
    +   *  n / N = N
    +   *  n / I = 0
    +   *  0 / n = 0
    +   *  0 / 0 = N
    +   *  0 / N = N
    +   *  0 / I = 0
    +   *  N / n = N
    +   *  N / 0 = N
    +   *  N / N = N
    +   *  N / I = N
    +   *  I / n = I
    +   *  I / 0 = I
    +   *  I / N = N
    +   *  I / I = N
    +   *
    +   * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to
    +   * `precision` significant digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.dividedBy = P.div = function (y) {
    +    return divide(this, new this.constructor(y));
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the integer part of dividing the value of this Decimal
    +   * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.dividedToIntegerBy = P.divToInt = function (y) {
    +    var x = this,
    +      Ctor = x.constructor;
    +    return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding);
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false.
    +   *
    +   */
    +  P.equals = P.eq = function (y) {
    +    return this.cmp(y) === 0;
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the
    +   * direction of negative Infinity.
    +   *
    +   */
    +  P.floor = function () {
    +    return finalise(new this.constructor(this), this.e + 1, 3);
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is greater than the value of `y`, otherwise return
    +   * false.
    +   *
    +   */
    +  P.greaterThan = P.gt = function (y) {
    +    return this.cmp(y) > 0;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is greater than or equal to the value of `y`,
    +   * otherwise return false.
    +   *
    +   */
    +  P.greaterThanOrEqualTo = P.gte = function (y) {
    +    var k = this.cmp(y);
    +    return k == 1 || k === 0;
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this
    +   * Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [1, Infinity]
    +   *
    +   * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ...
    +   *
    +   * cosh(0)         = 1
    +   * cosh(-0)        = 1
    +   * cosh(Infinity)  = Infinity
    +   * cosh(-Infinity) = Infinity
    +   * cosh(NaN)       = NaN
    +   *
    +   *  x        time taken (ms)   result
    +   * 1000      9                 9.8503555700852349694e+433
    +   * 10000     25                4.4034091128314607936e+4342
    +   * 100000    171               1.4033316802130615897e+43429
    +   * 1000000   3817              1.5166076984010437725e+434294
    +   * 10000000  abandoned after 2 minute wait
    +   *
    +   * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x))
    +   *
    +   */
    +  P.hyperbolicCosine = P.cosh = function () {
    +    var k, n, pr, rm, len,
    +      x = this,
    +      Ctor = x.constructor,
    +      one = new Ctor(1);
    +
    +    if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN);
    +    if (x.isZero()) return one;
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + Math.max(x.e, x.sd()) + 4;
    +    Ctor.rounding = 1;
    +    len = x.d.length;
    +
    +    // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1
    +    // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4))
    +
    +    // Estimate the optimum number of times to use the argument reduction.
    +    // TODO? Estimation reused from cosine() and may not be optimal here.
    +    if (len < 32) {
    +      k = Math.ceil(len / 3);
    +      n = (1 / tinyPow(4, k)).toString();
    +    } else {
    +      k = 16;
    +      n = '2.3283064365386962890625e-10';
    +    }
    +
    +    x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true);
    +
    +    // Reverse argument reduction
    +    var cosh2_x,
    +      i = k,
    +      d8 = new Ctor(8);
    +    for (; i--;) {
    +      cosh2_x = x.times(x);
    +      x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8))));
    +    }
    +
    +    return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this
    +   * Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-Infinity, Infinity]
    +   *
    +   * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ...
    +   *
    +   * sinh(0)         = 0
    +   * sinh(-0)        = -0
    +   * sinh(Infinity)  = Infinity
    +   * sinh(-Infinity) = -Infinity
    +   * sinh(NaN)       = NaN
    +   *
    +   * x        time taken (ms)
    +   * 10       2 ms
    +   * 100      5 ms
    +   * 1000     14 ms
    +   * 10000    82 ms
    +   * 100000   886 ms            1.4033316802130615897e+43429
    +   * 200000   2613 ms
    +   * 300000   5407 ms
    +   * 400000   8824 ms
    +   * 500000   13026 ms          8.7080643612718084129e+217146
    +   * 1000000  48543 ms
    +   *
    +   * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x))
    +   *
    +   */
    +  P.hyperbolicSine = P.sinh = function () {
    +    var k, pr, rm, len,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite() || x.isZero()) return new Ctor(x);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + Math.max(x.e, x.sd()) + 4;
    +    Ctor.rounding = 1;
    +    len = x.d.length;
    +
    +    if (len < 3) {
    +      x = taylorSeries(Ctor, 2, x, x, true);
    +    } else {
    +
    +      // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x))
    +      // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3))
    +      // 3 multiplications and 1 addition
    +
    +      // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x)))
    +      // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5)))
    +      // 4 multiplications and 2 additions
    +
    +      // Estimate the optimum number of times to use the argument reduction.
    +      k = 1.4 * Math.sqrt(len);
    +      k = k > 16 ? 16 : k | 0;
    +
    +      x = x.times(1 / tinyPow(5, k));
    +      x = taylorSeries(Ctor, 2, x, x, true);
    +
    +      // Reverse argument reduction
    +      var sinh2_x,
    +        d5 = new Ctor(5),
    +        d16 = new Ctor(16),
    +        d20 = new Ctor(20);
    +      for (; k--;) {
    +        sinh2_x = x.times(x);
    +        x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20))));
    +      }
    +    }
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return finalise(x, pr, rm, true);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this
    +   * Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-1, 1]
    +   *
    +   * tanh(x) = sinh(x) / cosh(x)
    +   *
    +   * tanh(0)         = 0
    +   * tanh(-0)        = -0
    +   * tanh(Infinity)  = 1
    +   * tanh(-Infinity) = -1
    +   * tanh(NaN)       = NaN
    +   *
    +   */
    +  P.hyperbolicTangent = P.tanh = function () {
    +    var pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite()) return new Ctor(x.s);
    +    if (x.isZero()) return new Ctor(x);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + 7;
    +    Ctor.rounding = 1;
    +
    +    return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of
    +   * this Decimal.
    +   *
    +   * Domain: [-1, 1]
    +   * Range: [0, pi]
    +   *
    +   * acos(x) = pi/2 - asin(x)
    +   *
    +   * acos(0)       = pi/2
    +   * acos(-0)      = pi/2
    +   * acos(1)       = 0
    +   * acos(-1)      = pi
    +   * acos(1/2)     = pi/3
    +   * acos(-1/2)    = 2*pi/3
    +   * acos(|x| > 1) = NaN
    +   * acos(NaN)     = NaN
    +   *
    +   */
    +  P.inverseCosine = P.acos = function () {
    +    var halfPi,
    +      x = this,
    +      Ctor = x.constructor,
    +      k = x.abs().cmp(1),
    +      pr = Ctor.precision,
    +      rm = Ctor.rounding;
    +
    +    if (k !== -1) {
    +      return k === 0
    +        // |x| is 1
    +        ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0)
    +        // |x| > 1 or x is NaN
    +        : new Ctor(NaN);
    +    }
    +
    +    if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5);
    +
    +    // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3
    +
    +    Ctor.precision = pr + 6;
    +    Ctor.rounding = 1;
    +
    +    x = x.asin();
    +    halfPi = getPi(Ctor, pr + 4, rm).times(0.5);
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return halfPi.minus(x);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the
    +   * value of this Decimal.
    +   *
    +   * Domain: [1, Infinity]
    +   * Range: [0, Infinity]
    +   *
    +   * acosh(x) = ln(x + sqrt(x^2 - 1))
    +   *
    +   * acosh(x < 1)     = NaN
    +   * acosh(NaN)       = NaN
    +   * acosh(Infinity)  = Infinity
    +   * acosh(-Infinity) = NaN
    +   * acosh(0)         = NaN
    +   * acosh(-0)        = NaN
    +   * acosh(1)         = 0
    +   * acosh(-1)        = NaN
    +   *
    +   */
    +  P.inverseHyperbolicCosine = P.acosh = function () {
    +    var pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN);
    +    if (!x.isFinite()) return new Ctor(x);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4;
    +    Ctor.rounding = 1;
    +    external = false;
    +
    +    x = x.times(x).minus(1).sqrt().plus(x);
    +
    +    external = true;
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return x.ln();
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value
    +   * of this Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-Infinity, Infinity]
    +   *
    +   * asinh(x) = ln(x + sqrt(x^2 + 1))
    +   *
    +   * asinh(NaN)       = NaN
    +   * asinh(Infinity)  = Infinity
    +   * asinh(-Infinity) = -Infinity
    +   * asinh(0)         = 0
    +   * asinh(-0)        = -0
    +   *
    +   */
    +  P.inverseHyperbolicSine = P.asinh = function () {
    +    var pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite() || x.isZero()) return new Ctor(x);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6;
    +    Ctor.rounding = 1;
    +    external = false;
    +
    +    x = x.times(x).plus(1).sqrt().plus(x);
    +
    +    external = true;
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return x.ln();
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the
    +   * value of this Decimal.
    +   *
    +   * Domain: [-1, 1]
    +   * Range: [-Infinity, Infinity]
    +   *
    +   * atanh(x) = 0.5 * ln((1 + x) / (1 - x))
    +   *
    +   * atanh(|x| > 1)   = NaN
    +   * atanh(NaN)       = NaN
    +   * atanh(Infinity)  = NaN
    +   * atanh(-Infinity) = NaN
    +   * atanh(0)         = 0
    +   * atanh(-0)        = -0
    +   * atanh(1)         = Infinity
    +   * atanh(-1)        = -Infinity
    +   *
    +   */
    +  P.inverseHyperbolicTangent = P.atanh = function () {
    +    var pr, rm, wpr, xsd,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite()) return new Ctor(NaN);
    +    if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    xsd = x.sd();
    +
    +    if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true);
    +
    +    Ctor.precision = wpr = xsd - x.e;
    +
    +    x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1);
    +
    +    Ctor.precision = pr + 4;
    +    Ctor.rounding = 1;
    +
    +    x = x.ln();
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return x.times(0.5);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this
    +   * Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-pi/2, pi/2]
    +   *
    +   * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2)))
    +   *
    +   * asin(0)       = 0
    +   * asin(-0)      = -0
    +   * asin(1/2)     = pi/6
    +   * asin(-1/2)    = -pi/6
    +   * asin(1)       = pi/2
    +   * asin(-1)      = -pi/2
    +   * asin(|x| > 1) = NaN
    +   * asin(NaN)     = NaN
    +   *
    +   * TODO? Compare performance of Taylor series.
    +   *
    +   */
    +  P.inverseSine = P.asin = function () {
    +    var halfPi, k,
    +      pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (x.isZero()) return new Ctor(x);
    +
    +    k = x.abs().cmp(1);
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +
    +    if (k !== -1) {
    +
    +      // |x| is 1
    +      if (k === 0) {
    +        halfPi = getPi(Ctor, pr + 4, rm).times(0.5);
    +        halfPi.s = x.s;
    +        return halfPi;
    +      }
    +
    +      // |x| > 1 or x is NaN
    +      return new Ctor(NaN);
    +    }
    +
    +    // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6
    +
    +    Ctor.precision = pr + 6;
    +    Ctor.rounding = 1;
    +
    +    x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan();
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return x.times(2);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value
    +   * of this Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-pi/2, pi/2]
    +   *
    +   * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ...
    +   *
    +   * atan(0)         = 0
    +   * atan(-0)        = -0
    +   * atan(1)         = pi/4
    +   * atan(-1)        = -pi/4
    +   * atan(Infinity)  = pi/2
    +   * atan(-Infinity) = -pi/2
    +   * atan(NaN)       = NaN
    +   *
    +   */
    +  P.inverseTangent = P.atan = function () {
    +    var i, j, k, n, px, t, r, wpr, x2,
    +      x = this,
    +      Ctor = x.constructor,
    +      pr = Ctor.precision,
    +      rm = Ctor.rounding;
    +
    +    if (!x.isFinite()) {
    +      if (!x.s) return new Ctor(NaN);
    +      if (pr + 4 <= PI_PRECISION) {
    +        r = getPi(Ctor, pr + 4, rm).times(0.5);
    +        r.s = x.s;
    +        return r;
    +      }
    +    } else if (x.isZero()) {
    +      return new Ctor(x);
    +    } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) {
    +      r = getPi(Ctor, pr + 4, rm).times(0.25);
    +      r.s = x.s;
    +      return r;
    +    }
    +
    +    Ctor.precision = wpr = pr + 10;
    +    Ctor.rounding = 1;
    +
    +    // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x);
    +
    +    // Argument reduction
    +    // Ensure |x| < 0.42
    +    // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2)))
    +
    +    k = Math.min(28, wpr / LOG_BASE + 2 | 0);
    +
    +    for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1));
    +
    +    external = false;
    +
    +    j = Math.ceil(wpr / LOG_BASE);
    +    n = 1;
    +    x2 = x.times(x);
    +    r = new Ctor(x);
    +    px = x;
    +
    +    // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ...
    +    for (; i !== -1;) {
    +      px = px.times(x2);
    +      t = r.minus(px.div(n += 2));
    +
    +      px = px.times(x2);
    +      r = t.plus(px.div(n += 2));
    +
    +      if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;);
    +    }
    +
    +    if (k) r = r.times(2 << (k - 1));
    +
    +    external = true;
    +
    +    return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true);
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is a finite number, otherwise return false.
    +   *
    +   */
    +  P.isFinite = function () {
    +    return !!this.d;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is an integer, otherwise return false.
    +   *
    +   */
    +  P.isInteger = P.isInt = function () {
    +    return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is NaN, otherwise return false.
    +   *
    +   */
    +  P.isNaN = function () {
    +    return !this.s;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is negative, otherwise return false.
    +   *
    +   */
    +  P.isNegative = P.isNeg = function () {
    +    return this.s < 0;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is positive, otherwise return false.
    +   *
    +   */
    +  P.isPositive = P.isPos = function () {
    +    return this.s > 0;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is 0 or -0, otherwise return false.
    +   *
    +   */
    +  P.isZero = function () {
    +    return !!this.d && this.d[0] === 0;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is less than `y`, otherwise return false.
    +   *
    +   */
    +  P.lessThan = P.lt = function (y) {
    +    return this.cmp(y) < 0;
    +  };
    +
    +
    +  /*
    +   * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false.
    +   *
    +   */
    +  P.lessThanOrEqualTo = P.lte = function (y) {
    +    return this.cmp(y) < 1;
    +  };
    +
    +
    +  /*
    +   * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * If no base is specified, return log[10](arg).
    +   *
    +   * log[base](arg) = ln(arg) / ln(base)
    +   *
    +   * The result will always be correctly rounded if the base of the log is 10, and 'almost always'
    +   * otherwise:
    +   *
    +   * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen
    +   * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error
    +   * between the result and the correctly rounded result will be one ulp (unit in the last place).
    +   *
    +   * log[-b](a)       = NaN
    +   * log[0](a)        = NaN
    +   * log[1](a)        = NaN
    +   * log[NaN](a)      = NaN
    +   * log[Infinity](a) = NaN
    +   * log[b](0)        = -Infinity
    +   * log[b](-0)       = -Infinity
    +   * log[b](-a)       = NaN
    +   * log[b](1)        = 0
    +   * log[b](Infinity) = Infinity
    +   * log[b](NaN)      = NaN
    +   *
    +   * [base] {number|string|Decimal} The base of the logarithm.
    +   *
    +   */
    +  P.logarithm = P.log = function (base) {
    +    var isBase10, d, denominator, k, inf, num, sd, r,
    +      arg = this,
    +      Ctor = arg.constructor,
    +      pr = Ctor.precision,
    +      rm = Ctor.rounding,
    +      guard = 5;
    +
    +    // Default base is 10.
    +    if (base == null) {
    +      base = new Ctor(10);
    +      isBase10 = true;
    +    } else {
    +      base = new Ctor(base);
    +      d = base.d;
    +
    +      // Return NaN if base is negative, or non-finite, or is 0 or 1.
    +      if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN);
    +
    +      isBase10 = base.eq(10);
    +    }
    +
    +    d = arg.d;
    +
    +    // Is arg negative, non-finite, 0 or 1?
    +    if (arg.s < 0 || !d || !d[0] || arg.eq(1)) {
    +      return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0);
    +    }
    +
    +    // The result will have a non-terminating decimal expansion if base is 10 and arg is not an
    +    // integer power of 10.
    +    if (isBase10) {
    +      if (d.length > 1) {
    +        inf = true;
    +      } else {
    +        for (k = d[0]; k % 10 === 0;) k /= 10;
    +        inf = k !== 1;
    +      }
    +    }
    +
    +    external = false;
    +    sd = pr + guard;
    +    num = naturalLogarithm(arg, sd);
    +    denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd);
    +
    +    // The result will have 5 rounding digits.
    +    r = divide(num, denominator, sd, 1);
    +
    +    // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000,
    +    // calculate 10 further digits.
    +    //
    +    // If the result is known to have an infinite decimal expansion, repeat this until it is clear
    +    // that the result is above or below the boundary. Otherwise, if after calculating the 10
    +    // further digits, the last 14 are nines, round up and assume the result is exact.
    +    // Also assume the result is exact if the last 14 are zero.
    +    //
    +    // Example of a result that will be incorrectly rounded:
    +    // log[1048576](4503599627370502) = 2.60000000000000009610279511444746...
    +    // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it
    +    // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so
    +    // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal
    +    // place is still 2.6.
    +    if (checkRoundingDigits(r.d, k = pr, rm)) {
    +
    +      do {
    +        sd += 10;
    +        num = naturalLogarithm(arg, sd);
    +        denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd);
    +        r = divide(num, denominator, sd, 1);
    +
    +        if (!inf) {
    +
    +          // Check for 14 nines from the 2nd rounding digit, as the first may be 4.
    +          if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) {
    +            r = finalise(r, pr + 1, 0);
    +          }
    +
    +          break;
    +        }
    +      } while (checkRoundingDigits(r.d, k += 10, rm));
    +    }
    +
    +    external = true;
    +
    +    return finalise(r, pr, rm);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal.
    +   *
    +   * arguments {number|string|Decimal}
    +   *
    +  P.max = function () {
    +    Array.prototype.push.call(arguments, this);
    +    return maxOrMin(this.constructor, arguments, 'lt');
    +  };
    +   */
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal.
    +   *
    +   * arguments {number|string|Decimal}
    +   *
    +  P.min = function () {
    +    Array.prototype.push.call(arguments, this);
    +    return maxOrMin(this.constructor, arguments, 'gt');
    +  };
    +   */
    +
    +
    +  /*
    +   *  n - 0 = n
    +   *  n - N = N
    +   *  n - I = -I
    +   *  0 - n = -n
    +   *  0 - 0 = 0
    +   *  0 - N = N
    +   *  0 - I = -I
    +   *  N - n = N
    +   *  N - 0 = N
    +   *  N - N = N
    +   *  N - I = N
    +   *  I - n = I
    +   *  I - 0 = I
    +   *  I - N = N
    +   *  I - I = N
    +   *
    +   * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.minus = P.sub = function (y) {
    +    var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    y = new Ctor(y);
    +
    +    // If either is not finite...
    +    if (!x.d || !y.d) {
    +
    +      // Return NaN if either is NaN.
    +      if (!x.s || !y.s) y = new Ctor(NaN);
    +
    +      // Return y negated if x is finite and y is ±Infinity.
    +      else if (x.d) y.s = -y.s;
    +
    +      // Return x if y is finite and x is ±Infinity.
    +      // Return x if both are ±Infinity with different signs.
    +      // Return NaN if both are ±Infinity with the same sign.
    +      else y = new Ctor(y.d || x.s !== y.s ? x : NaN);
    +
    +      return y;
    +    }
    +
    +    // If signs differ...
    +    if (x.s != y.s) {
    +      y.s = -y.s;
    +      return x.plus(y);
    +    }
    +
    +    xd = x.d;
    +    yd = y.d;
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +
    +    // If either is zero...
    +    if (!xd[0] || !yd[0]) {
    +
    +      // Return y negated if x is zero and y is non-zero.
    +      if (yd[0]) y.s = -y.s;
    +
    +      // Return x if y is zero and x is non-zero.
    +      else if (xd[0]) y = new Ctor(x);
    +
    +      // Return zero if both are zero.
    +      // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity.
    +      else return new Ctor(rm === 3 ? -0 : 0);
    +
    +      return external ? finalise(y, pr, rm) : y;
    +    }
    +
    +    // x and y are finite, non-zero numbers with the same sign.
    +
    +    // Calculate base 1e7 exponents.
    +    e = mathfloor(y.e / LOG_BASE);
    +    xe = mathfloor(x.e / LOG_BASE);
    +
    +    xd = xd.slice();
    +    k = xe - e;
    +
    +    // If base 1e7 exponents differ...
    +    if (k) {
    +      xLTy = k < 0;
    +
    +      if (xLTy) {
    +        d = xd;
    +        k = -k;
    +        len = yd.length;
    +      } else {
    +        d = yd;
    +        e = xe;
    +        len = xd.length;
    +      }
    +
    +      // Numbers with massively different exponents would result in a very high number of
    +      // zeros needing to be prepended, but this can be avoided while still ensuring correct
    +      // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`.
    +      i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2;
    +
    +      if (k > i) {
    +        k = i;
    +        d.length = 1;
    +      }
    +
    +      // Prepend zeros to equalise exponents.
    +      d.reverse();
    +      for (i = k; i--;) d.push(0);
    +      d.reverse();
    +
    +    // Base 1e7 exponents equal.
    +    } else {
    +
    +      // Check digits to determine which is the bigger number.
    +
    +      i = xd.length;
    +      len = yd.length;
    +      xLTy = i < len;
    +      if (xLTy) len = i;
    +
    +      for (i = 0; i < len; i++) {
    +        if (xd[i] != yd[i]) {
    +          xLTy = xd[i] < yd[i];
    +          break;
    +        }
    +      }
    +
    +      k = 0;
    +    }
    +
    +    if (xLTy) {
    +      d = xd;
    +      xd = yd;
    +      yd = d;
    +      y.s = -y.s;
    +    }
    +
    +    len = xd.length;
    +
    +    // Append zeros to `xd` if shorter.
    +    // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length.
    +    for (i = yd.length - len; i > 0; --i) xd[len++] = 0;
    +
    +    // Subtract yd from xd.
    +    for (i = yd.length; i > k;) {
    +
    +      if (xd[--i] < yd[i]) {
    +        for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1;
    +        --xd[j];
    +        xd[i] += BASE;
    +      }
    +
    +      xd[i] -= yd[i];
    +    }
    +
    +    // Remove trailing zeros.
    +    for (; xd[--len] === 0;) xd.pop();
    +
    +    // Remove leading zeros and adjust exponent accordingly.
    +    for (; xd[0] === 0; xd.shift()) --e;
    +
    +    // Zero?
    +    if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0);
    +
    +    y.d = xd;
    +    y.e = getBase10Exponent(xd, e);
    +
    +    return external ? finalise(y, pr, rm) : y;
    +  };
    +
    +
    +  /*
    +   *   n % 0 =  N
    +   *   n % N =  N
    +   *   n % I =  n
    +   *   0 % n =  0
    +   *  -0 % n = -0
    +   *   0 % 0 =  N
    +   *   0 % N =  N
    +   *   0 % I =  0
    +   *   N % n =  N
    +   *   N % 0 =  N
    +   *   N % N =  N
    +   *   N % I =  N
    +   *   I % n =  N
    +   *   I % 0 =  N
    +   *   I % N =  N
    +   *   I % I =  N
    +   *
    +   * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to
    +   * `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * The result depends on the modulo mode.
    +   *
    +   */
    +  P.modulo = P.mod = function (y) {
    +    var q,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    y = new Ctor(y);
    +
    +    // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0.
    +    if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN);
    +
    +    // Return x if y is ±Infinity or x is ±0.
    +    if (!y.d || x.d && !x.d[0]) {
    +      return finalise(new Ctor(x), Ctor.precision, Ctor.rounding);
    +    }
    +
    +    // Prevent rounding of intermediate calculations.
    +    external = false;
    +
    +    if (Ctor.modulo == 9) {
    +
    +      // Euclidian division: q = sign(y) * floor(x / abs(y))
    +      // result = x - q * y    where  0 <= result < abs(y)
    +      q = divide(x, y.abs(), 0, 3, 1);
    +      q.s *= y.s;
    +    } else {
    +      q = divide(x, y, 0, Ctor.modulo, 1);
    +    }
    +
    +    q = q.times(y);
    +
    +    external = true;
    +
    +    return x.minus(q);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the natural exponential of the value of this Decimal,
    +   * i.e. the base e raised to the power the value of this Decimal, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.naturalExponential = P.exp = function () {
    +    return naturalExponential(this);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the natural logarithm of the value of this Decimal,
    +   * rounded to `precision` significant digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.naturalLogarithm = P.ln = function () {
    +    return naturalLogarithm(this);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by
    +   * -1.
    +   *
    +   */
    +  P.negated = P.neg = function () {
    +    var x = new this.constructor(this);
    +    x.s = -x.s;
    +    return finalise(x);
    +  };
    +
    +
    +  /*
    +   *  n + 0 = n
    +   *  n + N = N
    +   *  n + I = I
    +   *  0 + n = n
    +   *  0 + 0 = 0
    +   *  0 + N = N
    +   *  0 + I = I
    +   *  N + n = N
    +   *  N + 0 = N
    +   *  N + N = N
    +   *  N + I = N
    +   *  I + n = I
    +   *  I + 0 = I
    +   *  I + N = N
    +   *  I + I = I
    +   *
    +   * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.plus = P.add = function (y) {
    +    var carry, d, e, i, k, len, pr, rm, xd, yd,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    y = new Ctor(y);
    +
    +    // If either is not finite...
    +    if (!x.d || !y.d) {
    +
    +      // Return NaN if either is NaN.
    +      if (!x.s || !y.s) y = new Ctor(NaN);
    +
    +      // Return x if y is finite and x is ±Infinity.
    +      // Return x if both are ±Infinity with the same sign.
    +      // Return NaN if both are ±Infinity with different signs.
    +      // Return y if x is finite and y is ±Infinity.
    +      else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN);
    +
    +      return y;
    +    }
    +
    +     // If signs differ...
    +    if (x.s != y.s) {
    +      y.s = -y.s;
    +      return x.minus(y);
    +    }
    +
    +    xd = x.d;
    +    yd = y.d;
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +
    +    // If either is zero...
    +    if (!xd[0] || !yd[0]) {
    +
    +      // Return x if y is zero.
    +      // Return y if y is non-zero.
    +      if (!yd[0]) y = new Ctor(x);
    +
    +      return external ? finalise(y, pr, rm) : y;
    +    }
    +
    +    // x and y are finite, non-zero numbers with the same sign.
    +
    +    // Calculate base 1e7 exponents.
    +    k = mathfloor(x.e / LOG_BASE);
    +    e = mathfloor(y.e / LOG_BASE);
    +
    +    xd = xd.slice();
    +    i = k - e;
    +
    +    // If base 1e7 exponents differ...
    +    if (i) {
    +
    +      if (i < 0) {
    +        d = xd;
    +        i = -i;
    +        len = yd.length;
    +      } else {
    +        d = yd;
    +        e = k;
    +        len = xd.length;
    +      }
    +
    +      // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1.
    +      k = Math.ceil(pr / LOG_BASE);
    +      len = k > len ? k + 1 : len + 1;
    +
    +      if (i > len) {
    +        i = len;
    +        d.length = 1;
    +      }
    +
    +      // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts.
    +      d.reverse();
    +      for (; i--;) d.push(0);
    +      d.reverse();
    +    }
    +
    +    len = xd.length;
    +    i = yd.length;
    +
    +    // If yd is longer than xd, swap xd and yd so xd points to the longer array.
    +    if (len - i < 0) {
    +      i = len;
    +      d = yd;
    +      yd = xd;
    +      xd = d;
    +    }
    +
    +    // Only start adding at yd.length - 1 as the further digits of xd can be left as they are.
    +    for (carry = 0; i;) {
    +      carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0;
    +      xd[i] %= BASE;
    +    }
    +
    +    if (carry) {
    +      xd.unshift(carry);
    +      ++e;
    +    }
    +
    +    // Remove trailing zeros.
    +    // No need to check for zero, as +x + +y != 0 && -x + -y != 0
    +    for (len = xd.length; xd[--len] == 0;) xd.pop();
    +
    +    y.d = xd;
    +    y.e = getBase10Exponent(xd, e);
    +
    +    return external ? finalise(y, pr, rm) : y;
    +  };
    +
    +
    +  /*
    +   * Return the number of significant digits of the value of this Decimal.
    +   *
    +   * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.
    +   *
    +   */
    +  P.precision = P.sd = function (z) {
    +    var k,
    +      x = this;
    +
    +    if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z);
    +
    +    if (x.d) {
    +      k = getPrecision(x.d);
    +      if (z && x.e + 1 > k) k = x.e + 1;
    +    } else {
    +      k = NaN;
    +    }
    +
    +    return k;
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using
    +   * rounding mode `rounding`.
    +   *
    +   */
    +  P.round = function () {
    +    var x = this,
    +      Ctor = x.constructor;
    +
    +    return finalise(new Ctor(x), x.e + 1, Ctor.rounding);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the sine of the value in radians of this Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-1, 1]
    +   *
    +   * sin(x) = x - x^3/3! + x^5/5! - ...
    +   *
    +   * sin(0)         = 0
    +   * sin(-0)        = -0
    +   * sin(Infinity)  = NaN
    +   * sin(-Infinity) = NaN
    +   * sin(NaN)       = NaN
    +   *
    +   */
    +  P.sine = P.sin = function () {
    +    var pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite()) return new Ctor(NaN);
    +    if (x.isZero()) return new Ctor(x);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE;
    +    Ctor.rounding = 1;
    +
    +    x = sine(Ctor, toLessThanHalfPi(Ctor, x));
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   *  sqrt(-n) =  N
    +   *  sqrt(N)  =  N
    +   *  sqrt(-I) =  N
    +   *  sqrt(I)  =  I
    +   *  sqrt(0)  =  0
    +   *  sqrt(-0) = -0
    +   *
    +   */
    +  P.squareRoot = P.sqrt = function () {
    +    var m, n, sd, r, rep, t,
    +      x = this,
    +      d = x.d,
    +      e = x.e,
    +      s = x.s,
    +      Ctor = x.constructor;
    +
    +    // Negative/NaN/Infinity/zero?
    +    if (s !== 1 || !d || !d[0]) {
    +      return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0);
    +    }
    +
    +    external = false;
    +
    +    // Initial estimate.
    +    s = Math.sqrt(+x);
    +
    +    // Math.sqrt underflow/overflow?
    +    // Pass x to Math.sqrt as integer, then adjust the exponent of the result.
    +    if (s == 0 || s == 1 / 0) {
    +      n = digitsToString(d);
    +
    +      if ((n.length + e) % 2 == 0) n += '0';
    +      s = Math.sqrt(n);
    +      e = mathfloor((e + 1) / 2) - (e < 0 || e % 2);
    +
    +      if (s == 1 / 0) {
    +        n = '5e' + e;
    +      } else {
    +        n = s.toExponential();
    +        n = n.slice(0, n.indexOf('e') + 1) + e;
    +      }
    +
    +      r = new Ctor(n);
    +    } else {
    +      r = new Ctor(s.toString());
    +    }
    +
    +    sd = (e = Ctor.precision) + 3;
    +
    +    // Newton-Raphson iteration.
    +    for (;;) {
    +      t = r;
    +      r = t.plus(divide(x, t, sd + 2, 1)).times(0.5);
    +
    +      // TODO? Replace with for-loop and checkRoundingDigits.
    +      if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) {
    +        n = n.slice(sd - 3, sd + 1);
    +
    +        // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or
    +        // 4999, i.e. approaching a rounding boundary, continue the iteration.
    +        if (n == '9999' || !rep && n == '4999') {
    +
    +          // On the first iteration only, check to see if rounding up gives the exact result as the
    +          // nines may infinitely repeat.
    +          if (!rep) {
    +            finalise(t, e + 1, 0);
    +
    +            if (t.times(t).eq(x)) {
    +              r = t;
    +              break;
    +            }
    +          }
    +
    +          sd += 4;
    +          rep = 1;
    +        } else {
    +
    +          // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result.
    +          // If not, then there are further digits and m will be truthy.
    +          if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
    +
    +            // Truncate to the first rounding digit.
    +            finalise(r, e + 1, 1);
    +            m = !r.times(r).eq(x);
    +          }
    +
    +          break;
    +        }
    +      }
    +    }
    +
    +    external = true;
    +
    +    return finalise(r, e, Ctor.rounding, m);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the tangent of the value in radians of this Decimal.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-Infinity, Infinity]
    +   *
    +   * tan(0)         = 0
    +   * tan(-0)        = -0
    +   * tan(Infinity)  = NaN
    +   * tan(-Infinity) = NaN
    +   * tan(NaN)       = NaN
    +   *
    +   */
    +  P.tangent = P.tan = function () {
    +    var pr, rm,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (!x.isFinite()) return new Ctor(NaN);
    +    if (x.isZero()) return new Ctor(x);
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +    Ctor.precision = pr + 10;
    +    Ctor.rounding = 1;
    +
    +    x = x.sin();
    +    x.s = 1;
    +    x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0);
    +
    +    Ctor.precision = pr;
    +    Ctor.rounding = rm;
    +
    +    return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true);
    +  };
    +
    +
    +  /*
    +   *  n * 0 = 0
    +   *  n * N = N
    +   *  n * I = I
    +   *  0 * n = 0
    +   *  0 * 0 = 0
    +   *  0 * N = N
    +   *  0 * I = N
    +   *  N * n = N
    +   *  N * 0 = N
    +   *  N * N = N
    +   *  N * I = N
    +   *  I * n = I
    +   *  I * 0 = N
    +   *  I * N = N
    +   *  I * I = I
    +   *
    +   * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   */
    +  P.times = P.mul = function (y) {
    +    var carry, e, i, k, r, rL, t, xdL, ydL,
    +      x = this,
    +      Ctor = x.constructor,
    +      xd = x.d,
    +      yd = (y = new Ctor(y)).d;
    +
    +    y.s *= x.s;
    +
    +     // If either is NaN, ±Infinity or ±0...
    +    if (!xd || !xd[0] || !yd || !yd[0]) {
    +
    +      return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd
    +
    +        // Return NaN if either is NaN.
    +        // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity.
    +        ? NaN
    +
    +        // Return ±Infinity if either is ±Infinity.
    +        // Return ±0 if either is ±0.
    +        : !xd || !yd ? y.s / 0 : y.s * 0);
    +    }
    +
    +    e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE);
    +    xdL = xd.length;
    +    ydL = yd.length;
    +
    +    // Ensure xd points to the longer array.
    +    if (xdL < ydL) {
    +      r = xd;
    +      xd = yd;
    +      yd = r;
    +      rL = xdL;
    +      xdL = ydL;
    +      ydL = rL;
    +    }
    +
    +    // Initialise the result array with zeros.
    +    r = [];
    +    rL = xdL + ydL;
    +    for (i = rL; i--;) r.push(0);
    +
    +    // Multiply!
    +    for (i = ydL; --i >= 0;) {
    +      carry = 0;
    +      for (k = xdL + i; k > i;) {
    +        t = r[k] + yd[i] * xd[k - i - 1] + carry;
    +        r[k--] = t % BASE | 0;
    +        carry = t / BASE | 0;
    +      }
    +
    +      r[k] = (r[k] + carry) % BASE | 0;
    +    }
    +
    +    // Remove trailing zeros.
    +    for (; !r[--rL];) r.pop();
    +
    +    if (carry) ++e;
    +    else r.shift();
    +
    +    y.d = r;
    +    y.e = getBase10Exponent(r, e);
    +
    +    return external ? finalise(y, Ctor.precision, Ctor.rounding) : y;
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal in base 2, round to `sd` significant
    +   * digits using rounding mode `rm`.
    +   *
    +   * If the optional `sd` argument is present then return binary exponential notation.
    +   *
    +   * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   */
    +  P.toBinary = function (sd, rm) {
    +    return toStringBinary(this, 2, sd, rm);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp`
    +   * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted.
    +   *
    +   * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal.
    +   *
    +   * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   */
    +  P.toDecimalPlaces = P.toDP = function (dp, rm) {
    +    var x = this,
    +      Ctor = x.constructor;
    +
    +    x = new Ctor(x);
    +    if (dp === void 0) return x;
    +
    +    checkInt32(dp, 0, MAX_DIGITS);
    +
    +    if (rm === void 0) rm = Ctor.rounding;
    +    else checkInt32(rm, 0, 8);
    +
    +    return finalise(x, dp + x.e + 1, rm);
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal in exponential notation rounded to
    +   * `dp` fixed decimal places using rounding mode `rounding`.
    +   *
    +   * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   */
    +  P.toExponential = function (dp, rm) {
    +    var str,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (dp === void 0) {
    +      str = finiteToString(x, true);
    +    } else {
    +      checkInt32(dp, 0, MAX_DIGITS);
    +
    +      if (rm === void 0) rm = Ctor.rounding;
    +      else checkInt32(rm, 0, 8);
    +
    +      x = finalise(new Ctor(x), dp + 1, rm);
    +      str = finiteToString(x, true, dp + 1);
    +    }
    +
    +    return x.isNeg() && !x.isZero() ? '-' + str : str;
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal in normal (fixed-point) notation to
    +   * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is
    +   * omitted.
    +   *
    +   * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.
    +   *
    +   * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.
    +   * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.
    +   * (-0).toFixed(3) is '0.000'.
    +   * (-0.5).toFixed(0) is '-0'.
    +   *
    +   */
    +  P.toFixed = function (dp, rm) {
    +    var str, y,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (dp === void 0) {
    +      str = finiteToString(x);
    +    } else {
    +      checkInt32(dp, 0, MAX_DIGITS);
    +
    +      if (rm === void 0) rm = Ctor.rounding;
    +      else checkInt32(rm, 0, 8);
    +
    +      y = finalise(new Ctor(x), dp + x.e + 1, rm);
    +      str = finiteToString(y, false, dp + y.e + 1);
    +    }
    +
    +    // To determine whether to add the minus sign look at the value before it was rounded,
    +    // i.e. look at `x` rather than `y`.
    +    return x.isNeg() && !x.isZero() ? '-' + str : str;
    +  };
    +
    +
    +  /*
    +   * Return an array representing the value of this Decimal as a simple fraction with an integer
    +   * numerator and an integer denominator.
    +   *
    +   * The denominator will be a positive non-zero value less than or equal to the specified maximum
    +   * denominator. If a maximum denominator is not specified, the denominator will be the lowest
    +   * value necessary to represent the number exactly.
    +   *
    +   * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity.
    +   *
    +   */
    +  P.toFraction = function (maxD) {
    +    var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r,
    +      x = this,
    +      xd = x.d,
    +      Ctor = x.constructor;
    +
    +    if (!xd) return new Ctor(x);
    +
    +    n1 = d0 = new Ctor(1);
    +    d1 = n0 = new Ctor(0);
    +
    +    d = new Ctor(d1);
    +    e = d.e = getPrecision(xd) - x.e - 1;
    +    k = e % LOG_BASE;
    +    d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k);
    +
    +    if (maxD == null) {
    +
    +      // d is 10**e, the minimum max-denominator needed.
    +      maxD = e > 0 ? d : n1;
    +    } else {
    +      n = new Ctor(maxD);
    +      if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n);
    +      maxD = n.gt(d) ? (e > 0 ? d : n1) : n;
    +    }
    +
    +    external = false;
    +    n = new Ctor(digitsToString(xd));
    +    pr = Ctor.precision;
    +    Ctor.precision = e = xd.length * LOG_BASE * 2;
    +
    +    for (;;)  {
    +      q = divide(n, d, 0, 1, 1);
    +      d2 = d0.plus(q.times(d1));
    +      if (d2.cmp(maxD) == 1) break;
    +      d0 = d1;
    +      d1 = d2;
    +      d2 = n1;
    +      n1 = n0.plus(q.times(d2));
    +      n0 = d2;
    +      d2 = d;
    +      d = n.minus(q.times(d2));
    +      n = d2;
    +    }
    +
    +    d2 = divide(maxD.minus(d0), d1, 0, 1, 1);
    +    n0 = n0.plus(d2.times(n1));
    +    d0 = d0.plus(d2.times(d1));
    +    n0.s = n1.s = x.s;
    +
    +    // Determine which fraction is closer to x, n0/d0 or n1/d1?
    +    r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1
    +        ? [n1, d1] : [n0, d0];
    +
    +    Ctor.precision = pr;
    +    external = true;
    +
    +    return r;
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal in base 16, round to `sd` significant
    +   * digits using rounding mode `rm`.
    +   *
    +   * If the optional `sd` argument is present then return binary exponential notation.
    +   *
    +   * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   */
    +  P.toHexadecimal = P.toHex = function (sd, rm) {
    +    return toStringBinary(this, 16, sd, rm);
    +  };
    +
    +
    +  /*
    +   * Returns a new Decimal whose value is the nearest multiple of `y` in the direction of rounding
    +   * mode `rm`, or `Decimal.rounding` if `rm` is omitted, to the value of this Decimal.
    +   *
    +   * The return value will always have the same sign as this Decimal, unless either this Decimal
    +   * or `y` is NaN, in which case the return value will be also be NaN.
    +   *
    +   * The return value is not affected by the value of `precision`.
    +   *
    +   * y {number|string|Decimal} The magnitude to round to a multiple of.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   * 'toNearest() rounding mode not an integer: {rm}'
    +   * 'toNearest() rounding mode out of range: {rm}'
    +   *
    +   */
    +  P.toNearest = function (y, rm) {
    +    var x = this,
    +      Ctor = x.constructor;
    +
    +    x = new Ctor(x);
    +
    +    if (y == null) {
    +
    +      // If x is not finite, return x.
    +      if (!x.d) return x;
    +
    +      y = new Ctor(1);
    +      rm = Ctor.rounding;
    +    } else {
    +      y = new Ctor(y);
    +      if (rm === void 0) {
    +        rm = Ctor.rounding;
    +      } else {
    +        checkInt32(rm, 0, 8);
    +      }
    +
    +      // If x is not finite, return x if y is not NaN, else NaN.
    +      if (!x.d) return y.s ? x : y;
    +
    +      // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN.
    +      if (!y.d) {
    +        if (y.s) y.s = x.s;
    +        return y;
    +      }
    +    }
    +
    +    // If y is not zero, calculate the nearest multiple of y to x.
    +    if (y.d[0]) {
    +      external = false;
    +      x = divide(x, y, 0, rm, 1).times(y);
    +      external = true;
    +      finalise(x);
    +
    +    // If y is zero, return zero with the sign of x.
    +    } else {
    +      y.s = x.s;
    +      x = y;
    +    }
    +
    +    return x;
    +  };
    +
    +
    +  /*
    +   * Return the value of this Decimal converted to a number primitive.
    +   * Zero keeps its sign.
    +   *
    +   */
    +  P.toNumber = function () {
    +    return +this;
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal in base 8, round to `sd` significant
    +   * digits using rounding mode `rm`.
    +   *
    +   * If the optional `sd` argument is present then return binary exponential notation.
    +   *
    +   * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   */
    +  P.toOctal = function (sd, rm) {
    +    return toStringBinary(this, 8, sd, rm);
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded
    +   * to `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * ECMAScript compliant.
    +   *
    +   *   pow(x, NaN)                           = NaN
    +   *   pow(x, ±0)                            = 1
    +
    +   *   pow(NaN, non-zero)                    = NaN
    +   *   pow(abs(x) > 1, +Infinity)            = +Infinity
    +   *   pow(abs(x) > 1, -Infinity)            = +0
    +   *   pow(abs(x) == 1, ±Infinity)           = NaN
    +   *   pow(abs(x) < 1, +Infinity)            = +0
    +   *   pow(abs(x) < 1, -Infinity)            = +Infinity
    +   *   pow(+Infinity, y > 0)                 = +Infinity
    +   *   pow(+Infinity, y < 0)                 = +0
    +   *   pow(-Infinity, odd integer > 0)       = -Infinity
    +   *   pow(-Infinity, even integer > 0)      = +Infinity
    +   *   pow(-Infinity, odd integer < 0)       = -0
    +   *   pow(-Infinity, even integer < 0)      = +0
    +   *   pow(+0, y > 0)                        = +0
    +   *   pow(+0, y < 0)                        = +Infinity
    +   *   pow(-0, odd integer > 0)              = -0
    +   *   pow(-0, even integer > 0)             = +0
    +   *   pow(-0, odd integer < 0)              = -Infinity
    +   *   pow(-0, even integer < 0)             = +Infinity
    +   *   pow(finite x < 0, finite non-integer) = NaN
    +   *
    +   * For non-integer or very large exponents pow(x, y) is calculated using
    +   *
    +   *   x^y = exp(y*ln(x))
    +   *
    +   * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the
    +   * probability of an incorrectly rounded result
    +   * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14
    +   * i.e. 1 in 250,000,000,000,000
    +   *
    +   * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place).
    +   *
    +   * y {number|string|Decimal} The power to which to raise this Decimal.
    +   *
    +   */
    +  P.toPower = P.pow = function (y) {
    +    var e, k, pr, r, rm, s,
    +      x = this,
    +      Ctor = x.constructor,
    +      yn = +(y = new Ctor(y));
    +
    +    // Either ±Infinity, NaN or ±0?
    +    if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn));
    +
    +    x = new Ctor(x);
    +
    +    if (x.eq(1)) return x;
    +
    +    pr = Ctor.precision;
    +    rm = Ctor.rounding;
    +
    +    if (y.eq(1)) return finalise(x, pr, rm);
    +
    +    // y exponent
    +    e = mathfloor(y.e / LOG_BASE);
    +
    +    // If y is a small integer use the 'exponentiation by squaring' algorithm.
    +    if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) {
    +      r = intPow(Ctor, x, k, pr);
    +      return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm);
    +    }
    +
    +    s = x.s;
    +
    +    // if x is negative
    +    if (s < 0) {
    +
    +      // if y is not an integer
    +      if (e < y.d.length - 1) return new Ctor(NaN);
    +
    +      // Result is positive if x is negative and the last digit of integer y is even.
    +      if ((y.d[e] & 1) == 0) s = 1;
    +
    +      // if x.eq(-1)
    +      if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) {
    +        x.s = s;
    +        return x;
    +      }
    +    }
    +
    +    // Estimate result exponent.
    +    // x^y = 10^e,  where e = y * log10(x)
    +    // log10(x) = log10(x_significand) + x_exponent
    +    // log10(x_significand) = ln(x_significand) / ln(10)
    +    k = mathpow(+x, yn);
    +    e = k == 0 || !isFinite(k)
    +      ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1))
    +      : new Ctor(k + '').e;
    +
    +    // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1.
    +
    +    // Overflow/underflow?
    +    if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0);
    +
    +    external = false;
    +    Ctor.rounding = x.s = 1;
    +
    +    // Estimate the extra guard digits needed to ensure five correct rounding digits from
    +    // naturalLogarithm(x). Example of failure without these extra digits (precision: 10):
    +    // new Decimal(2.32456).pow('2087987436534566.46411')
    +    // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815
    +    k = Math.min(12, (e + '').length);
    +
    +    // r = x^y = exp(y*ln(x))
    +    r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr);
    +
    +    // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40)
    +    if (r.d) {
    +
    +      // Truncate to the required precision plus five rounding digits.
    +      r = finalise(r, pr + 5, 1);
    +
    +      // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate
    +      // the result.
    +      if (checkRoundingDigits(r.d, pr, rm)) {
    +        e = pr + 10;
    +
    +        // Truncate to the increased precision plus five rounding digits.
    +        r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1);
    +
    +        // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9).
    +        if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) {
    +          r = finalise(r, pr + 1, 0);
    +        }
    +      }
    +    }
    +
    +    r.s = s;
    +    external = true;
    +    Ctor.rounding = rm;
    +
    +    return finalise(r, pr, rm);
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal rounded to `sd` significant digits
    +   * using rounding mode `rounding`.
    +   *
    +   * Return exponential notation if `sd` is less than the number of digits necessary to represent
    +   * the integer part of the value in normal notation.
    +   *
    +   * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   */
    +  P.toPrecision = function (sd, rm) {
    +    var str,
    +      x = this,
    +      Ctor = x.constructor;
    +
    +    if (sd === void 0) {
    +      str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos);
    +    } else {
    +      checkInt32(sd, 1, MAX_DIGITS);
    +
    +      if (rm === void 0) rm = Ctor.rounding;
    +      else checkInt32(rm, 0, 8);
    +
    +      x = finalise(new Ctor(x), sd, rm);
    +      str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd);
    +    }
    +
    +    return x.isNeg() && !x.isZero() ? '-' + str : str;
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd`
    +   * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if
    +   * omitted.
    +   *
    +   * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.
    +   * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
    +   *
    +   * 'toSD() digits out of range: {sd}'
    +   * 'toSD() digits not an integer: {sd}'
    +   * 'toSD() rounding mode not an integer: {rm}'
    +   * 'toSD() rounding mode out of range: {rm}'
    +   *
    +   */
    +  P.toSignificantDigits = P.toSD = function (sd, rm) {
    +    var x = this,
    +      Ctor = x.constructor;
    +
    +    if (sd === void 0) {
    +      sd = Ctor.precision;
    +      rm = Ctor.rounding;
    +    } else {
    +      checkInt32(sd, 1, MAX_DIGITS);
    +
    +      if (rm === void 0) rm = Ctor.rounding;
    +      else checkInt32(rm, 0, 8);
    +    }
    +
    +    return finalise(new Ctor(x), sd, rm);
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal.
    +   *
    +   * Return exponential notation if this Decimal has a positive exponent equal to or greater than
    +   * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`.
    +   *
    +   */
    +  P.toString = function () {
    +    var x = this,
    +      Ctor = x.constructor,
    +      str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos);
    +
    +    return x.isNeg() && !x.isZero() ? '-' + str : str;
    +  };
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of this Decimal truncated to a whole number.
    +   *
    +   */
    +  P.truncated = P.trunc = function () {
    +    return finalise(new this.constructor(this), this.e + 1, 1);
    +  };
    +
    +
    +  /*
    +   * Return a string representing the value of this Decimal.
    +   * Unlike `toString`, negative zero will include the minus sign.
    +   *
    +   */
    +  P.valueOf = P.toJSON = function () {
    +    var x = this,
    +      Ctor = x.constructor,
    +      str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos);
    +
    +    return x.isNeg() ? '-' + str : str;
    +  };
    +
    +
    +  // Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.
    +
    +
    +  /*
    +   *  digitsToString           P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower,
    +   *                           finiteToString, naturalExponential, naturalLogarithm
    +   *  checkInt32               P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest,
    +   *                           P.toPrecision, P.toSignificantDigits, toStringBinary, random
    +   *  checkRoundingDigits      P.logarithm, P.toPower, naturalExponential, naturalLogarithm
    +   *  convertBase              toStringBinary, parseOther
    +   *  cos                      P.cos
    +   *  divide                   P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy,
    +   *                           P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction,
    +   *                           P.toNearest, toStringBinary, naturalExponential, naturalLogarithm,
    +   *                           taylorSeries, atan2, parseOther
    +   *  finalise                 P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh,
    +   *                           P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus,
    +   *                           P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot,
    +   *                           P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed,
    +   *                           P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits,
    +   *                           P.truncated, divide, getLn10, getPi, naturalExponential,
    +   *                           naturalLogarithm, ceil, floor, round, trunc
    +   *  finiteToString           P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf,
    +   *                           toStringBinary
    +   *  getBase10Exponent        P.minus, P.plus, P.times, parseOther
    +   *  getLn10                  P.logarithm, naturalLogarithm
    +   *  getPi                    P.acos, P.asin, P.atan, toLessThanHalfPi, atan2
    +   *  getPrecision             P.precision, P.toFraction
    +   *  getZeroString            digitsToString, finiteToString
    +   *  intPow                   P.toPower, parseOther
    +   *  isOdd                    toLessThanHalfPi
    +   *  maxOrMin                 max, min
    +   *  naturalExponential       P.naturalExponential, P.toPower
    +   *  naturalLogarithm         P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm,
    +   *                           P.toPower, naturalExponential
    +   *  nonFiniteToString        finiteToString, toStringBinary
    +   *  parseDecimal             Decimal
    +   *  parseOther               Decimal
    +   *  sin                      P.sin
    +   *  taylorSeries             P.cosh, P.sinh, cos, sin
    +   *  toLessThanHalfPi         P.cos, P.sin
    +   *  toStringBinary           P.toBinary, P.toHexadecimal, P.toOctal
    +   *  truncate                 intPow
    +   *
    +   *  Throws:                  P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi,
    +   *                           naturalLogarithm, config, parseOther, random, Decimal
    +   */
    +
    +
    +  function digitsToString(d) {
    +    var i, k, ws,
    +      indexOfLastWord = d.length - 1,
    +      str = '',
    +      w = d[0];
    +
    +    if (indexOfLastWord > 0) {
    +      str += w;
    +      for (i = 1; i < indexOfLastWord; i++) {
    +        ws = d[i] + '';
    +        k = LOG_BASE - ws.length;
    +        if (k) str += getZeroString(k);
    +        str += ws;
    +      }
    +
    +      w = d[i];
    +      ws = w + '';
    +      k = LOG_BASE - ws.length;
    +      if (k) str += getZeroString(k);
    +    } else if (w === 0) {
    +      return '0';
    +    }
    +
    +    // Remove trailing zeros of last w.
    +    for (; w % 10 === 0;) w /= 10;
    +
    +    return str + w;
    +  }
    +
    +
    +  function checkInt32(i, min, max) {
    +    if (i !== ~~i || i < min || i > max) {
    +      throw Error(invalidArgument + i);
    +    }
    +  }
    +
    +
    +  /*
    +   * Check 5 rounding digits if `repeating` is null, 4 otherwise.
    +   * `repeating == null` if caller is `log` or `pow`,
    +   * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`.
    +   */
    +  function checkRoundingDigits(d, i, rm, repeating) {
    +    var di, k, r, rd;
    +
    +    // Get the length of the first word of the array d.
    +    for (k = d[0]; k >= 10; k /= 10) --i;
    +
    +    // Is the rounding digit in the first word of d?
    +    if (--i < 0) {
    +      i += LOG_BASE;
    +      di = 0;
    +    } else {
    +      di = Math.ceil((i + 1) / LOG_BASE);
    +      i %= LOG_BASE;
    +    }
    +
    +    // i is the index (0 - 6) of the rounding digit.
    +    // E.g. if within the word 3487563 the first rounding digit is 5,
    +    // then i = 4, k = 1000, rd = 3487563 % 1000 = 563
    +    k = mathpow(10, LOG_BASE - i);
    +    rd = d[di] % k | 0;
    +
    +    if (repeating == null) {
    +      if (i < 3) {
    +        if (i == 0) rd = rd / 100 | 0;
    +        else if (i == 1) rd = rd / 10 | 0;
    +        r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0;
    +      } else {
    +        r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) &&
    +          (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 ||
    +            (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0;
    +      }
    +    } else {
    +      if (i < 4) {
    +        if (i == 0) rd = rd / 1000 | 0;
    +        else if (i == 1) rd = rd / 100 | 0;
    +        else if (i == 2) rd = rd / 10 | 0;
    +        r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999;
    +      } else {
    +        r = ((repeating || rm < 4) && rd + 1 == k ||
    +        (!repeating && rm > 3) && rd + 1 == k / 2) &&
    +          (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1;
    +      }
    +    }
    +
    +    return r;
    +  }
    +
    +
    +  // Convert string of `baseIn` to an array of numbers of `baseOut`.
    +  // Eg. convertBase('255', 10, 16) returns [15, 15].
    +  // Eg. convertBase('ff', 16, 10) returns [2, 5, 5].
    +  function convertBase(str, baseIn, baseOut) {
    +    var j,
    +      arr = [0],
    +      arrL,
    +      i = 0,
    +      strL = str.length;
    +
    +    for (; i < strL;) {
    +      for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn;
    +      arr[0] += NUMERALS.indexOf(str.charAt(i++));
    +      for (j = 0; j < arr.length; j++) {
    +        if (arr[j] > baseOut - 1) {
    +          if (arr[j + 1] === void 0) arr[j + 1] = 0;
    +          arr[j + 1] += arr[j] / baseOut | 0;
    +          arr[j] %= baseOut;
    +        }
    +      }
    +    }
    +
    +    return arr.reverse();
    +  }
    +
    +
    +  /*
    +   * cos(x) = 1 - x^2/2! + x^4/4! - ...
    +   * |x| < pi/2
    +   *
    +   */
    +  function cosine(Ctor, x) {
    +    var k, len, y;
    +
    +    if (x.isZero()) return x;
    +
    +    // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1
    +    // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1
    +
    +    // Estimate the optimum number of times to use the argument reduction.
    +    len = x.d.length;
    +    if (len < 32) {
    +      k = Math.ceil(len / 3);
    +      y = (1 / tinyPow(4, k)).toString();
    +    } else {
    +      k = 16;
    +      y = '2.3283064365386962890625e-10';
    +    }
    +
    +    Ctor.precision += k;
    +
    +    x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1));
    +
    +    // Reverse argument reduction
    +    for (var i = k; i--;) {
    +      var cos2x = x.times(x);
    +      x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1);
    +    }
    +
    +    Ctor.precision -= k;
    +
    +    return x;
    +  }
    +
    +
    +  /*
    +   * Perform division in the specified base.
    +   */
    +  var divide = (function () {
    +
    +    // Assumes non-zero x and k, and hence non-zero result.
    +    function multiplyInteger(x, k, base) {
    +      var temp,
    +        carry = 0,
    +        i = x.length;
    +
    +      for (x = x.slice(); i--;) {
    +        temp = x[i] * k + carry;
    +        x[i] = temp % base | 0;
    +        carry = temp / base | 0;
    +      }
    +
    +      if (carry) x.unshift(carry);
    +
    +      return x;
    +    }
    +
    +    function compare(a, b, aL, bL) {
    +      var i, r;
    +
    +      if (aL != bL) {
    +        r = aL > bL ? 1 : -1;
    +      } else {
    +        for (i = r = 0; i < aL; i++) {
    +          if (a[i] != b[i]) {
    +            r = a[i] > b[i] ? 1 : -1;
    +            break;
    +          }
    +        }
    +      }
    +
    +      return r;
    +    }
    +
    +    function subtract(a, b, aL, base) {
    +      var i = 0;
    +
    +      // Subtract b from a.
    +      for (; aL--;) {
    +        a[aL] -= i;
    +        i = a[aL] < b[aL] ? 1 : 0;
    +        a[aL] = i * base + a[aL] - b[aL];
    +      }
    +
    +      // Remove leading zeros.
    +      for (; !a[0] && a.length > 1;) a.shift();
    +    }
    +
    +    return function (x, y, pr, rm, dp, base) {
    +      var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0,
    +        yL, yz,
    +        Ctor = x.constructor,
    +        sign = x.s == y.s ? 1 : -1,
    +        xd = x.d,
    +        yd = y.d;
    +
    +      // Either NaN, Infinity or 0?
    +      if (!xd || !xd[0] || !yd || !yd[0]) {
    +
    +        return new Ctor(// Return NaN if either NaN, or both Infinity or 0.
    +          !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN :
    +
    +          // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0.
    +          xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0);
    +      }
    +
    +      if (base) {
    +        logBase = 1;
    +        e = x.e - y.e;
    +      } else {
    +        base = BASE;
    +        logBase = LOG_BASE;
    +        e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase);
    +      }
    +
    +      yL = yd.length;
    +      xL = xd.length;
    +      q = new Ctor(sign);
    +      qd = q.d = [];
    +
    +      // Result exponent may be one less than e.
    +      // The digit array of a Decimal from toStringBinary may have trailing zeros.
    +      for (i = 0; yd[i] == (xd[i] || 0); i++);
    +
    +      if (yd[i] > (xd[i] || 0)) e--;
    +
    +      if (pr == null) {
    +        sd = pr = Ctor.precision;
    +        rm = Ctor.rounding;
    +      } else if (dp) {
    +        sd = pr + (x.e - y.e) + 1;
    +      } else {
    +        sd = pr;
    +      }
    +
    +      if (sd < 0) {
    +        qd.push(1);
    +        more = true;
    +      } else {
    +
    +        // Convert precision in number of base 10 digits to base 1e7 digits.
    +        sd = sd / logBase + 2 | 0;
    +        i = 0;
    +
    +        // divisor < 1e7
    +        if (yL == 1) {
    +          k = 0;
    +          yd = yd[0];
    +          sd++;
    +
    +          // k is the carry.
    +          for (; (i < xL || k) && sd--; i++) {
    +            t = k * base + (xd[i] || 0);
    +            qd[i] = t / yd | 0;
    +            k = t % yd | 0;
    +          }
    +
    +          more = k || i < xL;
    +
    +        // divisor >= 1e7
    +        } else {
    +
    +          // Normalise xd and yd so highest order digit of yd is >= base/2
    +          k = base / (yd[0] + 1) | 0;
    +
    +          if (k > 1) {
    +            yd = multiplyInteger(yd, k, base);
    +            xd = multiplyInteger(xd, k, base);
    +            yL = yd.length;
    +            xL = xd.length;
    +          }
    +
    +          xi = yL;
    +          rem = xd.slice(0, yL);
    +          remL = rem.length;
    +
    +          // Add zeros to make remainder as long as divisor.
    +          for (; remL < yL;) rem[remL++] = 0;
    +
    +          yz = yd.slice();
    +          yz.unshift(0);
    +          yd0 = yd[0];
    +
    +          if (yd[1] >= base / 2) ++yd0;
    +
    +          do {
    +            k = 0;
    +
    +            // Compare divisor and remainder.
    +            cmp = compare(yd, rem, yL, remL);
    +
    +            // If divisor < remainder.
    +            if (cmp < 0) {
    +
    +              // Calculate trial digit, k.
    +              rem0 = rem[0];
    +              if (yL != remL) rem0 = rem0 * base + (rem[1] || 0);
    +
    +              // k will be how many times the divisor goes into the current remainder.
    +              k = rem0 / yd0 | 0;
    +
    +              //  Algorithm:
    +              //  1. product = divisor * trial digit (k)
    +              //  2. if product > remainder: product -= divisor, k--
    +              //  3. remainder -= product
    +              //  4. if product was < remainder at 2:
    +              //    5. compare new remainder and divisor
    +              //    6. If remainder > divisor: remainder -= divisor, k++
    +
    +              if (k > 1) {
    +                if (k >= base) k = base - 1;
    +
    +                // product = divisor * trial digit.
    +                prod = multiplyInteger(yd, k, base);
    +                prodL = prod.length;
    +                remL = rem.length;
    +
    +                // Compare product and remainder.
    +                cmp = compare(prod, rem, prodL, remL);
    +
    +                // product > remainder.
    +                if (cmp == 1) {
    +                  k--;
    +
    +                  // Subtract divisor from product.
    +                  subtract(prod, yL < prodL ? yz : yd, prodL, base);
    +                }
    +              } else {
    +
    +                // cmp is -1.
    +                // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1
    +                // to avoid it. If k is 1 there is a need to compare yd and rem again below.
    +                if (k == 0) cmp = k = 1;
    +                prod = yd.slice();
    +              }
    +
    +              prodL = prod.length;
    +              if (prodL < remL) prod.unshift(0);
    +
    +              // Subtract product from remainder.
    +              subtract(rem, prod, remL, base);
    +
    +              // If product was < previous remainder.
    +              if (cmp == -1) {
    +                remL = rem.length;
    +
    +                // Compare divisor and new remainder.
    +                cmp = compare(yd, rem, yL, remL);
    +
    +                // If divisor < new remainder, subtract divisor from remainder.
    +                if (cmp < 1) {
    +                  k++;
    +
    +                  // Subtract divisor from remainder.
    +                  subtract(rem, yL < remL ? yz : yd, remL, base);
    +                }
    +              }
    +
    +              remL = rem.length;
    +            } else if (cmp === 0) {
    +              k++;
    +              rem = [0];
    +            }    // if cmp === 1, k will be 0
    +
    +            // Add the next digit, k, to the result array.
    +            qd[i++] = k;
    +
    +            // Update the remainder.
    +            if (cmp && rem[0]) {
    +              rem[remL++] = xd[xi] || 0;
    +            } else {
    +              rem = [xd[xi]];
    +              remL = 1;
    +            }
    +
    +          } while ((xi++ < xL || rem[0] !== void 0) && sd--);
    +
    +          more = rem[0] !== void 0;
    +        }
    +
    +        // Leading zero?
    +        if (!qd[0]) qd.shift();
    +      }
    +
    +      // logBase is 1 when divide is being used for base conversion.
    +      if (logBase == 1) {
    +        q.e = e;
    +        inexact = more;
    +      } else {
    +
    +        // To calculate q.e, first get the number of digits of qd[0].
    +        for (i = 1, k = qd[0]; k >= 10; k /= 10) i++;
    +        q.e = i + e * logBase - 1;
    +
    +        finalise(q, dp ? pr + q.e + 1 : pr, rm, more);
    +      }
    +
    +      return q;
    +    };
    +  })();
    +
    +
    +  /*
    +   * Round `x` to `sd` significant digits using rounding mode `rm`.
    +   * Check for over/under-flow.
    +   */
    +   function finalise(x, sd, rm, isTruncated) {
    +    var digits, i, j, k, rd, roundUp, w, xd, xdi,
    +      Ctor = x.constructor;
    +
    +    // Don't round if sd is null or undefined.
    +    out: if (sd != null) {
    +      xd = x.d;
    +
    +      // Infinity/NaN.
    +      if (!xd) return x;
    +
    +      // rd: the rounding digit, i.e. the digit after the digit that may be rounded up.
    +      // w: the word of xd containing rd, a base 1e7 number.
    +      // xdi: the index of w within xd.
    +      // digits: the number of digits of w.
    +      // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if
    +      // they had leading zeros)
    +      // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero).
    +
    +      // Get the length of the first word of the digits array xd.
    +      for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++;
    +      i = sd - digits;
    +
    +      // Is the rounding digit in the first word of xd?
    +      if (i < 0) {
    +        i += LOG_BASE;
    +        j = sd;
    +        w = xd[xdi = 0];
    +
    +        // Get the rounding digit at index j of w.
    +        rd = w / mathpow(10, digits - j - 1) % 10 | 0;
    +      } else {
    +        xdi = Math.ceil((i + 1) / LOG_BASE);
    +        k = xd.length;
    +        if (xdi >= k) {
    +          if (isTruncated) {
    +
    +            // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`.
    +            for (; k++ <= xdi;) xd.push(0);
    +            w = rd = 0;
    +            digits = 1;
    +            i %= LOG_BASE;
    +            j = i - LOG_BASE + 1;
    +          } else {
    +            break out;
    +          }
    +        } else {
    +          w = k = xd[xdi];
    +
    +          // Get the number of digits of w.
    +          for (digits = 1; k >= 10; k /= 10) digits++;
    +
    +          // Get the index of rd within w.
    +          i %= LOG_BASE;
    +
    +          // Get the index of rd within w, adjusted for leading zeros.
    +          // The number of leading zeros of w is given by LOG_BASE - digits.
    +          j = i - LOG_BASE + digits;
    +
    +          // Get the rounding digit at index j of w.
    +          rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0;
    +        }
    +      }
    +
    +      // Are there any non-zero digits after the rounding digit?
    +      isTruncated = isTruncated || sd < 0 ||
    +        xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1));
    +
    +      // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right
    +      // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression
    +      // will give 714.
    +
    +      roundUp = rm < 4
    +        ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
    +        : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 &&
    +
    +          // Check whether the digit to the left of the rounding digit is odd.
    +          ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 ||
    +            rm == (x.s < 0 ? 8 : 7));
    +
    +      if (sd < 1 || !xd[0]) {
    +        xd.length = 0;
    +        if (roundUp) {
    +
    +          // Convert sd to decimal places.
    +          sd -= x.e + 1;
    +
    +          // 1, 0.1, 0.01, 0.001, 0.0001 etc.
    +          xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE);
    +          x.e = -sd || 0;
    +        } else {
    +
    +          // Zero.
    +          xd[0] = x.e = 0;
    +        }
    +
    +        return x;
    +      }
    +
    +      // Remove excess digits.
    +      if (i == 0) {
    +        xd.length = xdi;
    +        k = 1;
    +        xdi--;
    +      } else {
    +        xd.length = xdi + 1;
    +        k = mathpow(10, LOG_BASE - i);
    +
    +        // E.g. 56700 becomes 56000 if 7 is the rounding digit.
    +        // j > 0 means i > number of leading zeros of w.
    +        xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0;
    +      }
    +
    +      if (roundUp) {
    +        for (;;) {
    +
    +          // Is the digit to be rounded up in the first word of xd?
    +          if (xdi == 0) {
    +
    +            // i will be the length of xd[0] before k is added.
    +            for (i = 1, j = xd[0]; j >= 10; j /= 10) i++;
    +            j = xd[0] += k;
    +            for (k = 1; j >= 10; j /= 10) k++;
    +
    +            // if i != k the length has increased.
    +            if (i != k) {
    +              x.e++;
    +              if (xd[0] == BASE) xd[0] = 1;
    +            }
    +
    +            break;
    +          } else {
    +            xd[xdi] += k;
    +            if (xd[xdi] != BASE) break;
    +            xd[xdi--] = 0;
    +            k = 1;
    +          }
    +        }
    +      }
    +
    +      // Remove trailing zeros.
    +      for (i = xd.length; xd[--i] === 0;) xd.pop();
    +    }
    +
    +    if (external) {
    +
    +      // Overflow?
    +      if (x.e > Ctor.maxE) {
    +
    +        // Infinity.
    +        x.d = null;
    +        x.e = NaN;
    +
    +      // Underflow?
    +      } else if (x.e < Ctor.minE) {
    +
    +        // Zero.
    +        x.e = 0;
    +        x.d = [0];
    +        // Ctor.underflow = true;
    +      } // else Ctor.underflow = false;
    +    }
    +
    +    return x;
    +  }
    +
    +
    +  function finiteToString(x, isExp, sd) {
    +    if (!x.isFinite()) return nonFiniteToString(x);
    +    var k,
    +      e = x.e,
    +      str = digitsToString(x.d),
    +      len = str.length;
    +
    +    if (isExp) {
    +      if (sd && (k = sd - len) > 0) {
    +        str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k);
    +      } else if (len > 1) {
    +        str = str.charAt(0) + '.' + str.slice(1);
    +      }
    +
    +      str = str + (x.e < 0 ? 'e' : 'e+') + x.e;
    +    } else if (e < 0) {
    +      str = '0.' + getZeroString(-e - 1) + str;
    +      if (sd && (k = sd - len) > 0) str += getZeroString(k);
    +    } else if (e >= len) {
    +      str += getZeroString(e + 1 - len);
    +      if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k);
    +    } else {
    +      if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k);
    +      if (sd && (k = sd - len) > 0) {
    +        if (e + 1 === len) str += '.';
    +        str += getZeroString(k);
    +      }
    +    }
    +
    +    return str;
    +  }
    +
    +
    +  // Calculate the base 10 exponent from the base 1e7 exponent.
    +  function getBase10Exponent(digits, e) {
    +    var w = digits[0];
    +
    +    // Add the number of digits of the first word of the digits array.
    +    for ( e *= LOG_BASE; w >= 10; w /= 10) e++;
    +    return e;
    +  }
    +
    +
    +  function getLn10(Ctor, sd, pr) {
    +    if (sd > LN10_PRECISION) {
    +
    +      // Reset global state in case the exception is caught.
    +      external = true;
    +      if (pr) Ctor.precision = pr;
    +      throw Error(precisionLimitExceeded);
    +    }
    +    return finalise(new Ctor(LN10), sd, 1, true);
    +  }
    +
    +
    +  function getPi(Ctor, sd, rm) {
    +    if (sd > PI_PRECISION) throw Error(precisionLimitExceeded);
    +    return finalise(new Ctor(PI), sd, rm, true);
    +  }
    +
    +
    +  function getPrecision(digits) {
    +    var w = digits.length - 1,
    +      len = w * LOG_BASE + 1;
    +
    +    w = digits[w];
    +
    +    // If non-zero...
    +    if (w) {
    +
    +      // Subtract the number of trailing zeros of the last word.
    +      for (; w % 10 == 0; w /= 10) len--;
    +
    +      // Add the number of digits of the first word.
    +      for (w = digits[0]; w >= 10; w /= 10) len++;
    +    }
    +
    +    return len;
    +  }
    +
    +
    +  function getZeroString(k) {
    +    var zs = '';
    +    for (; k--;) zs += '0';
    +    return zs;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an
    +   * integer of type number.
    +   *
    +   * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`.
    +   *
    +   */
    +  function intPow(Ctor, x, n, pr) {
    +    var isTruncated,
    +      r = new Ctor(1),
    +
    +      // Max n of 9007199254740991 takes 53 loop iterations.
    +      // Maximum digits array length; leaves [28, 34] guard digits.
    +      k = Math.ceil(pr / LOG_BASE + 4);
    +
    +    external = false;
    +
    +    for (;;) {
    +      if (n % 2) {
    +        r = r.times(x);
    +        if (truncate(r.d, k)) isTruncated = true;
    +      }
    +
    +      n = mathfloor(n / 2);
    +      if (n === 0) {
    +
    +        // To ensure correct rounding when r.d is truncated, increment the last word if it is zero.
    +        n = r.d.length - 1;
    +        if (isTruncated && r.d[n] === 0) ++r.d[n];
    +        break;
    +      }
    +
    +      x = x.times(x);
    +      truncate(x.d, k);
    +    }
    +
    +    external = true;
    +
    +    return r;
    +  }
    +
    +
    +  function isOdd(n) {
    +    return n.d[n.d.length - 1] & 1;
    +  }
    +
    +
    +  /*
    +   * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'.
    +   */
    +  function maxOrMin(Ctor, args, ltgt) {
    +    var y,
    +      x = new Ctor(args[0]),
    +      i = 0;
    +
    +    for (; ++i < args.length;) {
    +      y = new Ctor(args[i]);
    +      if (!y.s) {
    +        x = y;
    +        break;
    +      } else if (x[ltgt](y)) {
    +        x = y;
    +      }
    +    }
    +
    +    return x;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant
    +   * digits.
    +   *
    +   * Taylor/Maclaurin series.
    +   *
    +   * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ...
    +   *
    +   * Argument reduction:
    +   *   Repeat x = x / 32, k += 5, until |x| < 0.1
    +   *   exp(x) = exp(x / 2^k)^(2^k)
    +   *
    +   * Previously, the argument was initially reduced by
    +   * exp(x) = exp(r) * 10^k  where r = x - k * ln10, k = floor(x / ln10)
    +   * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was
    +   * found to be slower than just dividing repeatedly by 32 as above.
    +   *
    +   * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000
    +   * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000
    +   * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324)
    +   *
    +   *  exp(Infinity)  = Infinity
    +   *  exp(-Infinity) = 0
    +   *  exp(NaN)       = NaN
    +   *  exp(±0)        = 1
    +   *
    +   *  exp(x) is non-terminating for any finite, non-zero x.
    +   *
    +   *  The result will always be correctly rounded.
    +   *
    +   */
    +  function naturalExponential(x, sd) {
    +    var denominator, guard, j, pow, sum, t, wpr,
    +      rep = 0,
    +      i = 0,
    +      k = 0,
    +      Ctor = x.constructor,
    +      rm = Ctor.rounding,
    +      pr = Ctor.precision;
    +
    +    // 0/NaN/Infinity?
    +    if (!x.d || !x.d[0] || x.e > 17) {
    +
    +      return new Ctor(x.d
    +        ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0
    +        : x.s ? x.s < 0 ? 0 : x : 0 / 0);
    +    }
    +
    +    if (sd == null) {
    +      external = false;
    +      wpr = pr;
    +    } else {
    +      wpr = sd;
    +    }
    +
    +    t = new Ctor(0.03125);
    +
    +    // while abs(x) >= 0.1
    +    while (x.e > -2) {
    +
    +      // x = x / 2^5
    +      x = x.times(t);
    +      k += 5;
    +    }
    +
    +    // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision
    +    // necessary to ensure the first 4 rounding digits are correct.
    +    guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0;
    +    wpr += guard;
    +    denominator = pow = sum = new Ctor(1);
    +    Ctor.precision = wpr;
    +
    +    for (;;) {
    +      pow = finalise(pow.times(x), wpr, 1);
    +      denominator = denominator.times(++i);
    +      t = sum.plus(divide(pow, denominator, wpr, 1));
    +
    +      if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
    +        j = k;
    +        while (j--) sum = finalise(sum.times(sum), wpr, 1);
    +
    +        // Check to see if the first 4 rounding digits are [49]999.
    +        // If so, repeat the summation with a higher precision, otherwise
    +        // e.g. with precision: 18, rounding: 1
    +        // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123)
    +        // `wpr - guard` is the index of first rounding digit.
    +        if (sd == null) {
    +
    +          if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) {
    +            Ctor.precision = wpr += 10;
    +            denominator = pow = t = new Ctor(1);
    +            i = 0;
    +            rep++;
    +          } else {
    +            return finalise(sum, Ctor.precision = pr, rm, external = true);
    +          }
    +        } else {
    +          Ctor.precision = pr;
    +          return sum;
    +        }
    +      }
    +
    +      sum = t;
    +    }
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant
    +   * digits.
    +   *
    +   *  ln(-n)        = NaN
    +   *  ln(0)         = -Infinity
    +   *  ln(-0)        = -Infinity
    +   *  ln(1)         = 0
    +   *  ln(Infinity)  = Infinity
    +   *  ln(-Infinity) = NaN
    +   *  ln(NaN)       = NaN
    +   *
    +   *  ln(n) (n != 1) is non-terminating.
    +   *
    +   */
    +  function naturalLogarithm(y, sd) {
    +    var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2,
    +      n = 1,
    +      guard = 10,
    +      x = y,
    +      xd = x.d,
    +      Ctor = x.constructor,
    +      rm = Ctor.rounding,
    +      pr = Ctor.precision;
    +
    +    // Is x negative or Infinity, NaN, 0 or 1?
    +    if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) {
    +      return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x);
    +    }
    +
    +    if (sd == null) {
    +      external = false;
    +      wpr = pr;
    +    } else {
    +      wpr = sd;
    +    }
    +
    +    Ctor.precision = wpr += guard;
    +    c = digitsToString(xd);
    +    c0 = c.charAt(0);
    +
    +    if (Math.abs(e = x.e) < 1.5e15) {
    +
    +      // Argument reduction.
    +      // The series converges faster the closer the argument is to 1, so using
    +      // ln(a^b) = b * ln(a),   ln(a) = ln(a^b) / b
    +      // multiply the argument by itself until the leading digits of the significand are 7, 8, 9,
    +      // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can
    +      // later be divided by this number, then separate out the power of 10 using
    +      // ln(a*10^b) = ln(a) + b*ln(10).
    +
    +      // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14).
    +      //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) {
    +      // max n is 6 (gives 0.7 - 1.3)
    +      while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) {
    +        x = x.times(y);
    +        c = digitsToString(x.d);
    +        c0 = c.charAt(0);
    +        n++;
    +      }
    +
    +      e = x.e;
    +
    +      if (c0 > 1) {
    +        x = new Ctor('0.' + c);
    +        e++;
    +      } else {
    +        x = new Ctor(c0 + '.' + c.slice(1));
    +      }
    +    } else {
    +
    +      // The argument reduction method above may result in overflow if the argument y is a massive
    +      // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this
    +      // function using ln(x*10^e) = ln(x) + e*ln(10).
    +      t = getLn10(Ctor, wpr + 2, pr).times(e + '');
    +      x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t);
    +      Ctor.precision = pr;
    +
    +      return sd == null ? finalise(x, pr, rm, external = true) : x;
    +    }
    +
    +    // x1 is x reduced to a value near 1.
    +    x1 = x;
    +
    +    // Taylor series.
    +    // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...)
    +    // where x = (y - 1)/(y + 1)    (|x| < 1)
    +    sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1);
    +    x2 = finalise(x.times(x), wpr, 1);
    +    denominator = 3;
    +
    +    for (;;) {
    +      numerator = finalise(numerator.times(x2), wpr, 1);
    +      t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1));
    +
    +      if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {
    +        sum = sum.times(2);
    +
    +        // Reverse the argument reduction. Check that e is not 0 because, besides preventing an
    +        // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0.
    +        if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + ''));
    +        sum = divide(sum, new Ctor(n), wpr, 1);
    +
    +        // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has
    +        // been repeated previously) and the first 4 rounding digits 9999?
    +        // If so, restart the summation with a higher precision, otherwise
    +        // e.g. with precision: 12, rounding: 1
    +        // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463.
    +        // `wpr - guard` is the index of first rounding digit.
    +        if (sd == null) {
    +          if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) {
    +            Ctor.precision = wpr += guard;
    +            t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1);
    +            x2 = finalise(x.times(x), wpr, 1);
    +            denominator = rep = 1;
    +          } else {
    +            return finalise(sum, Ctor.precision = pr, rm, external = true);
    +          }
    +        } else {
    +          Ctor.precision = pr;
    +          return sum;
    +        }
    +      }
    +
    +      sum = t;
    +      denominator += 2;
    +    }
    +  }
    +
    +
    +  // ±Infinity, NaN.
    +  function nonFiniteToString(x) {
    +    // Unsigned.
    +    return String(x.s * x.s / 0);
    +  }
    +
    +
    +  /*
    +   * Parse the value of a new Decimal `x` from string `str`.
    +   */
    +  function parseDecimal(x, str) {
    +    var e, i, len;
    +
    +    // Decimal point?
    +    if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
    +
    +    // Exponential form?
    +    if ((i = str.search(/e/i)) > 0) {
    +
    +      // Determine exponent.
    +      if (e < 0) e = i;
    +      e += +str.slice(i + 1);
    +      str = str.substring(0, i);
    +    } else if (e < 0) {
    +
    +      // Integer.
    +      e = str.length;
    +    }
    +
    +    // Determine leading zeros.
    +    for (i = 0; str.charCodeAt(i) === 48; i++);
    +
    +    // Determine trailing zeros.
    +    for (len = str.length; str.charCodeAt(len - 1) === 48; --len);
    +    str = str.slice(i, len);
    +
    +    if (str) {
    +      len -= i;
    +      x.e = e = e - i - 1;
    +      x.d = [];
    +
    +      // Transform base
    +
    +      // e is the base 10 exponent.
    +      // i is where to slice str to get the first word of the digits array.
    +      i = (e + 1) % LOG_BASE;
    +      if (e < 0) i += LOG_BASE;
    +
    +      if (i < len) {
    +        if (i) x.d.push(+str.slice(0, i));
    +        for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE));
    +        str = str.slice(i);
    +        i = LOG_BASE - str.length;
    +      } else {
    +        i -= len;
    +      }
    +
    +      for (; i--;) str += '0';
    +      x.d.push(+str);
    +
    +      if (external) {
    +
    +        // Overflow?
    +        if (x.e > x.constructor.maxE) {
    +
    +          // Infinity.
    +          x.d = null;
    +          x.e = NaN;
    +
    +        // Underflow?
    +        } else if (x.e < x.constructor.minE) {
    +
    +          // Zero.
    +          x.e = 0;
    +          x.d = [0];
    +          // x.constructor.underflow = true;
    +        } // else x.constructor.underflow = false;
    +      }
    +    } else {
    +
    +      // Zero.
    +      x.e = 0;
    +      x.d = [0];
    +    }
    +
    +    return x;
    +  }
    +
    +
    +  /*
    +   * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value.
    +   */
    +  function parseOther(x, str) {
    +    var base, Ctor, divisor, i, isFloat, len, p, xd, xe;
    +
    +    if (str.indexOf('_') > -1) {
    +      str = str.replace(/(\d)_(?=\d)/g, '$1');
    +      if (isDecimal.test(str)) return parseDecimal(x, str);
    +    } else if (str === 'Infinity' || str === 'NaN') {
    +      if (!+str) x.s = NaN;
    +      x.e = NaN;
    +      x.d = null;
    +      return x;
    +    }
    +
    +    if (isHex.test(str))  {
    +      base = 16;
    +      str = str.toLowerCase();
    +    } else if (isBinary.test(str))  {
    +      base = 2;
    +    } else if (isOctal.test(str))  {
    +      base = 8;
    +    } else {
    +      throw Error(invalidArgument + str);
    +    }
    +
    +    // Is there a binary exponent part?
    +    i = str.search(/p/i);
    +
    +    if (i > 0) {
    +      p = +str.slice(i + 1);
    +      str = str.substring(2, i);
    +    } else {
    +      str = str.slice(2);
    +    }
    +
    +    // Convert `str` as an integer then divide the result by `base` raised to a power such that the
    +    // fraction part will be restored.
    +    i = str.indexOf('.');
    +    isFloat = i >= 0;
    +    Ctor = x.constructor;
    +
    +    if (isFloat) {
    +      str = str.replace('.', '');
    +      len = str.length;
    +      i = len - i;
    +
    +      // log[10](16) = 1.2041... , log[10](88) = 1.9444....
    +      divisor = intPow(Ctor, new Ctor(base), i, i * 2);
    +    }
    +
    +    xd = convertBase(str, base, BASE);
    +    xe = xd.length - 1;
    +
    +    // Remove trailing zeros.
    +    for (i = xe; xd[i] === 0; --i) xd.pop();
    +    if (i < 0) return new Ctor(x.s * 0);
    +    x.e = getBase10Exponent(xd, xe);
    +    x.d = xd;
    +    external = false;
    +
    +    // At what precision to perform the division to ensure exact conversion?
    +    // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount)
    +    // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412
    +    // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits.
    +    // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount
    +    // Therefore using 4 * the number of digits of str will always be enough.
    +    if (isFloat) x = divide(x, divisor, len * 4);
    +
    +    // Multiply by the binary exponent part if present.
    +    if (p) x = x.times(Math.abs(p) < 54 ? mathpow(2, p) : Decimal.pow(2, p));
    +    external = true;
    +
    +    return x;
    +  }
    +
    +
    +  /*
    +   * sin(x) = x - x^3/3! + x^5/5! - ...
    +   * |x| < pi/2
    +   *
    +   */
    +  function sine(Ctor, x) {
    +    var k,
    +      len = x.d.length;
    +
    +    if (len < 3) {
    +      return x.isZero() ? x : taylorSeries(Ctor, 2, x, x);
    +    }
    +
    +    // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x)
    +    // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5)
    +    // and  sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20))
    +
    +    // Estimate the optimum number of times to use the argument reduction.
    +    k = 1.4 * Math.sqrt(len);
    +    k = k > 16 ? 16 : k | 0;
    +
    +    x = x.times(1 / tinyPow(5, k));
    +    x = taylorSeries(Ctor, 2, x, x);
    +
    +    // Reverse argument reduction
    +    var sin2_x,
    +      d5 = new Ctor(5),
    +      d16 = new Ctor(16),
    +      d20 = new Ctor(20);
    +    for (; k--;) {
    +      sin2_x = x.times(x);
    +      x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20))));
    +    }
    +
    +    return x;
    +  }
    +
    +
    +  // Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`.
    +  function taylorSeries(Ctor, n, x, y, isHyperbolic) {
    +    var j, t, u, x2,
    +      pr = Ctor.precision,
    +      k = Math.ceil(pr / LOG_BASE);
    +
    +    external = false;
    +    x2 = x.times(x);
    +    u = new Ctor(y);
    +
    +    for (;;) {
    +      t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1);
    +      u = isHyperbolic ? y.plus(t) : y.minus(t);
    +      y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1);
    +      t = u.plus(y);
    +
    +      if (t.d[k] !== void 0) {
    +        for (j = k; t.d[j] === u.d[j] && j--;);
    +        if (j == -1) break;
    +      }
    +
    +      j = u;
    +      u = y;
    +      y = t;
    +      t = j;
    +    }
    +
    +    external = true;
    +    t.d.length = k + 1;
    +
    +    return t;
    +  }
    +
    +
    +  // Exponent e must be positive and non-zero.
    +  function tinyPow(b, e) {
    +    var n = b;
    +    while (--e) n *= b;
    +    return n;
    +  }
    +
    +
    +  // Return the absolute value of `x` reduced to less than or equal to half pi.
    +  function toLessThanHalfPi(Ctor, x) {
    +    var t,
    +      isNeg = x.s < 0,
    +      pi = getPi(Ctor, Ctor.precision, 1),
    +      halfPi = pi.times(0.5);
    +
    +    x = x.abs();
    +
    +    if (x.lte(halfPi)) {
    +      quadrant = isNeg ? 4 : 1;
    +      return x;
    +    }
    +
    +    t = x.divToInt(pi);
    +
    +    if (t.isZero()) {
    +      quadrant = isNeg ? 3 : 2;
    +    } else {
    +      x = x.minus(t.times(pi));
    +
    +      // 0 <= x < pi
    +      if (x.lte(halfPi)) {
    +        quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1);
    +        return x;
    +      }
    +
    +      quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2);
    +    }
    +
    +    return x.minus(pi).abs();
    +  }
    +
    +
    +  /*
    +   * Return the value of Decimal `x` as a string in base `baseOut`.
    +   *
    +   * If the optional `sd` argument is present include a binary exponent suffix.
    +   */
    +  function toStringBinary(x, baseOut, sd, rm) {
    +    var base, e, i, k, len, roundUp, str, xd, y,
    +      Ctor = x.constructor,
    +      isExp = sd !== void 0;
    +
    +    if (isExp) {
    +      checkInt32(sd, 1, MAX_DIGITS);
    +      if (rm === void 0) rm = Ctor.rounding;
    +      else checkInt32(rm, 0, 8);
    +    } else {
    +      sd = Ctor.precision;
    +      rm = Ctor.rounding;
    +    }
    +
    +    if (!x.isFinite()) {
    +      str = nonFiniteToString(x);
    +    } else {
    +      str = finiteToString(x);
    +      i = str.indexOf('.');
    +
    +      // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required:
    +      // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10))
    +      // minBinaryExponent = floor(decimalExponent * log[2](10))
    +      // log[2](10) = 3.321928094887362347870319429489390175864
    +
    +      if (isExp) {
    +        base = 2;
    +        if (baseOut == 16) {
    +          sd = sd * 4 - 3;
    +        } else if (baseOut == 8) {
    +          sd = sd * 3 - 2;
    +        }
    +      } else {
    +        base = baseOut;
    +      }
    +
    +      // Convert the number as an integer then divide the result by its base raised to a power such
    +      // that the fraction part will be restored.
    +
    +      // Non-integer.
    +      if (i >= 0) {
    +        str = str.replace('.', '');
    +        y = new Ctor(1);
    +        y.e = str.length - i;
    +        y.d = convertBase(finiteToString(y), 10, base);
    +        y.e = y.d.length;
    +      }
    +
    +      xd = convertBase(str, 10, base);
    +      e = len = xd.length;
    +
    +      // Remove trailing zeros.
    +      for (; xd[--len] == 0;) xd.pop();
    +
    +      if (!xd[0]) {
    +        str = isExp ? '0p+0' : '0';
    +      } else {
    +        if (i < 0) {
    +          e--;
    +        } else {
    +          x = new Ctor(x);
    +          x.d = xd;
    +          x.e = e;
    +          x = divide(x, y, sd, rm, 0, base);
    +          xd = x.d;
    +          e = x.e;
    +          roundUp = inexact;
    +        }
    +
    +        // The rounding digit, i.e. the digit after the digit that may be rounded up.
    +        i = xd[sd];
    +        k = base / 2;
    +        roundUp = roundUp || xd[sd + 1] !== void 0;
    +
    +        roundUp = rm < 4
    +          ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2))
    +          : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 ||
    +            rm === (x.s < 0 ? 8 : 7));
    +
    +        xd.length = sd;
    +
    +        if (roundUp) {
    +
    +          // Rounding up may mean the previous digit has to be rounded up and so on.
    +          for (; ++xd[--sd] > base - 1;) {
    +            xd[sd] = 0;
    +            if (!sd) {
    +              ++e;
    +              xd.unshift(1);
    +            }
    +          }
    +        }
    +
    +        // Determine trailing zeros.
    +        for (len = xd.length; !xd[len - 1]; --len);
    +
    +        // E.g. [4, 11, 15] becomes 4bf.
    +        for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]);
    +
    +        // Add binary exponent suffix?
    +        if (isExp) {
    +          if (len > 1) {
    +            if (baseOut == 16 || baseOut == 8) {
    +              i = baseOut == 16 ? 4 : 3;
    +              for (--len; len % i; len++) str += '0';
    +              xd = convertBase(str, base, baseOut);
    +              for (len = xd.length; !xd[len - 1]; --len);
    +
    +              // xd[0] will always be be 1
    +              for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]);
    +            } else {
    +              str = str.charAt(0) + '.' + str.slice(1);
    +            }
    +          }
    +
    +          str =  str + (e < 0 ? 'p' : 'p+') + e;
    +        } else if (e < 0) {
    +          for (; ++e;) str = '0' + str;
    +          str = '0.' + str;
    +        } else {
    +          if (++e > len) for (e -= len; e-- ;) str += '0';
    +          else if (e < len) str = str.slice(0, e) + '.' + str.slice(e);
    +        }
    +      }
    +
    +      str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str;
    +    }
    +
    +    return x.s < 0 ? '-' + str : str;
    +  }
    +
    +
    +  // Does not strip trailing zeros.
    +  function truncate(arr, len) {
    +    if (arr.length > len) {
    +      arr.length = len;
    +      return true;
    +    }
    +  }
    +
    +
    +  // Decimal methods
    +
    +
    +  /*
    +   *  abs
    +   *  acos
    +   *  acosh
    +   *  add
    +   *  asin
    +   *  asinh
    +   *  atan
    +   *  atanh
    +   *  atan2
    +   *  cbrt
    +   *  ceil
    +   *  clamp
    +   *  clone
    +   *  config
    +   *  cos
    +   *  cosh
    +   *  div
    +   *  exp
    +   *  floor
    +   *  hypot
    +   *  ln
    +   *  log
    +   *  log2
    +   *  log10
    +   *  max
    +   *  min
    +   *  mod
    +   *  mul
    +   *  pow
    +   *  random
    +   *  round
    +   *  set
    +   *  sign
    +   *  sin
    +   *  sinh
    +   *  sqrt
    +   *  sub
    +   *  sum
    +   *  tan
    +   *  tanh
    +   *  trunc
    +   */
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the absolute value of `x`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function abs(x) {
    +    return new this(x).abs();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arccosine in radians of `x`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function acos(x) {
    +    return new this(x).acos();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to
    +   * `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function acosh(x) {
    +    return new this(x).acosh();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   * y {number|string|Decimal}
    +   *
    +   */
    +  function add(x, y) {
    +    return new this(x).plus(y);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function asin(x) {
    +    return new this(x).asin();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to
    +   * `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function asinh(x) {
    +    return new this(x).asinh();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function atan(x) {
    +    return new this(x).atan();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to
    +   * `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function atanh(x) {
    +    return new this(x).atanh();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi
    +   * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * Domain: [-Infinity, Infinity]
    +   * Range: [-pi, pi]
    +   *
    +   * y {number|string|Decimal} The y-coordinate.
    +   * x {number|string|Decimal} The x-coordinate.
    +   *
    +   * atan2(±0, -0)               = ±pi
    +   * atan2(±0, +0)               = ±0
    +   * atan2(±0, -x)               = ±pi for x > 0
    +   * atan2(±0, x)                = ±0 for x > 0
    +   * atan2(-y, ±0)               = -pi/2 for y > 0
    +   * atan2(y, ±0)                = pi/2 for y > 0
    +   * atan2(±y, -Infinity)        = ±pi for finite y > 0
    +   * atan2(±y, +Infinity)        = ±0 for finite y > 0
    +   * atan2(±Infinity, x)         = ±pi/2 for finite x
    +   * atan2(±Infinity, -Infinity) = ±3*pi/4
    +   * atan2(±Infinity, +Infinity) = ±pi/4
    +   * atan2(NaN, x) = NaN
    +   * atan2(y, NaN) = NaN
    +   *
    +   */
    +  function atan2(y, x) {
    +    y = new this(y);
    +    x = new this(x);
    +    var r,
    +      pr = this.precision,
    +      rm = this.rounding,
    +      wpr = pr + 4;
    +
    +    // Either NaN
    +    if (!y.s || !x.s) {
    +      r = new this(NaN);
    +
    +    // Both ±Infinity
    +    } else if (!y.d && !x.d) {
    +      r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75);
    +      r.s = y.s;
    +
    +    // x is ±Infinity or y is ±0
    +    } else if (!x.d || y.isZero()) {
    +      r = x.s < 0 ? getPi(this, pr, rm) : new this(0);
    +      r.s = y.s;
    +
    +    // y is ±Infinity or x is ±0
    +    } else if (!y.d || x.isZero()) {
    +      r = getPi(this, wpr, 1).times(0.5);
    +      r.s = y.s;
    +
    +    // Both non-zero and finite
    +    } else if (x.s < 0) {
    +      this.precision = wpr;
    +      this.rounding = 1;
    +      r = this.atan(divide(y, x, wpr, 1));
    +      x = getPi(this, wpr, 1);
    +      this.precision = pr;
    +      this.rounding = rm;
    +      r = y.s < 0 ? r.minus(x) : r.plus(x);
    +    } else {
    +      r = this.atan(divide(y, x, wpr, 1));
    +    }
    +
    +    return r;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function cbrt(x) {
    +    return new this(x).cbrt();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function ceil(x) {
    +    return finalise(x = new this(x), x.e + 1, 2);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` clamped to the range delineated by `min` and `max`.
    +   *
    +   * x {number|string|Decimal}
    +   * min {number|string|Decimal}
    +   * max {number|string|Decimal}
    +   *
    +   */
    +  function clamp(x, min, max) {
    +    return new this(x).clamp(min, max);
    +  }
    +
    +
    +  /*
    +   * Configure global settings for a Decimal constructor.
    +   *
    +   * `obj` is an object with one or more of the following properties,
    +   *
    +   *   precision  {number}
    +   *   rounding   {number}
    +   *   toExpNeg   {number}
    +   *   toExpPos   {number}
    +   *   maxE       {number}
    +   *   minE       {number}
    +   *   modulo     {number}
    +   *   crypto     {boolean|number}
    +   *   defaults   {true}
    +   *
    +   * E.g. Decimal.config({ precision: 20, rounding: 4 })
    +   *
    +   */
    +  function config(obj) {
    +    if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected');
    +    var i, p, v,
    +      useDefaults = obj.defaults === true,
    +      ps = [
    +        'precision', 1, MAX_DIGITS,
    +        'rounding', 0, 8,
    +        'toExpNeg', -EXP_LIMIT, 0,
    +        'toExpPos', 0, EXP_LIMIT,
    +        'maxE', 0, EXP_LIMIT,
    +        'minE', -EXP_LIMIT, 0,
    +        'modulo', 0, 9
    +      ];
    +
    +    for (i = 0; i < ps.length; i += 3) {
    +      if (p = ps[i], useDefaults) this[p] = DEFAULTS[p];
    +      if ((v = obj[p]) !== void 0) {
    +        if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v;
    +        else throw Error(invalidArgument + p + ': ' + v);
    +      }
    +    }
    +
    +    if (p = 'crypto', useDefaults) this[p] = DEFAULTS[p];
    +    if ((v = obj[p]) !== void 0) {
    +      if (v === true || v === false || v === 0 || v === 1) {
    +        if (v) {
    +          if (typeof crypto != 'undefined' && crypto &&
    +            (crypto.getRandomValues || crypto.randomBytes)) {
    +            this[p] = true;
    +          } else {
    +            throw Error(cryptoUnavailable);
    +          }
    +        } else {
    +          this[p] = false;
    +        }
    +      } else {
    +        throw Error(invalidArgument + p + ': ' + v);
    +      }
    +    }
    +
    +    return this;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function cos(x) {
    +    return new this(x).cos();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function cosh(x) {
    +    return new this(x).cosh();
    +  }
    +
    +
    +  /*
    +   * Create and return a Decimal constructor with the same configuration properties as this Decimal
    +   * constructor.
    +   *
    +   */
    +  function clone(obj) {
    +    var i, p, ps;
    +
    +    /*
    +     * The Decimal constructor and exported function.
    +     * Return a new Decimal instance.
    +     *
    +     * v {number|string|Decimal} A numeric value.
    +     *
    +     */
    +    function Decimal(v) {
    +      var e, i, t,
    +        x = this;
    +
    +      // Decimal called without new.
    +      if (!(x instanceof Decimal)) return new Decimal(v);
    +
    +      // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor
    +      // which points to Object.
    +      x.constructor = Decimal;
    +
    +      // Duplicate.
    +      if (isDecimalInstance(v)) {
    +        x.s = v.s;
    +
    +        if (external) {
    +          if (!v.d || v.e > Decimal.maxE) {
    +
    +            // Infinity.
    +            x.e = NaN;
    +            x.d = null;
    +          } else if (v.e < Decimal.minE) {
    +
    +            // Zero.
    +            x.e = 0;
    +            x.d = [0];
    +          } else {
    +            x.e = v.e;
    +            x.d = v.d.slice();
    +          }
    +        } else {
    +          x.e = v.e;
    +          x.d = v.d ? v.d.slice() : v.d;
    +        }
    +
    +        return;
    +      }
    +
    +      t = typeof v;
    +
    +      if (t === 'number') {
    +        if (v === 0) {
    +          x.s = 1 / v < 0 ? -1 : 1;
    +          x.e = 0;
    +          x.d = [0];
    +          return;
    +        }
    +
    +        if (v < 0) {
    +          v = -v;
    +          x.s = -1;
    +        } else {
    +          x.s = 1;
    +        }
    +
    +        // Fast path for small integers.
    +        if (v === ~~v && v < 1e7) {
    +          for (e = 0, i = v; i >= 10; i /= 10) e++;
    +
    +          if (external) {
    +            if (e > Decimal.maxE) {
    +              x.e = NaN;
    +              x.d = null;
    +            } else if (e < Decimal.minE) {
    +              x.e = 0;
    +              x.d = [0];
    +            } else {
    +              x.e = e;
    +              x.d = [v];
    +            }
    +          } else {
    +            x.e = e;
    +            x.d = [v];
    +          }
    +
    +          return;
    +
    +        // Infinity, NaN.
    +        } else if (v * 0 !== 0) {
    +          if (!v) x.s = NaN;
    +          x.e = NaN;
    +          x.d = null;
    +          return;
    +        }
    +
    +        return parseDecimal(x, v.toString());
    +
    +      } else if (t !== 'string') {
    +        throw Error(invalidArgument + v);
    +      }
    +
    +      // Minus sign?
    +      if ((i = v.charCodeAt(0)) === 45) {
    +        v = v.slice(1);
    +        x.s = -1;
    +      } else {
    +        // Plus sign?
    +        if (i === 43) v = v.slice(1);
    +        x.s = 1;
    +      }
    +
    +      return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v);
    +    }
    +
    +    Decimal.prototype = P;
    +
    +    Decimal.ROUND_UP = 0;
    +    Decimal.ROUND_DOWN = 1;
    +    Decimal.ROUND_CEIL = 2;
    +    Decimal.ROUND_FLOOR = 3;
    +    Decimal.ROUND_HALF_UP = 4;
    +    Decimal.ROUND_HALF_DOWN = 5;
    +    Decimal.ROUND_HALF_EVEN = 6;
    +    Decimal.ROUND_HALF_CEIL = 7;
    +    Decimal.ROUND_HALF_FLOOR = 8;
    +    Decimal.EUCLID = 9;
    +
    +    Decimal.config = Decimal.set = config;
    +    Decimal.clone = clone;
    +    Decimal.isDecimal = isDecimalInstance;
    +
    +    Decimal.abs = abs;
    +    Decimal.acos = acos;
    +    Decimal.acosh = acosh;        // ES6
    +    Decimal.add = add;
    +    Decimal.asin = asin;
    +    Decimal.asinh = asinh;        // ES6
    +    Decimal.atan = atan;
    +    Decimal.atanh = atanh;        // ES6
    +    Decimal.atan2 = atan2;
    +    Decimal.cbrt = cbrt;          // ES6
    +    Decimal.ceil = ceil;
    +    Decimal.clamp = clamp;
    +    Decimal.cos = cos;
    +    Decimal.cosh = cosh;          // ES6
    +    Decimal.div = div;
    +    Decimal.exp = exp;
    +    Decimal.floor = floor;
    +    Decimal.hypot = hypot;        // ES6
    +    Decimal.ln = ln;
    +    Decimal.log = log;
    +    Decimal.log10 = log10;        // ES6
    +    Decimal.log2 = log2;          // ES6
    +    Decimal.max = max;
    +    Decimal.min = min;
    +    Decimal.mod = mod;
    +    Decimal.mul = mul;
    +    Decimal.pow = pow;
    +    Decimal.random = random;
    +    Decimal.round = round;
    +    Decimal.sign = sign;          // ES6
    +    Decimal.sin = sin;
    +    Decimal.sinh = sinh;          // ES6
    +    Decimal.sqrt = sqrt;
    +    Decimal.sub = sub;
    +    Decimal.sum = sum;
    +    Decimal.tan = tan;
    +    Decimal.tanh = tanh;          // ES6
    +    Decimal.trunc = trunc;        // ES6
    +
    +    if (obj === void 0) obj = {};
    +    if (obj) {
    +      if (obj.defaults !== true) {
    +        ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto'];
    +        for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p];
    +      }
    +    }
    +
    +    Decimal.config(obj);
    +
    +    return Decimal;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   * y {number|string|Decimal}
    +   *
    +   */
    +  function div(x, y) {
    +    return new this(x).div(y);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} The power to which to raise the base of the natural log.
    +   *
    +   */
    +  function exp(x) {
    +    return new this(x).exp();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function floor(x) {
    +    return finalise(x = new this(x), x.e + 1, 3);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the square root of the sum of the squares of the arguments,
    +   * rounded to `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...)
    +   *
    +   * arguments {number|string|Decimal}
    +   *
    +   */
    +  function hypot() {
    +    var i, n,
    +      t = new this(0);
    +
    +    external = false;
    +
    +    for (i = 0; i < arguments.length;) {
    +      n = new this(arguments[i++]);
    +      if (!n.d) {
    +        if (n.s) {
    +          external = true;
    +          return new this(1 / 0);
    +        }
    +        t = n;
    +      } else if (t.d) {
    +        t = t.plus(n.times(n));
    +      }
    +    }
    +
    +    external = true;
    +
    +    return t.sqrt();
    +  }
    +
    +
    +  /*
    +   * Return true if object is a Decimal instance (where Decimal is any Decimal constructor),
    +   * otherwise return false.
    +   *
    +   */
    +  function isDecimalInstance(obj) {
    +    return obj instanceof Decimal || obj && obj.toStringTag === tag || false;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function ln(x) {
    +    return new this(x).ln();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base
    +   * is specified, rounded to `precision` significant digits using rounding mode `rounding`.
    +   *
    +   * log[y](x)
    +   *
    +   * x {number|string|Decimal} The argument of the logarithm.
    +   * y {number|string|Decimal} The base of the logarithm.
    +   *
    +   */
    +  function log(x, y) {
    +    return new this(x).log(y);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function log2(x) {
    +    return new this(x).log(2);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function log10(x) {
    +    return new this(x).log(10);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the maximum of the arguments.
    +   *
    +   * arguments {number|string|Decimal}
    +   *
    +   */
    +  function max() {
    +    return maxOrMin(this, arguments, 'lt');
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the minimum of the arguments.
    +   *
    +   * arguments {number|string|Decimal}
    +   *
    +   */
    +  function min() {
    +    return maxOrMin(this, arguments, 'gt');
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits
    +   * using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   * y {number|string|Decimal}
    +   *
    +   */
    +  function mod(x, y) {
    +    return new this(x).mod(y);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   * y {number|string|Decimal}
    +   *
    +   */
    +  function mul(x, y) {
    +    return new this(x).mul(y);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} The base.
    +   * y {number|string|Decimal} The exponent.
    +   *
    +   */
    +  function pow(x, y) {
    +    return new this(x).pow(y);
    +  }
    +
    +
    +  /*
    +   * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with
    +   * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros
    +   * are produced).
    +   *
    +   * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive.
    +   *
    +   */
    +  function random(sd) {
    +    var d, e, k, n,
    +      i = 0,
    +      r = new this(1),
    +      rd = [];
    +
    +    if (sd === void 0) sd = this.precision;
    +    else checkInt32(sd, 1, MAX_DIGITS);
    +
    +    k = Math.ceil(sd / LOG_BASE);
    +
    +    if (!this.crypto) {
    +      for (; i < k;) rd[i++] = Math.random() * 1e7 | 0;
    +
    +    // Browsers supporting crypto.getRandomValues.
    +    } else if (crypto.getRandomValues) {
    +      d = crypto.getRandomValues(new Uint32Array(k));
    +
    +      for (; i < k;) {
    +        n = d[i];
    +
    +        // 0 <= n < 4294967296
    +        // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865).
    +        if (n >= 4.29e9) {
    +          d[i] = crypto.getRandomValues(new Uint32Array(1))[0];
    +        } else {
    +
    +          // 0 <= n <= 4289999999
    +          // 0 <= (n % 1e7) <= 9999999
    +          rd[i++] = n % 1e7;
    +        }
    +      }
    +
    +    // Node.js supporting crypto.randomBytes.
    +    } else if (crypto.randomBytes) {
    +
    +      // buffer
    +      d = crypto.randomBytes(k *= 4);
    +
    +      for (; i < k;) {
    +
    +        // 0 <= n < 2147483648
    +        n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24);
    +
    +        // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286).
    +        if (n >= 2.14e9) {
    +          crypto.randomBytes(4).copy(d, i);
    +        } else {
    +
    +          // 0 <= n <= 2139999999
    +          // 0 <= (n % 1e7) <= 9999999
    +          rd.push(n % 1e7);
    +          i += 4;
    +        }
    +      }
    +
    +      i = k / 4;
    +    } else {
    +      throw Error(cryptoUnavailable);
    +    }
    +
    +    k = rd[--i];
    +    sd %= LOG_BASE;
    +
    +    // Convert trailing digits to zeros according to sd.
    +    if (k && sd) {
    +      n = mathpow(10, LOG_BASE - sd);
    +      rd[i] = (k / n | 0) * n;
    +    }
    +
    +    // Remove trailing words which are zero.
    +    for (; rd[i] === 0; i--) rd.pop();
    +
    +    // Zero?
    +    if (i < 0) {
    +      e = 0;
    +      rd = [0];
    +    } else {
    +      e = -1;
    +
    +      // Remove leading words which are zero and adjust exponent accordingly.
    +      for (; rd[0] === 0; e -= LOG_BASE) rd.shift();
    +
    +      // Count the digits of the first word of rd to determine leading zeros.
    +      for (k = 1, n = rd[0]; n >= 10; n /= 10) k++;
    +
    +      // Adjust the exponent for leading zeros of the first word of rd.
    +      if (k < LOG_BASE) e -= LOG_BASE - k;
    +    }
    +
    +    r.e = e;
    +    r.d = rd;
    +
    +    return r;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`.
    +   *
    +   * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL).
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function round(x) {
    +    return finalise(x = new this(x), x.e + 1, this.rounding);
    +  }
    +
    +
    +  /*
    +   * Return
    +   *   1    if x > 0,
    +   *  -1    if x < 0,
    +   *   0    if x is 0,
    +   *  -0    if x is -0,
    +   *   NaN  otherwise
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function sign(x) {
    +    x = new this(x);
    +    return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN;
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits
    +   * using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function sin(x) {
    +    return new this(x).sin();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function sinh(x) {
    +    return new this(x).sinh();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function sqrt(x) {
    +    return new this(x).sqrt();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits
    +   * using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal}
    +   * y {number|string|Decimal}
    +   *
    +   */
    +  function sub(x, y) {
    +    return new this(x).sub(y);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the sum of the arguments, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * Only the result is rounded, not the intermediate calculations.
    +   *
    +   * arguments {number|string|Decimal}
    +   *
    +   */
    +  function sum() {
    +    var i = 0,
    +      args = arguments,
    +      x = new this(args[i]);
    +
    +    external = false;
    +    for (; x.s && ++i < args.length;) x = x.plus(args[i]);
    +    external = true;
    +
    +    return finalise(x, this.precision, this.rounding);
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant
    +   * digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function tan(x) {
    +    return new this(x).tan();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision`
    +   * significant digits using rounding mode `rounding`.
    +   *
    +   * x {number|string|Decimal} A value in radians.
    +   *
    +   */
    +  function tanh(x) {
    +    return new this(x).tanh();
    +  }
    +
    +
    +  /*
    +   * Return a new Decimal whose value is `x` truncated to an integer.
    +   *
    +   * x {number|string|Decimal}
    +   *
    +   */
    +  function trunc(x) {
    +    return finalise(x = new this(x), x.e + 1, 1);
    +  }
    +
    +
    +  // Create and configure initial Decimal constructor.
    +  Decimal = clone(DEFAULTS);
    +  Decimal.prototype.constructor = Decimal;
    +  Decimal['default'] = Decimal.Decimal = Decimal;
    +
    +  // Create the internal constants from their string values.
    +  LN10 = new Decimal(LN10);
    +  PI = new Decimal(PI);
    +
    +
    +  // Export.
    +
    +
    +  // AMD.
    +  if ( module.exports) {
    +    if (typeof Symbol == 'function' && typeof Symbol.iterator == 'symbol') {
    +      P[Symbol['for']('nodejs.util.inspect.custom')] = P.toString;
    +      P[Symbol.toStringTag] = 'Decimal';
    +    }
    +
    +    module.exports = Decimal;
    +
    +  // Browser.
    +  } else {
    +    if (!globalScope) {
    +      globalScope = typeof self != 'undefined' && self && self.self == self ? self : window;
    +    }
    +
    +    noConflict = globalScope.Decimal;
    +    Decimal.noConflict = function () {
    +      globalScope.Decimal = noConflict;
    +      return Decimal;
    +    };
    +
    +    globalScope.Decimal = Decimal;
    +  }
    +})(commonjsGlobal);
    +});
    +
    +var lodash = createCommonjsModule(function (module, exports) {
    +(function() {
    +
    +  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
    +  var undefined$1;
    +
    +  /** Used as the semantic version number. */
    +  var VERSION = '4.17.20';
    +
    +  /** Used as the size to enable large array optimizations. */
    +  var LARGE_ARRAY_SIZE = 200;
    +
    +  /** Error message constants. */
    +  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
    +      FUNC_ERROR_TEXT = 'Expected a function';
    +
    +  /** Used to stand-in for `undefined` hash values. */
    +  var HASH_UNDEFINED = '__lodash_hash_undefined__';
    +
    +  /** Used as the maximum memoize cache size. */
    +  var MAX_MEMOIZE_SIZE = 500;
    +
    +  /** Used as the internal argument placeholder. */
    +  var PLACEHOLDER = '__lodash_placeholder__';
    +
    +  /** Used to compose bitmasks for cloning. */
    +  var CLONE_DEEP_FLAG = 1,
    +      CLONE_FLAT_FLAG = 2,
    +      CLONE_SYMBOLS_FLAG = 4;
    +
    +  /** Used to compose bitmasks for value comparisons. */
    +  var COMPARE_PARTIAL_FLAG = 1,
    +      COMPARE_UNORDERED_FLAG = 2;
    +
    +  /** Used to compose bitmasks for function metadata. */
    +  var WRAP_BIND_FLAG = 1,
    +      WRAP_BIND_KEY_FLAG = 2,
    +      WRAP_CURRY_BOUND_FLAG = 4,
    +      WRAP_CURRY_FLAG = 8,
    +      WRAP_CURRY_RIGHT_FLAG = 16,
    +      WRAP_PARTIAL_FLAG = 32,
    +      WRAP_PARTIAL_RIGHT_FLAG = 64,
    +      WRAP_ARY_FLAG = 128,
    +      WRAP_REARG_FLAG = 256,
    +      WRAP_FLIP_FLAG = 512;
    +
    +  /** Used as default options for `_.truncate`. */
    +  var DEFAULT_TRUNC_LENGTH = 30,
    +      DEFAULT_TRUNC_OMISSION = '...';
    +
    +  /** Used to detect hot functions by number of calls within a span of milliseconds. */
    +  var HOT_COUNT = 800,
    +      HOT_SPAN = 16;
    +
    +  /** Used to indicate the type of lazy iteratees. */
    +  var LAZY_FILTER_FLAG = 1,
    +      LAZY_MAP_FLAG = 2,
    +      LAZY_WHILE_FLAG = 3;
    +
    +  /** Used as references for various `Number` constants. */
    +  var INFINITY = 1 / 0,
    +      MAX_SAFE_INTEGER = 9007199254740991,
    +      MAX_INTEGER = 1.7976931348623157e+308,
    +      NAN = 0 / 0;
    +
    +  /** Used as references for the maximum length and index of an array. */
    +  var MAX_ARRAY_LENGTH = 4294967295,
    +      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
    +      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
    +
    +  /** Used to associate wrap methods with their bit flags. */
    +  var wrapFlags = [
    +    ['ary', WRAP_ARY_FLAG],
    +    ['bind', WRAP_BIND_FLAG],
    +    ['bindKey', WRAP_BIND_KEY_FLAG],
    +    ['curry', WRAP_CURRY_FLAG],
    +    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
    +    ['flip', WRAP_FLIP_FLAG],
    +    ['partial', WRAP_PARTIAL_FLAG],
    +    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
    +    ['rearg', WRAP_REARG_FLAG]
    +  ];
    +
    +  /** `Object#toString` result references. */
    +  var argsTag = '[object Arguments]',
    +      arrayTag = '[object Array]',
    +      asyncTag = '[object AsyncFunction]',
    +      boolTag = '[object Boolean]',
    +      dateTag = '[object Date]',
    +      domExcTag = '[object DOMException]',
    +      errorTag = '[object Error]',
    +      funcTag = '[object Function]',
    +      genTag = '[object GeneratorFunction]',
    +      mapTag = '[object Map]',
    +      numberTag = '[object Number]',
    +      nullTag = '[object Null]',
    +      objectTag = '[object Object]',
    +      promiseTag = '[object Promise]',
    +      proxyTag = '[object Proxy]',
    +      regexpTag = '[object RegExp]',
    +      setTag = '[object Set]',
    +      stringTag = '[object String]',
    +      symbolTag = '[object Symbol]',
    +      undefinedTag = '[object Undefined]',
    +      weakMapTag = '[object WeakMap]',
    +      weakSetTag = '[object WeakSet]';
    +
    +  var arrayBufferTag = '[object ArrayBuffer]',
    +      dataViewTag = '[object DataView]',
    +      float32Tag = '[object Float32Array]',
    +      float64Tag = '[object Float64Array]',
    +      int8Tag = '[object Int8Array]',
    +      int16Tag = '[object Int16Array]',
    +      int32Tag = '[object Int32Array]',
    +      uint8Tag = '[object Uint8Array]',
    +      uint8ClampedTag = '[object Uint8ClampedArray]',
    +      uint16Tag = '[object Uint16Array]',
    +      uint32Tag = '[object Uint32Array]';
    +
    +  /** Used to match empty string literals in compiled template source. */
    +  var reEmptyStringLeading = /\b__p \+= '';/g,
    +      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
    +      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
    +
    +  /** Used to match HTML entities and HTML characters. */
    +  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
    +      reUnescapedHtml = /[&<>"']/g,
    +      reHasEscapedHtml = RegExp(reEscapedHtml.source),
    +      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
    +
    +  /** Used to match template delimiters. */
    +  var reEscape = /<%-([\s\S]+?)%>/g,
    +      reEvaluate = /<%([\s\S]+?)%>/g,
    +      reInterpolate = /<%=([\s\S]+?)%>/g;
    +
    +  /** Used to match property names within property paths. */
    +  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
    +      reIsPlainProp = /^\w*$/,
    +      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
    +
    +  /**
    +   * Used to match `RegExp`
    +   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
    +   */
    +  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
    +      reHasRegExpChar = RegExp(reRegExpChar.source);
    +
    +  /** Used to match leading and trailing whitespace. */
    +  var reTrim = /^\s+|\s+$/g,
    +      reTrimStart = /^\s+/,
    +      reTrimEnd = /\s+$/;
    +
    +  /** Used to match wrap detail comments. */
    +  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
    +      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
    +      reSplitDetails = /,? & /;
    +
    +  /** Used to match words composed of alphanumeric characters. */
    +  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
    +
    +  /** Used to match backslashes in property paths. */
    +  var reEscapeChar = /\\(\\)?/g;
    +
    +  /**
    +   * Used to match
    +   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
    +   */
    +  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
    +
    +  /** Used to match `RegExp` flags from their coerced string values. */
    +  var reFlags = /\w*$/;
    +
    +  /** Used to detect bad signed hexadecimal string values. */
    +  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
    +
    +  /** Used to detect binary string values. */
    +  var reIsBinary = /^0b[01]+$/i;
    +
    +  /** Used to detect host constructors (Safari). */
    +  var reIsHostCtor = /^\[object .+?Constructor\]$/;
    +
    +  /** Used to detect octal string values. */
    +  var reIsOctal = /^0o[0-7]+$/i;
    +
    +  /** Used to detect unsigned integer values. */
    +  var reIsUint = /^(?:0|[1-9]\d*)$/;
    +
    +  /** Used to match Latin Unicode letters (excluding mathematical operators). */
    +  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
    +
    +  /** Used to ensure capturing order of template delimiters. */
    +  var reNoMatch = /($^)/;
    +
    +  /** Used to match unescaped characters in compiled string literals. */
    +  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
    +
    +  /** Used to compose unicode character classes. */
    +  var rsAstralRange = '\\ud800-\\udfff',
    +      rsComboMarksRange = '\\u0300-\\u036f',
    +      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
    +      rsComboSymbolsRange = '\\u20d0-\\u20ff',
    +      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
    +      rsDingbatRange = '\\u2700-\\u27bf',
    +      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
    +      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
    +      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
    +      rsPunctuationRange = '\\u2000-\\u206f',
    +      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
    +      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
    +      rsVarRange = '\\ufe0e\\ufe0f',
    +      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
    +
    +  /** Used to compose unicode capture groups. */
    +  var rsApos = "['\u2019]",
    +      rsAstral = '[' + rsAstralRange + ']',
    +      rsBreak = '[' + rsBreakRange + ']',
    +      rsCombo = '[' + rsComboRange + ']',
    +      rsDigits = '\\d+',
    +      rsDingbat = '[' + rsDingbatRange + ']',
    +      rsLower = '[' + rsLowerRange + ']',
    +      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
    +      rsFitz = '\\ud83c[\\udffb-\\udfff]',
    +      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
    +      rsNonAstral = '[^' + rsAstralRange + ']',
    +      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
    +      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
    +      rsUpper = '[' + rsUpperRange + ']',
    +      rsZWJ = '\\u200d';
    +
    +  /** Used to compose unicode regexes. */
    +  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
    +      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
    +      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
    +      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
    +      reOptMod = rsModifier + '?',
    +      rsOptVar = '[' + rsVarRange + ']?',
    +      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
    +      rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
    +      rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
    +      rsSeq = rsOptVar + reOptMod + rsOptJoin,
    +      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
    +      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
    +
    +  /** Used to match apostrophes. */
    +  var reApos = RegExp(rsApos, 'g');
    +
    +  /**
    +   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
    +   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
    +   */
    +  var reComboMark = RegExp(rsCombo, 'g');
    +
    +  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
    +  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
    +
    +  /** Used to match complex or compound words. */
    +  var reUnicodeWord = RegExp([
    +    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
    +    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
    +    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
    +    rsUpper + '+' + rsOptContrUpper,
    +    rsOrdUpper,
    +    rsOrdLower,
    +    rsDigits,
    +    rsEmoji
    +  ].join('|'), 'g');
    +
    +  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
    +  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
    +
    +  /** Used to detect strings that need a more robust regexp to match words. */
    +  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
    +
    +  /** Used to assign default `context` object properties. */
    +  var contextProps = [
    +    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
    +    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
    +    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
    +    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
    +    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
    +  ];
    +
    +  /** Used to make template sourceURLs easier to identify. */
    +  var templateCounter = -1;
    +
    +  /** Used to identify `toStringTag` values of typed arrays. */
    +  var typedArrayTags = {};
    +  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
    +  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
    +  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
    +  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
    +  typedArrayTags[uint32Tag] = true;
    +  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
    +  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
    +  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
    +  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
    +  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
    +  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
    +  typedArrayTags[setTag] = typedArrayTags[stringTag] =
    +  typedArrayTags[weakMapTag] = false;
    +
    +  /** Used to identify `toStringTag` values supported by `_.clone`. */
    +  var cloneableTags = {};
    +  cloneableTags[argsTag] = cloneableTags[arrayTag] =
    +  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
    +  cloneableTags[boolTag] = cloneableTags[dateTag] =
    +  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
    +  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
    +  cloneableTags[int32Tag] = cloneableTags[mapTag] =
    +  cloneableTags[numberTag] = cloneableTags[objectTag] =
    +  cloneableTags[regexpTag] = cloneableTags[setTag] =
    +  cloneableTags[stringTag] = cloneableTags[symbolTag] =
    +  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
    +  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
    +  cloneableTags[errorTag] = cloneableTags[funcTag] =
    +  cloneableTags[weakMapTag] = false;
    +
    +  /** Used to map Latin Unicode letters to basic Latin letters. */
    +  var deburredLetters = {
    +    // Latin-1 Supplement block.
    +    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
    +    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
    +    '\xc7': 'C',  '\xe7': 'c',
    +    '\xd0': 'D',  '\xf0': 'd',
    +    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
    +    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
    +    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
    +    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
    +    '\xd1': 'N',  '\xf1': 'n',
    +    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
    +    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
    +    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
    +    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
    +    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
    +    '\xc6': 'Ae', '\xe6': 'ae',
    +    '\xde': 'Th', '\xfe': 'th',
    +    '\xdf': 'ss',
    +    // Latin Extended-A block.
    +    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
    +    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
    +    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
    +    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
    +    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
    +    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
    +    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
    +    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
    +    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
    +    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
    +    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
    +    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
    +    '\u0134': 'J',  '\u0135': 'j',
    +    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
    +    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
    +    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
    +    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
    +    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
    +    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
    +    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
    +    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
    +    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
    +    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
    +    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
    +    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
    +    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
    +    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
    +    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
    +    '\u0174': 'W',  '\u0175': 'w',
    +    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
    +    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
    +    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
    +    '\u0132': 'IJ', '\u0133': 'ij',
    +    '\u0152': 'Oe', '\u0153': 'oe',
    +    '\u0149': "'n", '\u017f': 's'
    +  };
    +
    +  /** Used to map characters to HTML entities. */
    +  var htmlEscapes = {
    +    '&': '&',
    +    '<': '<',
    +    '>': '>',
    +    '"': '"',
    +    "'": '''
    +  };
    +
    +  /** Used to map HTML entities to characters. */
    +  var htmlUnescapes = {
    +    '&': '&',
    +    '<': '<',
    +    '>': '>',
    +    '"': '"',
    +    ''': "'"
    +  };
    +
    +  /** Used to escape characters for inclusion in compiled string literals. */
    +  var stringEscapes = {
    +    '\\': '\\',
    +    "'": "'",
    +    '\n': 'n',
    +    '\r': 'r',
    +    '\u2028': 'u2028',
    +    '\u2029': 'u2029'
    +  };
    +
    +  /** Built-in method references without a dependency on `root`. */
    +  var freeParseFloat = parseFloat,
    +      freeParseInt = parseInt;
    +
    +  /** Detect free variable `global` from Node.js. */
    +  var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
    +
    +  /** Detect free variable `self`. */
    +  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
    +
    +  /** Used as a reference to the global object. */
    +  var root = freeGlobal || freeSelf || Function('return this')();
    +
    +  /** Detect free variable `exports`. */
    +  var freeExports =  exports && !exports.nodeType && exports;
    +
    +  /** Detect free variable `module`. */
    +  var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
    +
    +  /** Detect the popular CommonJS extension `module.exports`. */
    +  var moduleExports = freeModule && freeModule.exports === freeExports;
    +
    +  /** Detect free variable `process` from Node.js. */
    +  var freeProcess = moduleExports && freeGlobal.process;
    +
    +  /** Used to access faster Node.js helpers. */
    +  var nodeUtil = (function() {
    +    try {
    +      // Use `util.types` for Node.js 10+.
    +      var types = freeModule && freeModule.require && freeModule.require('util').types;
    +
    +      if (types) {
    +        return types;
    +      }
    +
    +      // Legacy `process.binding('util')` for Node.js < 10.
    +      return freeProcess && freeProcess.binding && freeProcess.binding('util');
    +    } catch (e) {}
    +  }());
    +
    +  /* Node.js helper references. */
    +  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
    +      nodeIsDate = nodeUtil && nodeUtil.isDate,
    +      nodeIsMap = nodeUtil && nodeUtil.isMap,
    +      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
    +      nodeIsSet = nodeUtil && nodeUtil.isSet,
    +      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
    +
    +  /*--------------------------------------------------------------------------*/
    +
    +  /**
    +   * A faster alternative to `Function#apply`, this function invokes `func`
    +   * with the `this` binding of `thisArg` and the arguments of `args`.
    +   *
    +   * @private
    +   * @param {Function} func The function to invoke.
    +   * @param {*} thisArg The `this` binding of `func`.
    +   * @param {Array} args The arguments to invoke `func` with.
    +   * @returns {*} Returns the result of `func`.
    +   */
    +  function apply(func, thisArg, args) {
    +    switch (args.length) {
    +      case 0: return func.call(thisArg);
    +      case 1: return func.call(thisArg, args[0]);
    +      case 2: return func.call(thisArg, args[0], args[1]);
    +      case 3: return func.call(thisArg, args[0], args[1], args[2]);
    +    }
    +    return func.apply(thisArg, args);
    +  }
    +
    +  /**
    +   * A specialized version of `baseAggregator` for arrays.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} setter The function to set `accumulator` values.
    +   * @param {Function} iteratee The iteratee to transform keys.
    +   * @param {Object} accumulator The initial aggregated object.
    +   * @returns {Function} Returns `accumulator`.
    +   */
    +  function arrayAggregator(array, setter, iteratee, accumulator) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length;
    +
    +    while (++index < length) {
    +      var value = array[index];
    +      setter(accumulator, value, iteratee(value), array);
    +    }
    +    return accumulator;
    +  }
    +
    +  /**
    +   * A specialized version of `_.forEach` for arrays without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @returns {Array} Returns `array`.
    +   */
    +  function arrayEach(array, iteratee) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length;
    +
    +    while (++index < length) {
    +      if (iteratee(array[index], index, array) === false) {
    +        break;
    +      }
    +    }
    +    return array;
    +  }
    +
    +  /**
    +   * A specialized version of `_.forEachRight` for arrays without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @returns {Array} Returns `array`.
    +   */
    +  function arrayEachRight(array, iteratee) {
    +    var length = array == null ? 0 : array.length;
    +
    +    while (length--) {
    +      if (iteratee(array[length], length, array) === false) {
    +        break;
    +      }
    +    }
    +    return array;
    +  }
    +
    +  /**
    +   * A specialized version of `_.every` for arrays without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} predicate The function invoked per iteration.
    +   * @returns {boolean} Returns `true` if all elements pass the predicate check,
    +   *  else `false`.
    +   */
    +  function arrayEvery(array, predicate) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length;
    +
    +    while (++index < length) {
    +      if (!predicate(array[index], index, array)) {
    +        return false;
    +      }
    +    }
    +    return true;
    +  }
    +
    +  /**
    +   * A specialized version of `_.filter` for arrays without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} predicate The function invoked per iteration.
    +   * @returns {Array} Returns the new filtered array.
    +   */
    +  function arrayFilter(array, predicate) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length,
    +        resIndex = 0,
    +        result = [];
    +
    +    while (++index < length) {
    +      var value = array[index];
    +      if (predicate(value, index, array)) {
    +        result[resIndex++] = value;
    +      }
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * A specialized version of `_.includes` for arrays without support for
    +   * specifying an index to search from.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to inspect.
    +   * @param {*} target The value to search for.
    +   * @returns {boolean} Returns `true` if `target` is found, else `false`.
    +   */
    +  function arrayIncludes(array, value) {
    +    var length = array == null ? 0 : array.length;
    +    return !!length && baseIndexOf(array, value, 0) > -1;
    +  }
    +
    +  /**
    +   * This function is like `arrayIncludes` except that it accepts a comparator.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to inspect.
    +   * @param {*} target The value to search for.
    +   * @param {Function} comparator The comparator invoked per element.
    +   * @returns {boolean} Returns `true` if `target` is found, else `false`.
    +   */
    +  function arrayIncludesWith(array, value, comparator) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length;
    +
    +    while (++index < length) {
    +      if (comparator(value, array[index])) {
    +        return true;
    +      }
    +    }
    +    return false;
    +  }
    +
    +  /**
    +   * A specialized version of `_.map` for arrays without support for iteratee
    +   * shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @returns {Array} Returns the new mapped array.
    +   */
    +  function arrayMap(array, iteratee) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length,
    +        result = Array(length);
    +
    +    while (++index < length) {
    +      result[index] = iteratee(array[index], index, array);
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Appends the elements of `values` to `array`.
    +   *
    +   * @private
    +   * @param {Array} array The array to modify.
    +   * @param {Array} values The values to append.
    +   * @returns {Array} Returns `array`.
    +   */
    +  function arrayPush(array, values) {
    +    var index = -1,
    +        length = values.length,
    +        offset = array.length;
    +
    +    while (++index < length) {
    +      array[offset + index] = values[index];
    +    }
    +    return array;
    +  }
    +
    +  /**
    +   * A specialized version of `_.reduce` for arrays without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @param {*} [accumulator] The initial value.
    +   * @param {boolean} [initAccum] Specify using the first element of `array` as
    +   *  the initial value.
    +   * @returns {*} Returns the accumulated value.
    +   */
    +  function arrayReduce(array, iteratee, accumulator, initAccum) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length;
    +
    +    if (initAccum && length) {
    +      accumulator = array[++index];
    +    }
    +    while (++index < length) {
    +      accumulator = iteratee(accumulator, array[index], index, array);
    +    }
    +    return accumulator;
    +  }
    +
    +  /**
    +   * A specialized version of `_.reduceRight` for arrays without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @param {*} [accumulator] The initial value.
    +   * @param {boolean} [initAccum] Specify using the last element of `array` as
    +   *  the initial value.
    +   * @returns {*} Returns the accumulated value.
    +   */
    +  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
    +    var length = array == null ? 0 : array.length;
    +    if (initAccum && length) {
    +      accumulator = array[--length];
    +    }
    +    while (length--) {
    +      accumulator = iteratee(accumulator, array[length], length, array);
    +    }
    +    return accumulator;
    +  }
    +
    +  /**
    +   * A specialized version of `_.some` for arrays without support for iteratee
    +   * shorthands.
    +   *
    +   * @private
    +   * @param {Array} [array] The array to iterate over.
    +   * @param {Function} predicate The function invoked per iteration.
    +   * @returns {boolean} Returns `true` if any element passes the predicate check,
    +   *  else `false`.
    +   */
    +  function arraySome(array, predicate) {
    +    var index = -1,
    +        length = array == null ? 0 : array.length;
    +
    +    while (++index < length) {
    +      if (predicate(array[index], index, array)) {
    +        return true;
    +      }
    +    }
    +    return false;
    +  }
    +
    +  /**
    +   * Gets the size of an ASCII `string`.
    +   *
    +   * @private
    +   * @param {string} string The string inspect.
    +   * @returns {number} Returns the string size.
    +   */
    +  var asciiSize = baseProperty('length');
    +
    +  /**
    +   * Converts an ASCII `string` to an array.
    +   *
    +   * @private
    +   * @param {string} string The string to convert.
    +   * @returns {Array} Returns the converted array.
    +   */
    +  function asciiToArray(string) {
    +    return string.split('');
    +  }
    +
    +  /**
    +   * Splits an ASCII `string` into an array of its words.
    +   *
    +   * @private
    +   * @param {string} The string to inspect.
    +   * @returns {Array} Returns the words of `string`.
    +   */
    +  function asciiWords(string) {
    +    return string.match(reAsciiWord) || [];
    +  }
    +
    +  /**
    +   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
    +   * without support for iteratee shorthands, which iterates over `collection`
    +   * using `eachFunc`.
    +   *
    +   * @private
    +   * @param {Array|Object} collection The collection to inspect.
    +   * @param {Function} predicate The function invoked per iteration.
    +   * @param {Function} eachFunc The function to iterate over `collection`.
    +   * @returns {*} Returns the found element or its key, else `undefined`.
    +   */
    +  function baseFindKey(collection, predicate, eachFunc) {
    +    var result;
    +    eachFunc(collection, function(value, key, collection) {
    +      if (predicate(value, key, collection)) {
    +        result = key;
    +        return false;
    +      }
    +    });
    +    return result;
    +  }
    +
    +  /**
    +   * The base implementation of `_.findIndex` and `_.findLastIndex` without
    +   * support for iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} array The array to inspect.
    +   * @param {Function} predicate The function invoked per iteration.
    +   * @param {number} fromIndex The index to search from.
    +   * @param {boolean} [fromRight] Specify iterating from right to left.
    +   * @returns {number} Returns the index of the matched value, else `-1`.
    +   */
    +  function baseFindIndex(array, predicate, fromIndex, fromRight) {
    +    var length = array.length,
    +        index = fromIndex + (fromRight ? 1 : -1);
    +
    +    while ((fromRight ? index-- : ++index < length)) {
    +      if (predicate(array[index], index, array)) {
    +        return index;
    +      }
    +    }
    +    return -1;
    +  }
    +
    +  /**
    +   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
    +   *
    +   * @private
    +   * @param {Array} array The array to inspect.
    +   * @param {*} value The value to search for.
    +   * @param {number} fromIndex The index to search from.
    +   * @returns {number} Returns the index of the matched value, else `-1`.
    +   */
    +  function baseIndexOf(array, value, fromIndex) {
    +    return value === value
    +      ? strictIndexOf(array, value, fromIndex)
    +      : baseFindIndex(array, baseIsNaN, fromIndex);
    +  }
    +
    +  /**
    +   * This function is like `baseIndexOf` except that it accepts a comparator.
    +   *
    +   * @private
    +   * @param {Array} array The array to inspect.
    +   * @param {*} value The value to search for.
    +   * @param {number} fromIndex The index to search from.
    +   * @param {Function} comparator The comparator invoked per element.
    +   * @returns {number} Returns the index of the matched value, else `-1`.
    +   */
    +  function baseIndexOfWith(array, value, fromIndex, comparator) {
    +    var index = fromIndex - 1,
    +        length = array.length;
    +
    +    while (++index < length) {
    +      if (comparator(array[index], value)) {
    +        return index;
    +      }
    +    }
    +    return -1;
    +  }
    +
    +  /**
    +   * The base implementation of `_.isNaN` without support for number objects.
    +   *
    +   * @private
    +   * @param {*} value The value to check.
    +   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
    +   */
    +  function baseIsNaN(value) {
    +    return value !== value;
    +  }
    +
    +  /**
    +   * The base implementation of `_.mean` and `_.meanBy` without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} array The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @returns {number} Returns the mean.
    +   */
    +  function baseMean(array, iteratee) {
    +    var length = array == null ? 0 : array.length;
    +    return length ? (baseSum(array, iteratee) / length) : NAN;
    +  }
    +
    +  /**
    +   * The base implementation of `_.property` without support for deep paths.
    +   *
    +   * @private
    +   * @param {string} key The key of the property to get.
    +   * @returns {Function} Returns the new accessor function.
    +   */
    +  function baseProperty(key) {
    +    return function(object) {
    +      return object == null ? undefined$1 : object[key];
    +    };
    +  }
    +
    +  /**
    +   * The base implementation of `_.propertyOf` without support for deep paths.
    +   *
    +   * @private
    +   * @param {Object} object The object to query.
    +   * @returns {Function} Returns the new accessor function.
    +   */
    +  function basePropertyOf(object) {
    +    return function(key) {
    +      return object == null ? undefined$1 : object[key];
    +    };
    +  }
    +
    +  /**
    +   * The base implementation of `_.reduce` and `_.reduceRight`, without support
    +   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
    +   *
    +   * @private
    +   * @param {Array|Object} collection The collection to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @param {*} accumulator The initial value.
    +   * @param {boolean} initAccum Specify using the first or last element of
    +   *  `collection` as the initial value.
    +   * @param {Function} eachFunc The function to iterate over `collection`.
    +   * @returns {*} Returns the accumulated value.
    +   */
    +  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
    +    eachFunc(collection, function(value, index, collection) {
    +      accumulator = initAccum
    +        ? (initAccum = false, value)
    +        : iteratee(accumulator, value, index, collection);
    +    });
    +    return accumulator;
    +  }
    +
    +  /**
    +   * The base implementation of `_.sortBy` which uses `comparer` to define the
    +   * sort order of `array` and replaces criteria objects with their corresponding
    +   * values.
    +   *
    +   * @private
    +   * @param {Array} array The array to sort.
    +   * @param {Function} comparer The function to define sort order.
    +   * @returns {Array} Returns `array`.
    +   */
    +  function baseSortBy(array, comparer) {
    +    var length = array.length;
    +
    +    array.sort(comparer);
    +    while (length--) {
    +      array[length] = array[length].value;
    +    }
    +    return array;
    +  }
    +
    +  /**
    +   * The base implementation of `_.sum` and `_.sumBy` without support for
    +   * iteratee shorthands.
    +   *
    +   * @private
    +   * @param {Array} array The array to iterate over.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @returns {number} Returns the sum.
    +   */
    +  function baseSum(array, iteratee) {
    +    var result,
    +        index = -1,
    +        length = array.length;
    +
    +    while (++index < length) {
    +      var current = iteratee(array[index]);
    +      if (current !== undefined$1) {
    +        result = result === undefined$1 ? current : (result + current);
    +      }
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * The base implementation of `_.times` without support for iteratee shorthands
    +   * or max array length checks.
    +   *
    +   * @private
    +   * @param {number} n The number of times to invoke `iteratee`.
    +   * @param {Function} iteratee The function invoked per iteration.
    +   * @returns {Array} Returns the array of results.
    +   */
    +  function baseTimes(n, iteratee) {
    +    var index = -1,
    +        result = Array(n);
    +
    +    while (++index < n) {
    +      result[index] = iteratee(index);
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
    +   * of key-value pairs for `object` corresponding to the property names of `props`.
    +   *
    +   * @private
    +   * @param {Object} object The object to query.
    +   * @param {Array} props The property names to get values for.
    +   * @returns {Object} Returns the key-value pairs.
    +   */
    +  function baseToPairs(object, props) {
    +    return arrayMap(props, function(key) {
    +      return [key, object[key]];
    +    });
    +  }
    +
    +  /**
    +   * The base implementation of `_.unary` without support for storing metadata.
    +   *
    +   * @private
    +   * @param {Function} func The function to cap arguments for.
    +   * @returns {Function} Returns the new capped function.
    +   */
    +  function baseUnary(func) {
    +    return function(value) {
    +      return func(value);
    +    };
    +  }
    +
    +  /**
    +   * The base implementation of `_.values` and `_.valuesIn` which creates an
    +   * array of `object` property values corresponding to the property names
    +   * of `props`.
    +   *
    +   * @private
    +   * @param {Object} object The object to query.
    +   * @param {Array} props The property names to get values for.
    +   * @returns {Object} Returns the array of property values.
    +   */
    +  function baseValues(object, props) {
    +    return arrayMap(props, function(key) {
    +      return object[key];
    +    });
    +  }
    +
    +  /**
    +   * Checks if a `cache` value for `key` exists.
    +   *
    +   * @private
    +   * @param {Object} cache The cache to query.
    +   * @param {string} key The key of the entry to check.
    +   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
    +   */
    +  function cacheHas(cache, key) {
    +    return cache.has(key);
    +  }
    +
    +  /**
    +   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
    +   * that is not found in the character symbols.
    +   *
    +   * @private
    +   * @param {Array} strSymbols The string symbols to inspect.
    +   * @param {Array} chrSymbols The character symbols to find.
    +   * @returns {number} Returns the index of the first unmatched string symbol.
    +   */
    +  function charsStartIndex(strSymbols, chrSymbols) {
    +    var index = -1,
    +        length = strSymbols.length;
    +
    +    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
    +    return index;
    +  }
    +
    +  /**
    +   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
    +   * that is not found in the character symbols.
    +   *
    +   * @private
    +   * @param {Array} strSymbols The string symbols to inspect.
    +   * @param {Array} chrSymbols The character symbols to find.
    +   * @returns {number} Returns the index of the last unmatched string symbol.
    +   */
    +  function charsEndIndex(strSymbols, chrSymbols) {
    +    var index = strSymbols.length;
    +
    +    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
    +    return index;
    +  }
    +
    +  /**
    +   * Gets the number of `placeholder` occurrences in `array`.
    +   *
    +   * @private
    +   * @param {Array} array The array to inspect.
    +   * @param {*} placeholder The placeholder to search for.
    +   * @returns {number} Returns the placeholder count.
    +   */
    +  function countHolders(array, placeholder) {
    +    var length = array.length,
    +        result = 0;
    +
    +    while (length--) {
    +      if (array[length] === placeholder) {
    +        ++result;
    +      }
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
    +   * letters to basic Latin letters.
    +   *
    +   * @private
    +   * @param {string} letter The matched letter to deburr.
    +   * @returns {string} Returns the deburred letter.
    +   */
    +  var deburrLetter = basePropertyOf(deburredLetters);
    +
    +  /**
    +   * Used by `_.escape` to convert characters to HTML entities.
    +   *
    +   * @private
    +   * @param {string} chr The matched character to escape.
    +   * @returns {string} Returns the escaped character.
    +   */
    +  var escapeHtmlChar = basePropertyOf(htmlEscapes);
    +
    +  /**
    +   * Used by `_.template` to escape characters for inclusion in compiled string literals.
    +   *
    +   * @private
    +   * @param {string} chr The matched character to escape.
    +   * @returns {string} Returns the escaped character.
    +   */
    +  function escapeStringChar(chr) {
    +    return '\\' + stringEscapes[chr];
    +  }
    +
    +  /**
    +   * Gets the value at `key` of `object`.
    +   *
    +   * @private
    +   * @param {Object} [object] The object to query.
    +   * @param {string} key The key of the property to get.
    +   * @returns {*} Returns the property value.
    +   */
    +  function getValue(object, key) {
    +    return object == null ? undefined$1 : object[key];
    +  }
    +
    +  /**
    +   * Checks if `string` contains Unicode symbols.
    +   *
    +   * @private
    +   * @param {string} string The string to inspect.
    +   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
    +   */
    +  function hasUnicode(string) {
    +    return reHasUnicode.test(string);
    +  }
    +
    +  /**
    +   * Checks if `string` contains a word composed of Unicode symbols.
    +   *
    +   * @private
    +   * @param {string} string The string to inspect.
    +   * @returns {boolean} Returns `true` if a word is found, else `false`.
    +   */
    +  function hasUnicodeWord(string) {
    +    return reHasUnicodeWord.test(string);
    +  }
    +
    +  /**
    +   * Converts `iterator` to an array.
    +   *
    +   * @private
    +   * @param {Object} iterator The iterator to convert.
    +   * @returns {Array} Returns the converted array.
    +   */
    +  function iteratorToArray(iterator) {
    +    var data,
    +        result = [];
    +
    +    while (!(data = iterator.next()).done) {
    +      result.push(data.value);
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Converts `map` to its key-value pairs.
    +   *
    +   * @private
    +   * @param {Object} map The map to convert.
    +   * @returns {Array} Returns the key-value pairs.
    +   */
    +  function mapToArray(map) {
    +    var index = -1,
    +        result = Array(map.size);
    +
    +    map.forEach(function(value, key) {
    +      result[++index] = [key, value];
    +    });
    +    return result;
    +  }
    +
    +  /**
    +   * Creates a unary function that invokes `func` with its argument transformed.
    +   *
    +   * @private
    +   * @param {Function} func The function to wrap.
    +   * @param {Function} transform The argument transform.
    +   * @returns {Function} Returns the new function.
    +   */
    +  function overArg(func, transform) {
    +    return function(arg) {
    +      return func(transform(arg));
    +    };
    +  }
    +
    +  /**
    +   * Replaces all `placeholder` elements in `array` with an internal placeholder
    +   * and returns an array of their indexes.
    +   *
    +   * @private
    +   * @param {Array} array The array to modify.
    +   * @param {*} placeholder The placeholder to replace.
    +   * @returns {Array} Returns the new array of placeholder indexes.
    +   */
    +  function replaceHolders(array, placeholder) {
    +    var index = -1,
    +        length = array.length,
    +        resIndex = 0,
    +        result = [];
    +
    +    while (++index < length) {
    +      var value = array[index];
    +      if (value === placeholder || value === PLACEHOLDER) {
    +        array[index] = PLACEHOLDER;
    +        result[resIndex++] = index;
    +      }
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Converts `set` to an array of its values.
    +   *
    +   * @private
    +   * @param {Object} set The set to convert.
    +   * @returns {Array} Returns the values.
    +   */
    +  function setToArray(set) {
    +    var index = -1,
    +        result = Array(set.size);
    +
    +    set.forEach(function(value) {
    +      result[++index] = value;
    +    });
    +    return result;
    +  }
    +
    +  /**
    +   * Converts `set` to its value-value pairs.
    +   *
    +   * @private
    +   * @param {Object} set The set to convert.
    +   * @returns {Array} Returns the value-value pairs.
    +   */
    +  function setToPairs(set) {
    +    var index = -1,
    +        result = Array(set.size);
    +
    +    set.forEach(function(value) {
    +      result[++index] = [value, value];
    +    });
    +    return result;
    +  }
    +
    +  /**
    +   * A specialized version of `_.indexOf` which performs strict equality
    +   * comparisons of values, i.e. `===`.
    +   *
    +   * @private
    +   * @param {Array} array The array to inspect.
    +   * @param {*} value The value to search for.
    +   * @param {number} fromIndex The index to search from.
    +   * @returns {number} Returns the index of the matched value, else `-1`.
    +   */
    +  function strictIndexOf(array, value, fromIndex) {
    +    var index = fromIndex - 1,
    +        length = array.length;
    +
    +    while (++index < length) {
    +      if (array[index] === value) {
    +        return index;
    +      }
    +    }
    +    return -1;
    +  }
    +
    +  /**
    +   * A specialized version of `_.lastIndexOf` which performs strict equality
    +   * comparisons of values, i.e. `===`.
    +   *
    +   * @private
    +   * @param {Array} array The array to inspect.
    +   * @param {*} value The value to search for.
    +   * @param {number} fromIndex The index to search from.
    +   * @returns {number} Returns the index of the matched value, else `-1`.
    +   */
    +  function strictLastIndexOf(array, value, fromIndex) {
    +    var index = fromIndex + 1;
    +    while (index--) {
    +      if (array[index] === value) {
    +        return index;
    +      }
    +    }
    +    return index;
    +  }
    +
    +  /**
    +   * Gets the number of symbols in `string`.
    +   *
    +   * @private
    +   * @param {string} string The string to inspect.
    +   * @returns {number} Returns the string size.
    +   */
    +  function stringSize(string) {
    +    return hasUnicode(string)
    +      ? unicodeSize(string)
    +      : asciiSize(string);
    +  }
    +
    +  /**
    +   * Converts `string` to an array.
    +   *
    +   * @private
    +   * @param {string} string The string to convert.
    +   * @returns {Array} Returns the converted array.
    +   */
    +  function stringToArray(string) {
    +    return hasUnicode(string)
    +      ? unicodeToArray(string)
    +      : asciiToArray(string);
    +  }
    +
    +  /**
    +   * Used by `_.unescape` to convert HTML entities to characters.
    +   *
    +   * @private
    +   * @param {string} chr The matched character to unescape.
    +   * @returns {string} Returns the unescaped character.
    +   */
    +  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
    +
    +  /**
    +   * Gets the size of a Unicode `string`.
    +   *
    +   * @private
    +   * @param {string} string The string inspect.
    +   * @returns {number} Returns the string size.
    +   */
    +  function unicodeSize(string) {
    +    var result = reUnicode.lastIndex = 0;
    +    while (reUnicode.test(string)) {
    +      ++result;
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Converts a Unicode `string` to an array.
    +   *
    +   * @private
    +   * @param {string} string The string to convert.
    +   * @returns {Array} Returns the converted array.
    +   */
    +  function unicodeToArray(string) {
    +    return string.match(reUnicode) || [];
    +  }
    +
    +  /**
    +   * Splits a Unicode `string` into an array of its words.
    +   *
    +   * @private
    +   * @param {string} The string to inspect.
    +   * @returns {Array} Returns the words of `string`.
    +   */
    +  function unicodeWords(string) {
    +    return string.match(reUnicodeWord) || [];
    +  }
    +
    +  /*--------------------------------------------------------------------------*/
    +
    +  /**
    +   * Create a new pristine `lodash` function using the `context` object.
    +   *
    +   * @static
    +   * @memberOf _
    +   * @since 1.1.0
    +   * @category Util
    +   * @param {Object} [context=root] The context object.
    +   * @returns {Function} Returns a new `lodash` function.
    +   * @example
    +   *
    +   * _.mixin({ 'foo': _.constant('foo') });
    +   *
    +   * var lodash = _.runInContext();
    +   * lodash.mixin({ 'bar': lodash.constant('bar') });
    +   *
    +   * _.isFunction(_.foo);
    +   * // => true
    +   * _.isFunction(_.bar);
    +   * // => false
    +   *
    +   * lodash.isFunction(lodash.foo);
    +   * // => false
    +   * lodash.isFunction(lodash.bar);
    +   * // => true
    +   *
    +   * // Create a suped-up `defer` in Node.js.
    +   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
    +   */
    +  var runInContext = (function runInContext(context) {
    +    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
    +
    +    /** Built-in constructor references. */
    +    var Array = context.Array,
    +        Date = context.Date,
    +        Error = context.Error,
    +        Function = context.Function,
    +        Math = context.Math,
    +        Object = context.Object,
    +        RegExp = context.RegExp,
    +        String = context.String,
    +        TypeError = context.TypeError;
    +
    +    /** Used for built-in method references. */
    +    var arrayProto = Array.prototype,
    +        funcProto = Function.prototype,
    +        objectProto = Object.prototype;
    +
    +    /** Used to detect overreaching core-js shims. */
    +    var coreJsData = context['__core-js_shared__'];
    +
    +    /** Used to resolve the decompiled source of functions. */
    +    var funcToString = funcProto.toString;
    +
    +    /** Used to check objects for own properties. */
    +    var hasOwnProperty = objectProto.hasOwnProperty;
    +
    +    /** Used to generate unique IDs. */
    +    var idCounter = 0;
    +
    +    /** Used to detect methods masquerading as native. */
    +    var maskSrcKey = (function() {
    +      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
    +      return uid ? ('Symbol(src)_1.' + uid) : '';
    +    }());
    +
    +    /**
    +     * Used to resolve the
    +     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
    +     * of values.
    +     */
    +    var nativeObjectToString = objectProto.toString;
    +
    +    /** Used to infer the `Object` constructor. */
    +    var objectCtorString = funcToString.call(Object);
    +
    +    /** Used to restore the original `_` reference in `_.noConflict`. */
    +    var oldDash = root._;
    +
    +    /** Used to detect if a method is native. */
    +    var reIsNative = RegExp('^' +
    +      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
    +      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
    +    );
    +
    +    /** Built-in value references. */
    +    var Buffer = moduleExports ? context.Buffer : undefined$1,
    +        Symbol = context.Symbol,
    +        Uint8Array = context.Uint8Array,
    +        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined$1,
    +        getPrototype = overArg(Object.getPrototypeOf, Object),
    +        objectCreate = Object.create,
    +        propertyIsEnumerable = objectProto.propertyIsEnumerable,
    +        splice = arrayProto.splice,
    +        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined$1,
    +        symIterator = Symbol ? Symbol.iterator : undefined$1,
    +        symToStringTag = Symbol ? Symbol.toStringTag : undefined$1;
    +
    +    var defineProperty = (function() {
    +      try {
    +        var func = getNative(Object, 'defineProperty');
    +        func({}, '', {});
    +        return func;
    +      } catch (e) {}
    +    }());
    +
    +    /** Mocked built-ins. */
    +    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
    +        ctxNow = Date && Date.now !== root.Date.now && Date.now,
    +        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
    +
    +    /* Built-in method references for those with the same name as other `lodash` methods. */
    +    var nativeCeil = Math.ceil,
    +        nativeFloor = Math.floor,
    +        nativeGetSymbols = Object.getOwnPropertySymbols,
    +        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined$1,
    +        nativeIsFinite = context.isFinite,
    +        nativeJoin = arrayProto.join,
    +        nativeKeys = overArg(Object.keys, Object),
    +        nativeMax = Math.max,
    +        nativeMin = Math.min,
    +        nativeNow = Date.now,
    +        nativeParseInt = context.parseInt,
    +        nativeRandom = Math.random,
    +        nativeReverse = arrayProto.reverse;
    +
    +    /* Built-in method references that are verified to be native. */
    +    var DataView = getNative(context, 'DataView'),
    +        Map = getNative(context, 'Map'),
    +        Promise = getNative(context, 'Promise'),
    +        Set = getNative(context, 'Set'),
    +        WeakMap = getNative(context, 'WeakMap'),
    +        nativeCreate = getNative(Object, 'create');
    +
    +    /** Used to store function metadata. */
    +    var metaMap = WeakMap && new WeakMap;
    +
    +    /** Used to lookup unminified function names. */
    +    var realNames = {};
    +
    +    /** Used to detect maps, sets, and weakmaps. */
    +    var dataViewCtorString = toSource(DataView),
    +        mapCtorString = toSource(Map),
    +        promiseCtorString = toSource(Promise),
    +        setCtorString = toSource(Set),
    +        weakMapCtorString = toSource(WeakMap);
    +
    +    /** Used to convert symbols to primitives and strings. */
    +    var symbolProto = Symbol ? Symbol.prototype : undefined$1,
    +        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined$1,
    +        symbolToString = symbolProto ? symbolProto.toString : undefined$1;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates a `lodash` object which wraps `value` to enable implicit method
    +     * chain sequences. Methods that operate on and return arrays, collections,
    +     * and functions can be chained together. Methods that retrieve a single value
    +     * or may return a primitive value will automatically end the chain sequence
    +     * and return the unwrapped value. Otherwise, the value must be unwrapped
    +     * with `_#value`.
    +     *
    +     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
    +     * enabled using `_.chain`.
    +     *
    +     * The execution of chained methods is lazy, that is, it's deferred until
    +     * `_#value` is implicitly or explicitly called.
    +     *
    +     * Lazy evaluation allows several methods to support shortcut fusion.
    +     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
    +     * the creation of intermediate arrays and can greatly reduce the number of
    +     * iteratee executions. Sections of a chain sequence qualify for shortcut
    +     * fusion if the section is applied to an array and iteratees accept only
    +     * one argument. The heuristic for whether a section qualifies for shortcut
    +     * fusion is subject to change.
    +     *
    +     * Chaining is supported in custom builds as long as the `_#value` method is
    +     * directly or indirectly included in the build.
    +     *
    +     * In addition to lodash methods, wrappers have `Array` and `String` methods.
    +     *
    +     * The wrapper `Array` methods are:
    +     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
    +     *
    +     * The wrapper `String` methods are:
    +     * `replace` and `split`
    +     *
    +     * The wrapper methods that support shortcut fusion are:
    +     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
    +     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
    +     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
    +     *
    +     * The chainable wrapper methods are:
    +     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
    +     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
    +     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
    +     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
    +     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
    +     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
    +     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
    +     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
    +     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
    +     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
    +     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
    +     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
    +     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
    +     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
    +     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
    +     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
    +     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
    +     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
    +     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
    +     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
    +     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
    +     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
    +     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
    +     * `zipObject`, `zipObjectDeep`, and `zipWith`
    +     *
    +     * The wrapper methods that are **not** chainable by default are:
    +     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
    +     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
    +     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
    +     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
    +     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
    +     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
    +     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
    +     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
    +     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
    +     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
    +     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
    +     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
    +     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
    +     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
    +     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
    +     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
    +     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
    +     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
    +     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
    +     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
    +     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
    +     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
    +     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
    +     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
    +     * `upperFirst`, `value`, and `words`
    +     *
    +     * @name _
    +     * @constructor
    +     * @category Seq
    +     * @param {*} value The value to wrap in a `lodash` instance.
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * function square(n) {
    +     *   return n * n;
    +     * }
    +     *
    +     * var wrapped = _([1, 2, 3]);
    +     *
    +     * // Returns an unwrapped value.
    +     * wrapped.reduce(_.add);
    +     * // => 6
    +     *
    +     * // Returns a wrapped value.
    +     * var squares = wrapped.map(square);
    +     *
    +     * _.isArray(squares);
    +     * // => false
    +     *
    +     * _.isArray(squares.value());
    +     * // => true
    +     */
    +    function lodash(value) {
    +      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
    +        if (value instanceof LodashWrapper) {
    +          return value;
    +        }
    +        if (hasOwnProperty.call(value, '__wrapped__')) {
    +          return wrapperClone(value);
    +        }
    +      }
    +      return new LodashWrapper(value);
    +    }
    +
    +    /**
    +     * The base implementation of `_.create` without support for assigning
    +     * properties to the created object.
    +     *
    +     * @private
    +     * @param {Object} proto The object to inherit from.
    +     * @returns {Object} Returns the new object.
    +     */
    +    var baseCreate = (function() {
    +      function object() {}
    +      return function(proto) {
    +        if (!isObject(proto)) {
    +          return {};
    +        }
    +        if (objectCreate) {
    +          return objectCreate(proto);
    +        }
    +        object.prototype = proto;
    +        var result = new object;
    +        object.prototype = undefined$1;
    +        return result;
    +      };
    +    }());
    +
    +    /**
    +     * The function whose prototype chain sequence wrappers inherit from.
    +     *
    +     * @private
    +     */
    +    function baseLodash() {
    +      // No operation performed.
    +    }
    +
    +    /**
    +     * The base constructor for creating `lodash` wrapper objects.
    +     *
    +     * @private
    +     * @param {*} value The value to wrap.
    +     * @param {boolean} [chainAll] Enable explicit method chain sequences.
    +     */
    +    function LodashWrapper(value, chainAll) {
    +      this.__wrapped__ = value;
    +      this.__actions__ = [];
    +      this.__chain__ = !!chainAll;
    +      this.__index__ = 0;
    +      this.__values__ = undefined$1;
    +    }
    +
    +    /**
    +     * By default, the template delimiters used by lodash are like those in
    +     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
    +     * following template settings to use alternative delimiters.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @type {Object}
    +     */
    +    lodash.templateSettings = {
    +
    +      /**
    +       * Used to detect `data` property values to be HTML-escaped.
    +       *
    +       * @memberOf _.templateSettings
    +       * @type {RegExp}
    +       */
    +      'escape': reEscape,
    +
    +      /**
    +       * Used to detect code to be evaluated.
    +       *
    +       * @memberOf _.templateSettings
    +       * @type {RegExp}
    +       */
    +      'evaluate': reEvaluate,
    +
    +      /**
    +       * Used to detect `data` property values to inject.
    +       *
    +       * @memberOf _.templateSettings
    +       * @type {RegExp}
    +       */
    +      'interpolate': reInterpolate,
    +
    +      /**
    +       * Used to reference the data object in the template text.
    +       *
    +       * @memberOf _.templateSettings
    +       * @type {string}
    +       */
    +      'variable': '',
    +
    +      /**
    +       * Used to import variables into the compiled template.
    +       *
    +       * @memberOf _.templateSettings
    +       * @type {Object}
    +       */
    +      'imports': {
    +
    +        /**
    +         * A reference to the `lodash` function.
    +         *
    +         * @memberOf _.templateSettings.imports
    +         * @type {Function}
    +         */
    +        '_': lodash
    +      }
    +    };
    +
    +    // Ensure wrappers are instances of `baseLodash`.
    +    lodash.prototype = baseLodash.prototype;
    +    lodash.prototype.constructor = lodash;
    +
    +    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
    +    LodashWrapper.prototype.constructor = LodashWrapper;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
    +     *
    +     * @private
    +     * @constructor
    +     * @param {*} value The value to wrap.
    +     */
    +    function LazyWrapper(value) {
    +      this.__wrapped__ = value;
    +      this.__actions__ = [];
    +      this.__dir__ = 1;
    +      this.__filtered__ = false;
    +      this.__iteratees__ = [];
    +      this.__takeCount__ = MAX_ARRAY_LENGTH;
    +      this.__views__ = [];
    +    }
    +
    +    /**
    +     * Creates a clone of the lazy wrapper object.
    +     *
    +     * @private
    +     * @name clone
    +     * @memberOf LazyWrapper
    +     * @returns {Object} Returns the cloned `LazyWrapper` object.
    +     */
    +    function lazyClone() {
    +      var result = new LazyWrapper(this.__wrapped__);
    +      result.__actions__ = copyArray(this.__actions__);
    +      result.__dir__ = this.__dir__;
    +      result.__filtered__ = this.__filtered__;
    +      result.__iteratees__ = copyArray(this.__iteratees__);
    +      result.__takeCount__ = this.__takeCount__;
    +      result.__views__ = copyArray(this.__views__);
    +      return result;
    +    }
    +
    +    /**
    +     * Reverses the direction of lazy iteration.
    +     *
    +     * @private
    +     * @name reverse
    +     * @memberOf LazyWrapper
    +     * @returns {Object} Returns the new reversed `LazyWrapper` object.
    +     */
    +    function lazyReverse() {
    +      if (this.__filtered__) {
    +        var result = new LazyWrapper(this);
    +        result.__dir__ = -1;
    +        result.__filtered__ = true;
    +      } else {
    +        result = this.clone();
    +        result.__dir__ *= -1;
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Extracts the unwrapped value from its lazy wrapper.
    +     *
    +     * @private
    +     * @name value
    +     * @memberOf LazyWrapper
    +     * @returns {*} Returns the unwrapped value.
    +     */
    +    function lazyValue() {
    +      var array = this.__wrapped__.value(),
    +          dir = this.__dir__,
    +          isArr = isArray(array),
    +          isRight = dir < 0,
    +          arrLength = isArr ? array.length : 0,
    +          view = getView(0, arrLength, this.__views__),
    +          start = view.start,
    +          end = view.end,
    +          length = end - start,
    +          index = isRight ? end : (start - 1),
    +          iteratees = this.__iteratees__,
    +          iterLength = iteratees.length,
    +          resIndex = 0,
    +          takeCount = nativeMin(length, this.__takeCount__);
    +
    +      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
    +        return baseWrapperValue(array, this.__actions__);
    +      }
    +      var result = [];
    +
    +      outer:
    +      while (length-- && resIndex < takeCount) {
    +        index += dir;
    +
    +        var iterIndex = -1,
    +            value = array[index];
    +
    +        while (++iterIndex < iterLength) {
    +          var data = iteratees[iterIndex],
    +              iteratee = data.iteratee,
    +              type = data.type,
    +              computed = iteratee(value);
    +
    +          if (type == LAZY_MAP_FLAG) {
    +            value = computed;
    +          } else if (!computed) {
    +            if (type == LAZY_FILTER_FLAG) {
    +              continue outer;
    +            } else {
    +              break outer;
    +            }
    +          }
    +        }
    +        result[resIndex++] = value;
    +      }
    +      return result;
    +    }
    +
    +    // Ensure `LazyWrapper` is an instance of `baseLodash`.
    +    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
    +    LazyWrapper.prototype.constructor = LazyWrapper;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates a hash object.
    +     *
    +     * @private
    +     * @constructor
    +     * @param {Array} [entries] The key-value pairs to cache.
    +     */
    +    function Hash(entries) {
    +      var index = -1,
    +          length = entries == null ? 0 : entries.length;
    +
    +      this.clear();
    +      while (++index < length) {
    +        var entry = entries[index];
    +        this.set(entry[0], entry[1]);
    +      }
    +    }
    +
    +    /**
    +     * Removes all key-value entries from the hash.
    +     *
    +     * @private
    +     * @name clear
    +     * @memberOf Hash
    +     */
    +    function hashClear() {
    +      this.__data__ = nativeCreate ? nativeCreate(null) : {};
    +      this.size = 0;
    +    }
    +
    +    /**
    +     * Removes `key` and its value from the hash.
    +     *
    +     * @private
    +     * @name delete
    +     * @memberOf Hash
    +     * @param {Object} hash The hash to modify.
    +     * @param {string} key The key of the value to remove.
    +     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
    +     */
    +    function hashDelete(key) {
    +      var result = this.has(key) && delete this.__data__[key];
    +      this.size -= result ? 1 : 0;
    +      return result;
    +    }
    +
    +    /**
    +     * Gets the hash value for `key`.
    +     *
    +     * @private
    +     * @name get
    +     * @memberOf Hash
    +     * @param {string} key The key of the value to get.
    +     * @returns {*} Returns the entry value.
    +     */
    +    function hashGet(key) {
    +      var data = this.__data__;
    +      if (nativeCreate) {
    +        var result = data[key];
    +        return result === HASH_UNDEFINED ? undefined$1 : result;
    +      }
    +      return hasOwnProperty.call(data, key) ? data[key] : undefined$1;
    +    }
    +
    +    /**
    +     * Checks if a hash value for `key` exists.
    +     *
    +     * @private
    +     * @name has
    +     * @memberOf Hash
    +     * @param {string} key The key of the entry to check.
    +     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
    +     */
    +    function hashHas(key) {
    +      var data = this.__data__;
    +      return nativeCreate ? (data[key] !== undefined$1) : hasOwnProperty.call(data, key);
    +    }
    +
    +    /**
    +     * Sets the hash `key` to `value`.
    +     *
    +     * @private
    +     * @name set
    +     * @memberOf Hash
    +     * @param {string} key The key of the value to set.
    +     * @param {*} value The value to set.
    +     * @returns {Object} Returns the hash instance.
    +     */
    +    function hashSet(key, value) {
    +      var data = this.__data__;
    +      this.size += this.has(key) ? 0 : 1;
    +      data[key] = (nativeCreate && value === undefined$1) ? HASH_UNDEFINED : value;
    +      return this;
    +    }
    +
    +    // Add methods to `Hash`.
    +    Hash.prototype.clear = hashClear;
    +    Hash.prototype['delete'] = hashDelete;
    +    Hash.prototype.get = hashGet;
    +    Hash.prototype.has = hashHas;
    +    Hash.prototype.set = hashSet;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates an list cache object.
    +     *
    +     * @private
    +     * @constructor
    +     * @param {Array} [entries] The key-value pairs to cache.
    +     */
    +    function ListCache(entries) {
    +      var index = -1,
    +          length = entries == null ? 0 : entries.length;
    +
    +      this.clear();
    +      while (++index < length) {
    +        var entry = entries[index];
    +        this.set(entry[0], entry[1]);
    +      }
    +    }
    +
    +    /**
    +     * Removes all key-value entries from the list cache.
    +     *
    +     * @private
    +     * @name clear
    +     * @memberOf ListCache
    +     */
    +    function listCacheClear() {
    +      this.__data__ = [];
    +      this.size = 0;
    +    }
    +
    +    /**
    +     * Removes `key` and its value from the list cache.
    +     *
    +     * @private
    +     * @name delete
    +     * @memberOf ListCache
    +     * @param {string} key The key of the value to remove.
    +     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
    +     */
    +    function listCacheDelete(key) {
    +      var data = this.__data__,
    +          index = assocIndexOf(data, key);
    +
    +      if (index < 0) {
    +        return false;
    +      }
    +      var lastIndex = data.length - 1;
    +      if (index == lastIndex) {
    +        data.pop();
    +      } else {
    +        splice.call(data, index, 1);
    +      }
    +      --this.size;
    +      return true;
    +    }
    +
    +    /**
    +     * Gets the list cache value for `key`.
    +     *
    +     * @private
    +     * @name get
    +     * @memberOf ListCache
    +     * @param {string} key The key of the value to get.
    +     * @returns {*} Returns the entry value.
    +     */
    +    function listCacheGet(key) {
    +      var data = this.__data__,
    +          index = assocIndexOf(data, key);
    +
    +      return index < 0 ? undefined$1 : data[index][1];
    +    }
    +
    +    /**
    +     * Checks if a list cache value for `key` exists.
    +     *
    +     * @private
    +     * @name has
    +     * @memberOf ListCache
    +     * @param {string} key The key of the entry to check.
    +     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
    +     */
    +    function listCacheHas(key) {
    +      return assocIndexOf(this.__data__, key) > -1;
    +    }
    +
    +    /**
    +     * Sets the list cache `key` to `value`.
    +     *
    +     * @private
    +     * @name set
    +     * @memberOf ListCache
    +     * @param {string} key The key of the value to set.
    +     * @param {*} value The value to set.
    +     * @returns {Object} Returns the list cache instance.
    +     */
    +    function listCacheSet(key, value) {
    +      var data = this.__data__,
    +          index = assocIndexOf(data, key);
    +
    +      if (index < 0) {
    +        ++this.size;
    +        data.push([key, value]);
    +      } else {
    +        data[index][1] = value;
    +      }
    +      return this;
    +    }
    +
    +    // Add methods to `ListCache`.
    +    ListCache.prototype.clear = listCacheClear;
    +    ListCache.prototype['delete'] = listCacheDelete;
    +    ListCache.prototype.get = listCacheGet;
    +    ListCache.prototype.has = listCacheHas;
    +    ListCache.prototype.set = listCacheSet;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates a map cache object to store key-value pairs.
    +     *
    +     * @private
    +     * @constructor
    +     * @param {Array} [entries] The key-value pairs to cache.
    +     */
    +    function MapCache(entries) {
    +      var index = -1,
    +          length = entries == null ? 0 : entries.length;
    +
    +      this.clear();
    +      while (++index < length) {
    +        var entry = entries[index];
    +        this.set(entry[0], entry[1]);
    +      }
    +    }
    +
    +    /**
    +     * Removes all key-value entries from the map.
    +     *
    +     * @private
    +     * @name clear
    +     * @memberOf MapCache
    +     */
    +    function mapCacheClear() {
    +      this.size = 0;
    +      this.__data__ = {
    +        'hash': new Hash,
    +        'map': new (Map || ListCache),
    +        'string': new Hash
    +      };
    +    }
    +
    +    /**
    +     * Removes `key` and its value from the map.
    +     *
    +     * @private
    +     * @name delete
    +     * @memberOf MapCache
    +     * @param {string} key The key of the value to remove.
    +     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
    +     */
    +    function mapCacheDelete(key) {
    +      var result = getMapData(this, key)['delete'](key);
    +      this.size -= result ? 1 : 0;
    +      return result;
    +    }
    +
    +    /**
    +     * Gets the map value for `key`.
    +     *
    +     * @private
    +     * @name get
    +     * @memberOf MapCache
    +     * @param {string} key The key of the value to get.
    +     * @returns {*} Returns the entry value.
    +     */
    +    function mapCacheGet(key) {
    +      return getMapData(this, key).get(key);
    +    }
    +
    +    /**
    +     * Checks if a map value for `key` exists.
    +     *
    +     * @private
    +     * @name has
    +     * @memberOf MapCache
    +     * @param {string} key The key of the entry to check.
    +     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
    +     */
    +    function mapCacheHas(key) {
    +      return getMapData(this, key).has(key);
    +    }
    +
    +    /**
    +     * Sets the map `key` to `value`.
    +     *
    +     * @private
    +     * @name set
    +     * @memberOf MapCache
    +     * @param {string} key The key of the value to set.
    +     * @param {*} value The value to set.
    +     * @returns {Object} Returns the map cache instance.
    +     */
    +    function mapCacheSet(key, value) {
    +      var data = getMapData(this, key),
    +          size = data.size;
    +
    +      data.set(key, value);
    +      this.size += data.size == size ? 0 : 1;
    +      return this;
    +    }
    +
    +    // Add methods to `MapCache`.
    +    MapCache.prototype.clear = mapCacheClear;
    +    MapCache.prototype['delete'] = mapCacheDelete;
    +    MapCache.prototype.get = mapCacheGet;
    +    MapCache.prototype.has = mapCacheHas;
    +    MapCache.prototype.set = mapCacheSet;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     *
    +     * Creates an array cache object to store unique values.
    +     *
    +     * @private
    +     * @constructor
    +     * @param {Array} [values] The values to cache.
    +     */
    +    function SetCache(values) {
    +      var index = -1,
    +          length = values == null ? 0 : values.length;
    +
    +      this.__data__ = new MapCache;
    +      while (++index < length) {
    +        this.add(values[index]);
    +      }
    +    }
    +
    +    /**
    +     * Adds `value` to the array cache.
    +     *
    +     * @private
    +     * @name add
    +     * @memberOf SetCache
    +     * @alias push
    +     * @param {*} value The value to cache.
    +     * @returns {Object} Returns the cache instance.
    +     */
    +    function setCacheAdd(value) {
    +      this.__data__.set(value, HASH_UNDEFINED);
    +      return this;
    +    }
    +
    +    /**
    +     * Checks if `value` is in the array cache.
    +     *
    +     * @private
    +     * @name has
    +     * @memberOf SetCache
    +     * @param {*} value The value to search for.
    +     * @returns {number} Returns `true` if `value` is found, else `false`.
    +     */
    +    function setCacheHas(value) {
    +      return this.__data__.has(value);
    +    }
    +
    +    // Add methods to `SetCache`.
    +    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
    +    SetCache.prototype.has = setCacheHas;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates a stack cache object to store key-value pairs.
    +     *
    +     * @private
    +     * @constructor
    +     * @param {Array} [entries] The key-value pairs to cache.
    +     */
    +    function Stack(entries) {
    +      var data = this.__data__ = new ListCache(entries);
    +      this.size = data.size;
    +    }
    +
    +    /**
    +     * Removes all key-value entries from the stack.
    +     *
    +     * @private
    +     * @name clear
    +     * @memberOf Stack
    +     */
    +    function stackClear() {
    +      this.__data__ = new ListCache;
    +      this.size = 0;
    +    }
    +
    +    /**
    +     * Removes `key` and its value from the stack.
    +     *
    +     * @private
    +     * @name delete
    +     * @memberOf Stack
    +     * @param {string} key The key of the value to remove.
    +     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
    +     */
    +    function stackDelete(key) {
    +      var data = this.__data__,
    +          result = data['delete'](key);
    +
    +      this.size = data.size;
    +      return result;
    +    }
    +
    +    /**
    +     * Gets the stack value for `key`.
    +     *
    +     * @private
    +     * @name get
    +     * @memberOf Stack
    +     * @param {string} key The key of the value to get.
    +     * @returns {*} Returns the entry value.
    +     */
    +    function stackGet(key) {
    +      return this.__data__.get(key);
    +    }
    +
    +    /**
    +     * Checks if a stack value for `key` exists.
    +     *
    +     * @private
    +     * @name has
    +     * @memberOf Stack
    +     * @param {string} key The key of the entry to check.
    +     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
    +     */
    +    function stackHas(key) {
    +      return this.__data__.has(key);
    +    }
    +
    +    /**
    +     * Sets the stack `key` to `value`.
    +     *
    +     * @private
    +     * @name set
    +     * @memberOf Stack
    +     * @param {string} key The key of the value to set.
    +     * @param {*} value The value to set.
    +     * @returns {Object} Returns the stack cache instance.
    +     */
    +    function stackSet(key, value) {
    +      var data = this.__data__;
    +      if (data instanceof ListCache) {
    +        var pairs = data.__data__;
    +        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
    +          pairs.push([key, value]);
    +          this.size = ++data.size;
    +          return this;
    +        }
    +        data = this.__data__ = new MapCache(pairs);
    +      }
    +      data.set(key, value);
    +      this.size = data.size;
    +      return this;
    +    }
    +
    +    // Add methods to `Stack`.
    +    Stack.prototype.clear = stackClear;
    +    Stack.prototype['delete'] = stackDelete;
    +    Stack.prototype.get = stackGet;
    +    Stack.prototype.has = stackHas;
    +    Stack.prototype.set = stackSet;
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates an array of the enumerable property names of the array-like `value`.
    +     *
    +     * @private
    +     * @param {*} value The value to query.
    +     * @param {boolean} inherited Specify returning inherited property names.
    +     * @returns {Array} Returns the array of property names.
    +     */
    +    function arrayLikeKeys(value, inherited) {
    +      var isArr = isArray(value),
    +          isArg = !isArr && isArguments(value),
    +          isBuff = !isArr && !isArg && isBuffer(value),
    +          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
    +          skipIndexes = isArr || isArg || isBuff || isType,
    +          result = skipIndexes ? baseTimes(value.length, String) : [],
    +          length = result.length;
    +
    +      for (var key in value) {
    +        if ((inherited || hasOwnProperty.call(value, key)) &&
    +            !(skipIndexes && (
    +               // Safari 9 has enumerable `arguments.length` in strict mode.
    +               key == 'length' ||
    +               // Node.js 0.10 has enumerable non-index properties on buffers.
    +               (isBuff && (key == 'offset' || key == 'parent')) ||
    +               // PhantomJS 2 has enumerable non-index properties on typed arrays.
    +               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
    +               // Skip index properties.
    +               isIndex(key, length)
    +            ))) {
    +          result.push(key);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * A specialized version of `_.sample` for arrays.
    +     *
    +     * @private
    +     * @param {Array} array The array to sample.
    +     * @returns {*} Returns the random element.
    +     */
    +    function arraySample(array) {
    +      var length = array.length;
    +      return length ? array[baseRandom(0, length - 1)] : undefined$1;
    +    }
    +
    +    /**
    +     * A specialized version of `_.sampleSize` for arrays.
    +     *
    +     * @private
    +     * @param {Array} array The array to sample.
    +     * @param {number} n The number of elements to sample.
    +     * @returns {Array} Returns the random elements.
    +     */
    +    function arraySampleSize(array, n) {
    +      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
    +    }
    +
    +    /**
    +     * A specialized version of `_.shuffle` for arrays.
    +     *
    +     * @private
    +     * @param {Array} array The array to shuffle.
    +     * @returns {Array} Returns the new shuffled array.
    +     */
    +    function arrayShuffle(array) {
    +      return shuffleSelf(copyArray(array));
    +    }
    +
    +    /**
    +     * This function is like `assignValue` except that it doesn't assign
    +     * `undefined` values.
    +     *
    +     * @private
    +     * @param {Object} object The object to modify.
    +     * @param {string} key The key of the property to assign.
    +     * @param {*} value The value to assign.
    +     */
    +    function assignMergeValue(object, key, value) {
    +      if ((value !== undefined$1 && !eq(object[key], value)) ||
    +          (value === undefined$1 && !(key in object))) {
    +        baseAssignValue(object, key, value);
    +      }
    +    }
    +
    +    /**
    +     * Assigns `value` to `key` of `object` if the existing value is not equivalent
    +     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons.
    +     *
    +     * @private
    +     * @param {Object} object The object to modify.
    +     * @param {string} key The key of the property to assign.
    +     * @param {*} value The value to assign.
    +     */
    +    function assignValue(object, key, value) {
    +      var objValue = object[key];
    +      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
    +          (value === undefined$1 && !(key in object))) {
    +        baseAssignValue(object, key, value);
    +      }
    +    }
    +
    +    /**
    +     * Gets the index at which the `key` is found in `array` of key-value pairs.
    +     *
    +     * @private
    +     * @param {Array} array The array to inspect.
    +     * @param {*} key The key to search for.
    +     * @returns {number} Returns the index of the matched value, else `-1`.
    +     */
    +    function assocIndexOf(array, key) {
    +      var length = array.length;
    +      while (length--) {
    +        if (eq(array[length][0], key)) {
    +          return length;
    +        }
    +      }
    +      return -1;
    +    }
    +
    +    /**
    +     * Aggregates elements of `collection` on `accumulator` with keys transformed
    +     * by `iteratee` and values set by `setter`.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} setter The function to set `accumulator` values.
    +     * @param {Function} iteratee The iteratee to transform keys.
    +     * @param {Object} accumulator The initial aggregated object.
    +     * @returns {Function} Returns `accumulator`.
    +     */
    +    function baseAggregator(collection, setter, iteratee, accumulator) {
    +      baseEach(collection, function(value, key, collection) {
    +        setter(accumulator, value, iteratee(value), collection);
    +      });
    +      return accumulator;
    +    }
    +
    +    /**
    +     * The base implementation of `_.assign` without support for multiple sources
    +     * or `customizer` functions.
    +     *
    +     * @private
    +     * @param {Object} object The destination object.
    +     * @param {Object} source The source object.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function baseAssign(object, source) {
    +      return object && copyObject(source, keys(source), object);
    +    }
    +
    +    /**
    +     * The base implementation of `_.assignIn` without support for multiple sources
    +     * or `customizer` functions.
    +     *
    +     * @private
    +     * @param {Object} object The destination object.
    +     * @param {Object} source The source object.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function baseAssignIn(object, source) {
    +      return object && copyObject(source, keysIn(source), object);
    +    }
    +
    +    /**
    +     * The base implementation of `assignValue` and `assignMergeValue` without
    +     * value checks.
    +     *
    +     * @private
    +     * @param {Object} object The object to modify.
    +     * @param {string} key The key of the property to assign.
    +     * @param {*} value The value to assign.
    +     */
    +    function baseAssignValue(object, key, value) {
    +      if (key == '__proto__' && defineProperty) {
    +        defineProperty(object, key, {
    +          'configurable': true,
    +          'enumerable': true,
    +          'value': value,
    +          'writable': true
    +        });
    +      } else {
    +        object[key] = value;
    +      }
    +    }
    +
    +    /**
    +     * The base implementation of `_.at` without support for individual paths.
    +     *
    +     * @private
    +     * @param {Object} object The object to iterate over.
    +     * @param {string[]} paths The property paths to pick.
    +     * @returns {Array} Returns the picked elements.
    +     */
    +    function baseAt(object, paths) {
    +      var index = -1,
    +          length = paths.length,
    +          result = Array(length),
    +          skip = object == null;
    +
    +      while (++index < length) {
    +        result[index] = skip ? undefined$1 : get(object, paths[index]);
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.clamp` which doesn't coerce arguments.
    +     *
    +     * @private
    +     * @param {number} number The number to clamp.
    +     * @param {number} [lower] The lower bound.
    +     * @param {number} upper The upper bound.
    +     * @returns {number} Returns the clamped number.
    +     */
    +    function baseClamp(number, lower, upper) {
    +      if (number === number) {
    +        if (upper !== undefined$1) {
    +          number = number <= upper ? number : upper;
    +        }
    +        if (lower !== undefined$1) {
    +          number = number >= lower ? number : lower;
    +        }
    +      }
    +      return number;
    +    }
    +
    +    /**
    +     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
    +     * traversed objects.
    +     *
    +     * @private
    +     * @param {*} value The value to clone.
    +     * @param {boolean} bitmask The bitmask flags.
    +     *  1 - Deep clone
    +     *  2 - Flatten inherited properties
    +     *  4 - Clone symbols
    +     * @param {Function} [customizer] The function to customize cloning.
    +     * @param {string} [key] The key of `value`.
    +     * @param {Object} [object] The parent object of `value`.
    +     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
    +     * @returns {*} Returns the cloned value.
    +     */
    +    function baseClone(value, bitmask, customizer, key, object, stack) {
    +      var result,
    +          isDeep = bitmask & CLONE_DEEP_FLAG,
    +          isFlat = bitmask & CLONE_FLAT_FLAG,
    +          isFull = bitmask & CLONE_SYMBOLS_FLAG;
    +
    +      if (customizer) {
    +        result = object ? customizer(value, key, object, stack) : customizer(value);
    +      }
    +      if (result !== undefined$1) {
    +        return result;
    +      }
    +      if (!isObject(value)) {
    +        return value;
    +      }
    +      var isArr = isArray(value);
    +      if (isArr) {
    +        result = initCloneArray(value);
    +        if (!isDeep) {
    +          return copyArray(value, result);
    +        }
    +      } else {
    +        var tag = getTag(value),
    +            isFunc = tag == funcTag || tag == genTag;
    +
    +        if (isBuffer(value)) {
    +          return cloneBuffer(value, isDeep);
    +        }
    +        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
    +          result = (isFlat || isFunc) ? {} : initCloneObject(value);
    +          if (!isDeep) {
    +            return isFlat
    +              ? copySymbolsIn(value, baseAssignIn(result, value))
    +              : copySymbols(value, baseAssign(result, value));
    +          }
    +        } else {
    +          if (!cloneableTags[tag]) {
    +            return object ? value : {};
    +          }
    +          result = initCloneByTag(value, tag, isDeep);
    +        }
    +      }
    +      // Check for circular references and return its corresponding clone.
    +      stack || (stack = new Stack);
    +      var stacked = stack.get(value);
    +      if (stacked) {
    +        return stacked;
    +      }
    +      stack.set(value, result);
    +
    +      if (isSet(value)) {
    +        value.forEach(function(subValue) {
    +          result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
    +        });
    +      } else if (isMap(value)) {
    +        value.forEach(function(subValue, key) {
    +          result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
    +        });
    +      }
    +
    +      var keysFunc = isFull
    +        ? (isFlat ? getAllKeysIn : getAllKeys)
    +        : (isFlat ? keysIn : keys);
    +
    +      var props = isArr ? undefined$1 : keysFunc(value);
    +      arrayEach(props || value, function(subValue, key) {
    +        if (props) {
    +          key = subValue;
    +          subValue = value[key];
    +        }
    +        // Recursively populate clone (susceptible to call stack limits).
    +        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
    +      });
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.conforms` which doesn't clone `source`.
    +     *
    +     * @private
    +     * @param {Object} source The object of property predicates to conform to.
    +     * @returns {Function} Returns the new spec function.
    +     */
    +    function baseConforms(source) {
    +      var props = keys(source);
    +      return function(object) {
    +        return baseConformsTo(object, source, props);
    +      };
    +    }
    +
    +    /**
    +     * The base implementation of `_.conformsTo` which accepts `props` to check.
    +     *
    +     * @private
    +     * @param {Object} object The object to inspect.
    +     * @param {Object} source The object of property predicates to conform to.
    +     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
    +     */
    +    function baseConformsTo(object, source, props) {
    +      var length = props.length;
    +      if (object == null) {
    +        return !length;
    +      }
    +      object = Object(object);
    +      while (length--) {
    +        var key = props[length],
    +            predicate = source[key],
    +            value = object[key];
    +
    +        if ((value === undefined$1 && !(key in object)) || !predicate(value)) {
    +          return false;
    +        }
    +      }
    +      return true;
    +    }
    +
    +    /**
    +     * The base implementation of `_.delay` and `_.defer` which accepts `args`
    +     * to provide to `func`.
    +     *
    +     * @private
    +     * @param {Function} func The function to delay.
    +     * @param {number} wait The number of milliseconds to delay invocation.
    +     * @param {Array} args The arguments to provide to `func`.
    +     * @returns {number|Object} Returns the timer id or timeout object.
    +     */
    +    function baseDelay(func, wait, args) {
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      return setTimeout(function() { func.apply(undefined$1, args); }, wait);
    +    }
    +
    +    /**
    +     * The base implementation of methods like `_.difference` without support
    +     * for excluding multiple arrays or iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array} array The array to inspect.
    +     * @param {Array} values The values to exclude.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of filtered values.
    +     */
    +    function baseDifference(array, values, iteratee, comparator) {
    +      var index = -1,
    +          includes = arrayIncludes,
    +          isCommon = true,
    +          length = array.length,
    +          result = [],
    +          valuesLength = values.length;
    +
    +      if (!length) {
    +        return result;
    +      }
    +      if (iteratee) {
    +        values = arrayMap(values, baseUnary(iteratee));
    +      }
    +      if (comparator) {
    +        includes = arrayIncludesWith;
    +        isCommon = false;
    +      }
    +      else if (values.length >= LARGE_ARRAY_SIZE) {
    +        includes = cacheHas;
    +        isCommon = false;
    +        values = new SetCache(values);
    +      }
    +      outer:
    +      while (++index < length) {
    +        var value = array[index],
    +            computed = iteratee == null ? value : iteratee(value);
    +
    +        value = (comparator || value !== 0) ? value : 0;
    +        if (isCommon && computed === computed) {
    +          var valuesIndex = valuesLength;
    +          while (valuesIndex--) {
    +            if (values[valuesIndex] === computed) {
    +              continue outer;
    +            }
    +          }
    +          result.push(value);
    +        }
    +        else if (!includes(values, computed, comparator)) {
    +          result.push(value);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.forEach` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @returns {Array|Object} Returns `collection`.
    +     */
    +    var baseEach = createBaseEach(baseForOwn);
    +
    +    /**
    +     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @returns {Array|Object} Returns `collection`.
    +     */
    +    var baseEachRight = createBaseEach(baseForOwnRight, true);
    +
    +    /**
    +     * The base implementation of `_.every` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} predicate The function invoked per iteration.
    +     * @returns {boolean} Returns `true` if all elements pass the predicate check,
    +     *  else `false`
    +     */
    +    function baseEvery(collection, predicate) {
    +      var result = true;
    +      baseEach(collection, function(value, index, collection) {
    +        result = !!predicate(value, index, collection);
    +        return result;
    +      });
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of methods like `_.max` and `_.min` which accepts a
    +     * `comparator` to determine the extremum value.
    +     *
    +     * @private
    +     * @param {Array} array The array to iterate over.
    +     * @param {Function} iteratee The iteratee invoked per iteration.
    +     * @param {Function} comparator The comparator used to compare values.
    +     * @returns {*} Returns the extremum value.
    +     */
    +    function baseExtremum(array, iteratee, comparator) {
    +      var index = -1,
    +          length = array.length;
    +
    +      while (++index < length) {
    +        var value = array[index],
    +            current = iteratee(value);
    +
    +        if (current != null && (computed === undefined$1
    +              ? (current === current && !isSymbol(current))
    +              : comparator(current, computed)
    +            )) {
    +          var computed = current,
    +              result = value;
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.fill` without an iteratee call guard.
    +     *
    +     * @private
    +     * @param {Array} array The array to fill.
    +     * @param {*} value The value to fill `array` with.
    +     * @param {number} [start=0] The start position.
    +     * @param {number} [end=array.length] The end position.
    +     * @returns {Array} Returns `array`.
    +     */
    +    function baseFill(array, value, start, end) {
    +      var length = array.length;
    +
    +      start = toInteger(start);
    +      if (start < 0) {
    +        start = -start > length ? 0 : (length + start);
    +      }
    +      end = (end === undefined$1 || end > length) ? length : toInteger(end);
    +      if (end < 0) {
    +        end += length;
    +      }
    +      end = start > end ? 0 : toLength(end);
    +      while (start < end) {
    +        array[start++] = value;
    +      }
    +      return array;
    +    }
    +
    +    /**
    +     * The base implementation of `_.filter` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} predicate The function invoked per iteration.
    +     * @returns {Array} Returns the new filtered array.
    +     */
    +    function baseFilter(collection, predicate) {
    +      var result = [];
    +      baseEach(collection, function(value, index, collection) {
    +        if (predicate(value, index, collection)) {
    +          result.push(value);
    +        }
    +      });
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.flatten` with support for restricting flattening.
    +     *
    +     * @private
    +     * @param {Array} array The array to flatten.
    +     * @param {number} depth The maximum recursion depth.
    +     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
    +     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
    +     * @param {Array} [result=[]] The initial result value.
    +     * @returns {Array} Returns the new flattened array.
    +     */
    +    function baseFlatten(array, depth, predicate, isStrict, result) {
    +      var index = -1,
    +          length = array.length;
    +
    +      predicate || (predicate = isFlattenable);
    +      result || (result = []);
    +
    +      while (++index < length) {
    +        var value = array[index];
    +        if (depth > 0 && predicate(value)) {
    +          if (depth > 1) {
    +            // Recursively flatten arrays (susceptible to call stack limits).
    +            baseFlatten(value, depth - 1, predicate, isStrict, result);
    +          } else {
    +            arrayPush(result, value);
    +          }
    +        } else if (!isStrict) {
    +          result[result.length] = value;
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `baseForOwn` which iterates over `object`
    +     * properties returned by `keysFunc` and invokes `iteratee` for each property.
    +     * Iteratee functions may exit iteration early by explicitly returning `false`.
    +     *
    +     * @private
    +     * @param {Object} object The object to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @param {Function} keysFunc The function to get the keys of `object`.
    +     * @returns {Object} Returns `object`.
    +     */
    +    var baseFor = createBaseFor();
    +
    +    /**
    +     * This function is like `baseFor` except that it iterates over properties
    +     * in the opposite order.
    +     *
    +     * @private
    +     * @param {Object} object The object to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @param {Function} keysFunc The function to get the keys of `object`.
    +     * @returns {Object} Returns `object`.
    +     */
    +    var baseForRight = createBaseFor(true);
    +
    +    /**
    +     * The base implementation of `_.forOwn` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Object} object The object to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function baseForOwn(object, iteratee) {
    +      return object && baseFor(object, iteratee, keys);
    +    }
    +
    +    /**
    +     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Object} object The object to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function baseForOwnRight(object, iteratee) {
    +      return object && baseForRight(object, iteratee, keys);
    +    }
    +
    +    /**
    +     * The base implementation of `_.functions` which creates an array of
    +     * `object` function property names filtered from `props`.
    +     *
    +     * @private
    +     * @param {Object} object The object to inspect.
    +     * @param {Array} props The property names to filter.
    +     * @returns {Array} Returns the function names.
    +     */
    +    function baseFunctions(object, props) {
    +      return arrayFilter(props, function(key) {
    +        return isFunction(object[key]);
    +      });
    +    }
    +
    +    /**
    +     * The base implementation of `_.get` without support for default values.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {Array|string} path The path of the property to get.
    +     * @returns {*} Returns the resolved value.
    +     */
    +    function baseGet(object, path) {
    +      path = castPath(path, object);
    +
    +      var index = 0,
    +          length = path.length;
    +
    +      while (object != null && index < length) {
    +        object = object[toKey(path[index++])];
    +      }
    +      return (index && index == length) ? object : undefined$1;
    +    }
    +
    +    /**
    +     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
    +     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
    +     * symbols of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {Function} keysFunc The function to get the keys of `object`.
    +     * @param {Function} symbolsFunc The function to get the symbols of `object`.
    +     * @returns {Array} Returns the array of property names and symbols.
    +     */
    +    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
    +      var result = keysFunc(object);
    +      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
    +    }
    +
    +    /**
    +     * The base implementation of `getTag` without fallbacks for buggy environments.
    +     *
    +     * @private
    +     * @param {*} value The value to query.
    +     * @returns {string} Returns the `toStringTag`.
    +     */
    +    function baseGetTag(value) {
    +      if (value == null) {
    +        return value === undefined$1 ? undefinedTag : nullTag;
    +      }
    +      return (symToStringTag && symToStringTag in Object(value))
    +        ? getRawTag(value)
    +        : objectToString(value);
    +    }
    +
    +    /**
    +     * The base implementation of `_.gt` which doesn't coerce arguments.
    +     *
    +     * @private
    +     * @param {*} value The value to compare.
    +     * @param {*} other The other value to compare.
    +     * @returns {boolean} Returns `true` if `value` is greater than `other`,
    +     *  else `false`.
    +     */
    +    function baseGt(value, other) {
    +      return value > other;
    +    }
    +
    +    /**
    +     * The base implementation of `_.has` without support for deep paths.
    +     *
    +     * @private
    +     * @param {Object} [object] The object to query.
    +     * @param {Array|string} key The key to check.
    +     * @returns {boolean} Returns `true` if `key` exists, else `false`.
    +     */
    +    function baseHas(object, key) {
    +      return object != null && hasOwnProperty.call(object, key);
    +    }
    +
    +    /**
    +     * The base implementation of `_.hasIn` without support for deep paths.
    +     *
    +     * @private
    +     * @param {Object} [object] The object to query.
    +     * @param {Array|string} key The key to check.
    +     * @returns {boolean} Returns `true` if `key` exists, else `false`.
    +     */
    +    function baseHasIn(object, key) {
    +      return object != null && key in Object(object);
    +    }
    +
    +    /**
    +     * The base implementation of `_.inRange` which doesn't coerce arguments.
    +     *
    +     * @private
    +     * @param {number} number The number to check.
    +     * @param {number} start The start of the range.
    +     * @param {number} end The end of the range.
    +     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
    +     */
    +    function baseInRange(number, start, end) {
    +      return number >= nativeMin(start, end) && number < nativeMax(start, end);
    +    }
    +
    +    /**
    +     * The base implementation of methods like `_.intersection`, without support
    +     * for iteratee shorthands, that accepts an array of arrays to inspect.
    +     *
    +     * @private
    +     * @param {Array} arrays The arrays to inspect.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of shared values.
    +     */
    +    function baseIntersection(arrays, iteratee, comparator) {
    +      var includes = comparator ? arrayIncludesWith : arrayIncludes,
    +          length = arrays[0].length,
    +          othLength = arrays.length,
    +          othIndex = othLength,
    +          caches = Array(othLength),
    +          maxLength = Infinity,
    +          result = [];
    +
    +      while (othIndex--) {
    +        var array = arrays[othIndex];
    +        if (othIndex && iteratee) {
    +          array = arrayMap(array, baseUnary(iteratee));
    +        }
    +        maxLength = nativeMin(array.length, maxLength);
    +        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
    +          ? new SetCache(othIndex && array)
    +          : undefined$1;
    +      }
    +      array = arrays[0];
    +
    +      var index = -1,
    +          seen = caches[0];
    +
    +      outer:
    +      while (++index < length && result.length < maxLength) {
    +        var value = array[index],
    +            computed = iteratee ? iteratee(value) : value;
    +
    +        value = (comparator || value !== 0) ? value : 0;
    +        if (!(seen
    +              ? cacheHas(seen, computed)
    +              : includes(result, computed, comparator)
    +            )) {
    +          othIndex = othLength;
    +          while (--othIndex) {
    +            var cache = caches[othIndex];
    +            if (!(cache
    +                  ? cacheHas(cache, computed)
    +                  : includes(arrays[othIndex], computed, comparator))
    +                ) {
    +              continue outer;
    +            }
    +          }
    +          if (seen) {
    +            seen.push(computed);
    +          }
    +          result.push(value);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.invert` and `_.invertBy` which inverts
    +     * `object` with values transformed by `iteratee` and set by `setter`.
    +     *
    +     * @private
    +     * @param {Object} object The object to iterate over.
    +     * @param {Function} setter The function to set `accumulator` values.
    +     * @param {Function} iteratee The iteratee to transform values.
    +     * @param {Object} accumulator The initial inverted object.
    +     * @returns {Function} Returns `accumulator`.
    +     */
    +    function baseInverter(object, setter, iteratee, accumulator) {
    +      baseForOwn(object, function(value, key, object) {
    +        setter(accumulator, iteratee(value), key, object);
    +      });
    +      return accumulator;
    +    }
    +
    +    /**
    +     * The base implementation of `_.invoke` without support for individual
    +     * method arguments.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {Array|string} path The path of the method to invoke.
    +     * @param {Array} args The arguments to invoke the method with.
    +     * @returns {*} Returns the result of the invoked method.
    +     */
    +    function baseInvoke(object, path, args) {
    +      path = castPath(path, object);
    +      object = parent(object, path);
    +      var func = object == null ? object : object[toKey(last(path))];
    +      return func == null ? undefined$1 : apply(func, object, args);
    +    }
    +
    +    /**
    +     * The base implementation of `_.isArguments`.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
    +     */
    +    function baseIsArguments(value) {
    +      return isObjectLike(value) && baseGetTag(value) == argsTag;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
    +     */
    +    function baseIsArrayBuffer(value) {
    +      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isDate` without Node.js optimizations.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
    +     */
    +    function baseIsDate(value) {
    +      return isObjectLike(value) && baseGetTag(value) == dateTag;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isEqual` which supports partial comparisons
    +     * and tracks traversed objects.
    +     *
    +     * @private
    +     * @param {*} value The value to compare.
    +     * @param {*} other The other value to compare.
    +     * @param {boolean} bitmask The bitmask flags.
    +     *  1 - Unordered comparison
    +     *  2 - Partial comparison
    +     * @param {Function} [customizer] The function to customize comparisons.
    +     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
    +     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
    +     */
    +    function baseIsEqual(value, other, bitmask, customizer, stack) {
    +      if (value === other) {
    +        return true;
    +      }
    +      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
    +        return value !== value && other !== other;
    +      }
    +      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
    +    }
    +
    +    /**
    +     * A specialized version of `baseIsEqual` for arrays and objects which performs
    +     * deep comparisons and tracks traversed objects enabling objects with circular
    +     * references to be compared.
    +     *
    +     * @private
    +     * @param {Object} object The object to compare.
    +     * @param {Object} other The other object to compare.
    +     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
    +     * @param {Function} customizer The function to customize comparisons.
    +     * @param {Function} equalFunc The function to determine equivalents of values.
    +     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
    +     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
    +     */
    +    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
    +      var objIsArr = isArray(object),
    +          othIsArr = isArray(other),
    +          objTag = objIsArr ? arrayTag : getTag(object),
    +          othTag = othIsArr ? arrayTag : getTag(other);
    +
    +      objTag = objTag == argsTag ? objectTag : objTag;
    +      othTag = othTag == argsTag ? objectTag : othTag;
    +
    +      var objIsObj = objTag == objectTag,
    +          othIsObj = othTag == objectTag,
    +          isSameTag = objTag == othTag;
    +
    +      if (isSameTag && isBuffer(object)) {
    +        if (!isBuffer(other)) {
    +          return false;
    +        }
    +        objIsArr = true;
    +        objIsObj = false;
    +      }
    +      if (isSameTag && !objIsObj) {
    +        stack || (stack = new Stack);
    +        return (objIsArr || isTypedArray(object))
    +          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
    +          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
    +      }
    +      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
    +        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
    +            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
    +
    +        if (objIsWrapped || othIsWrapped) {
    +          var objUnwrapped = objIsWrapped ? object.value() : object,
    +              othUnwrapped = othIsWrapped ? other.value() : other;
    +
    +          stack || (stack = new Stack);
    +          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
    +        }
    +      }
    +      if (!isSameTag) {
    +        return false;
    +      }
    +      stack || (stack = new Stack);
    +      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
    +    }
    +
    +    /**
    +     * The base implementation of `_.isMap` without Node.js optimizations.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
    +     */
    +    function baseIsMap(value) {
    +      return isObjectLike(value) && getTag(value) == mapTag;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isMatch` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Object} object The object to inspect.
    +     * @param {Object} source The object of property values to match.
    +     * @param {Array} matchData The property names, values, and compare flags to match.
    +     * @param {Function} [customizer] The function to customize comparisons.
    +     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
    +     */
    +    function baseIsMatch(object, source, matchData, customizer) {
    +      var index = matchData.length,
    +          length = index,
    +          noCustomizer = !customizer;
    +
    +      if (object == null) {
    +        return !length;
    +      }
    +      object = Object(object);
    +      while (index--) {
    +        var data = matchData[index];
    +        if ((noCustomizer && data[2])
    +              ? data[1] !== object[data[0]]
    +              : !(data[0] in object)
    +            ) {
    +          return false;
    +        }
    +      }
    +      while (++index < length) {
    +        data = matchData[index];
    +        var key = data[0],
    +            objValue = object[key],
    +            srcValue = data[1];
    +
    +        if (noCustomizer && data[2]) {
    +          if (objValue === undefined$1 && !(key in object)) {
    +            return false;
    +          }
    +        } else {
    +          var stack = new Stack;
    +          if (customizer) {
    +            var result = customizer(objValue, srcValue, key, object, source, stack);
    +          }
    +          if (!(result === undefined$1
    +                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
    +                : result
    +              )) {
    +            return false;
    +          }
    +        }
    +      }
    +      return true;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isNative` without bad shim checks.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a native function,
    +     *  else `false`.
    +     */
    +    function baseIsNative(value) {
    +      if (!isObject(value) || isMasked(value)) {
    +        return false;
    +      }
    +      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
    +      return pattern.test(toSource(value));
    +    }
    +
    +    /**
    +     * The base implementation of `_.isRegExp` without Node.js optimizations.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
    +     */
    +    function baseIsRegExp(value) {
    +      return isObjectLike(value) && baseGetTag(value) == regexpTag;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isSet` without Node.js optimizations.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
    +     */
    +    function baseIsSet(value) {
    +      return isObjectLike(value) && getTag(value) == setTag;
    +    }
    +
    +    /**
    +     * The base implementation of `_.isTypedArray` without Node.js optimizations.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
    +     */
    +    function baseIsTypedArray(value) {
    +      return isObjectLike(value) &&
    +        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
    +    }
    +
    +    /**
    +     * The base implementation of `_.iteratee`.
    +     *
    +     * @private
    +     * @param {*} [value=_.identity] The value to convert to an iteratee.
    +     * @returns {Function} Returns the iteratee.
    +     */
    +    function baseIteratee(value) {
    +      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
    +      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
    +      if (typeof value == 'function') {
    +        return value;
    +      }
    +      if (value == null) {
    +        return identity;
    +      }
    +      if (typeof value == 'object') {
    +        return isArray(value)
    +          ? baseMatchesProperty(value[0], value[1])
    +          : baseMatches(value);
    +      }
    +      return property(value);
    +    }
    +
    +    /**
    +     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of property names.
    +     */
    +    function baseKeys(object) {
    +      if (!isPrototype(object)) {
    +        return nativeKeys(object);
    +      }
    +      var result = [];
    +      for (var key in Object(object)) {
    +        if (hasOwnProperty.call(object, key) && key != 'constructor') {
    +          result.push(key);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of property names.
    +     */
    +    function baseKeysIn(object) {
    +      if (!isObject(object)) {
    +        return nativeKeysIn(object);
    +      }
    +      var isProto = isPrototype(object),
    +          result = [];
    +
    +      for (var key in object) {
    +        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
    +          result.push(key);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.lt` which doesn't coerce arguments.
    +     *
    +     * @private
    +     * @param {*} value The value to compare.
    +     * @param {*} other The other value to compare.
    +     * @returns {boolean} Returns `true` if `value` is less than `other`,
    +     *  else `false`.
    +     */
    +    function baseLt(value, other) {
    +      return value < other;
    +    }
    +
    +    /**
    +     * The base implementation of `_.map` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} iteratee The function invoked per iteration.
    +     * @returns {Array} Returns the new mapped array.
    +     */
    +    function baseMap(collection, iteratee) {
    +      var index = -1,
    +          result = isArrayLike(collection) ? Array(collection.length) : [];
    +
    +      baseEach(collection, function(value, key, collection) {
    +        result[++index] = iteratee(value, key, collection);
    +      });
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.matches` which doesn't clone `source`.
    +     *
    +     * @private
    +     * @param {Object} source The object of property values to match.
    +     * @returns {Function} Returns the new spec function.
    +     */
    +    function baseMatches(source) {
    +      var matchData = getMatchData(source);
    +      if (matchData.length == 1 && matchData[0][2]) {
    +        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
    +      }
    +      return function(object) {
    +        return object === source || baseIsMatch(object, source, matchData);
    +      };
    +    }
    +
    +    /**
    +     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
    +     *
    +     * @private
    +     * @param {string} path The path of the property to get.
    +     * @param {*} srcValue The value to match.
    +     * @returns {Function} Returns the new spec function.
    +     */
    +    function baseMatchesProperty(path, srcValue) {
    +      if (isKey(path) && isStrictComparable(srcValue)) {
    +        return matchesStrictComparable(toKey(path), srcValue);
    +      }
    +      return function(object) {
    +        var objValue = get(object, path);
    +        return (objValue === undefined$1 && objValue === srcValue)
    +          ? hasIn(object, path)
    +          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
    +      };
    +    }
    +
    +    /**
    +     * The base implementation of `_.merge` without support for multiple sources.
    +     *
    +     * @private
    +     * @param {Object} object The destination object.
    +     * @param {Object} source The source object.
    +     * @param {number} srcIndex The index of `source`.
    +     * @param {Function} [customizer] The function to customize merged values.
    +     * @param {Object} [stack] Tracks traversed source values and their merged
    +     *  counterparts.
    +     */
    +    function baseMerge(object, source, srcIndex, customizer, stack) {
    +      if (object === source) {
    +        return;
    +      }
    +      baseFor(source, function(srcValue, key) {
    +        stack || (stack = new Stack);
    +        if (isObject(srcValue)) {
    +          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
    +        }
    +        else {
    +          var newValue = customizer
    +            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
    +            : undefined$1;
    +
    +          if (newValue === undefined$1) {
    +            newValue = srcValue;
    +          }
    +          assignMergeValue(object, key, newValue);
    +        }
    +      }, keysIn);
    +    }
    +
    +    /**
    +     * A specialized version of `baseMerge` for arrays and objects which performs
    +     * deep merges and tracks traversed objects enabling objects with circular
    +     * references to be merged.
    +     *
    +     * @private
    +     * @param {Object} object The destination object.
    +     * @param {Object} source The source object.
    +     * @param {string} key The key of the value to merge.
    +     * @param {number} srcIndex The index of `source`.
    +     * @param {Function} mergeFunc The function to merge values.
    +     * @param {Function} [customizer] The function to customize assigned values.
    +     * @param {Object} [stack] Tracks traversed source values and their merged
    +     *  counterparts.
    +     */
    +    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
    +      var objValue = safeGet(object, key),
    +          srcValue = safeGet(source, key),
    +          stacked = stack.get(srcValue);
    +
    +      if (stacked) {
    +        assignMergeValue(object, key, stacked);
    +        return;
    +      }
    +      var newValue = customizer
    +        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
    +        : undefined$1;
    +
    +      var isCommon = newValue === undefined$1;
    +
    +      if (isCommon) {
    +        var isArr = isArray(srcValue),
    +            isBuff = !isArr && isBuffer(srcValue),
    +            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
    +
    +        newValue = srcValue;
    +        if (isArr || isBuff || isTyped) {
    +          if (isArray(objValue)) {
    +            newValue = objValue;
    +          }
    +          else if (isArrayLikeObject(objValue)) {
    +            newValue = copyArray(objValue);
    +          }
    +          else if (isBuff) {
    +            isCommon = false;
    +            newValue = cloneBuffer(srcValue, true);
    +          }
    +          else if (isTyped) {
    +            isCommon = false;
    +            newValue = cloneTypedArray(srcValue, true);
    +          }
    +          else {
    +            newValue = [];
    +          }
    +        }
    +        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
    +          newValue = objValue;
    +          if (isArguments(objValue)) {
    +            newValue = toPlainObject(objValue);
    +          }
    +          else if (!isObject(objValue) || isFunction(objValue)) {
    +            newValue = initCloneObject(srcValue);
    +          }
    +        }
    +        else {
    +          isCommon = false;
    +        }
    +      }
    +      if (isCommon) {
    +        // Recursively merge objects and arrays (susceptible to call stack limits).
    +        stack.set(srcValue, newValue);
    +        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
    +        stack['delete'](srcValue);
    +      }
    +      assignMergeValue(object, key, newValue);
    +    }
    +
    +    /**
    +     * The base implementation of `_.nth` which doesn't coerce arguments.
    +     *
    +     * @private
    +     * @param {Array} array The array to query.
    +     * @param {number} n The index of the element to return.
    +     * @returns {*} Returns the nth element of `array`.
    +     */
    +    function baseNth(array, n) {
    +      var length = array.length;
    +      if (!length) {
    +        return;
    +      }
    +      n += n < 0 ? length : 0;
    +      return isIndex(n, length) ? array[n] : undefined$1;
    +    }
    +
    +    /**
    +     * The base implementation of `_.orderBy` without param guards.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
    +     * @param {string[]} orders The sort orders of `iteratees`.
    +     * @returns {Array} Returns the new sorted array.
    +     */
    +    function baseOrderBy(collection, iteratees, orders) {
    +      if (iteratees.length) {
    +        iteratees = arrayMap(iteratees, function(iteratee) {
    +          if (isArray(iteratee)) {
    +            return function(value) {
    +              return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
    +            }
    +          }
    +          return iteratee;
    +        });
    +      } else {
    +        iteratees = [identity];
    +      }
    +
    +      var index = -1;
    +      iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
    +
    +      var result = baseMap(collection, function(value, key, collection) {
    +        var criteria = arrayMap(iteratees, function(iteratee) {
    +          return iteratee(value);
    +        });
    +        return { 'criteria': criteria, 'index': ++index, 'value': value };
    +      });
    +
    +      return baseSortBy(result, function(object, other) {
    +        return compareMultiple(object, other, orders);
    +      });
    +    }
    +
    +    /**
    +     * The base implementation of `_.pick` without support for individual
    +     * property identifiers.
    +     *
    +     * @private
    +     * @param {Object} object The source object.
    +     * @param {string[]} paths The property paths to pick.
    +     * @returns {Object} Returns the new object.
    +     */
    +    function basePick(object, paths) {
    +      return basePickBy(object, paths, function(value, path) {
    +        return hasIn(object, path);
    +      });
    +    }
    +
    +    /**
    +     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Object} object The source object.
    +     * @param {string[]} paths The property paths to pick.
    +     * @param {Function} predicate The function invoked per property.
    +     * @returns {Object} Returns the new object.
    +     */
    +    function basePickBy(object, paths, predicate) {
    +      var index = -1,
    +          length = paths.length,
    +          result = {};
    +
    +      while (++index < length) {
    +        var path = paths[index],
    +            value = baseGet(object, path);
    +
    +        if (predicate(value, path)) {
    +          baseSet(result, castPath(path, object), value);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * A specialized version of `baseProperty` which supports deep paths.
    +     *
    +     * @private
    +     * @param {Array|string} path The path of the property to get.
    +     * @returns {Function} Returns the new accessor function.
    +     */
    +    function basePropertyDeep(path) {
    +      return function(object) {
    +        return baseGet(object, path);
    +      };
    +    }
    +
    +    /**
    +     * The base implementation of `_.pullAllBy` without support for iteratee
    +     * shorthands.
    +     *
    +     * @private
    +     * @param {Array} array The array to modify.
    +     * @param {Array} values The values to remove.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns `array`.
    +     */
    +    function basePullAll(array, values, iteratee, comparator) {
    +      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
    +          index = -1,
    +          length = values.length,
    +          seen = array;
    +
    +      if (array === values) {
    +        values = copyArray(values);
    +      }
    +      if (iteratee) {
    +        seen = arrayMap(array, baseUnary(iteratee));
    +      }
    +      while (++index < length) {
    +        var fromIndex = 0,
    +            value = values[index],
    +            computed = iteratee ? iteratee(value) : value;
    +
    +        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
    +          if (seen !== array) {
    +            splice.call(seen, fromIndex, 1);
    +          }
    +          splice.call(array, fromIndex, 1);
    +        }
    +      }
    +      return array;
    +    }
    +
    +    /**
    +     * The base implementation of `_.pullAt` without support for individual
    +     * indexes or capturing the removed elements.
    +     *
    +     * @private
    +     * @param {Array} array The array to modify.
    +     * @param {number[]} indexes The indexes of elements to remove.
    +     * @returns {Array} Returns `array`.
    +     */
    +    function basePullAt(array, indexes) {
    +      var length = array ? indexes.length : 0,
    +          lastIndex = length - 1;
    +
    +      while (length--) {
    +        var index = indexes[length];
    +        if (length == lastIndex || index !== previous) {
    +          var previous = index;
    +          if (isIndex(index)) {
    +            splice.call(array, index, 1);
    +          } else {
    +            baseUnset(array, index);
    +          }
    +        }
    +      }
    +      return array;
    +    }
    +
    +    /**
    +     * The base implementation of `_.random` without support for returning
    +     * floating-point numbers.
    +     *
    +     * @private
    +     * @param {number} lower The lower bound.
    +     * @param {number} upper The upper bound.
    +     * @returns {number} Returns the random number.
    +     */
    +    function baseRandom(lower, upper) {
    +      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
    +    }
    +
    +    /**
    +     * The base implementation of `_.range` and `_.rangeRight` which doesn't
    +     * coerce arguments.
    +     *
    +     * @private
    +     * @param {number} start The start of the range.
    +     * @param {number} end The end of the range.
    +     * @param {number} step The value to increment or decrement by.
    +     * @param {boolean} [fromRight] Specify iterating from right to left.
    +     * @returns {Array} Returns the range of numbers.
    +     */
    +    function baseRange(start, end, step, fromRight) {
    +      var index = -1,
    +          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
    +          result = Array(length);
    +
    +      while (length--) {
    +        result[fromRight ? length : ++index] = start;
    +        start += step;
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.repeat` which doesn't coerce arguments.
    +     *
    +     * @private
    +     * @param {string} string The string to repeat.
    +     * @param {number} n The number of times to repeat the string.
    +     * @returns {string} Returns the repeated string.
    +     */
    +    function baseRepeat(string, n) {
    +      var result = '';
    +      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
    +        return result;
    +      }
    +      // Leverage the exponentiation by squaring algorithm for a faster repeat.
    +      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
    +      do {
    +        if (n % 2) {
    +          result += string;
    +        }
    +        n = nativeFloor(n / 2);
    +        if (n) {
    +          string += string;
    +        }
    +      } while (n);
    +
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
    +     *
    +     * @private
    +     * @param {Function} func The function to apply a rest parameter to.
    +     * @param {number} [start=func.length-1] The start position of the rest parameter.
    +     * @returns {Function} Returns the new function.
    +     */
    +    function baseRest(func, start) {
    +      return setToString(overRest(func, start, identity), func + '');
    +    }
    +
    +    /**
    +     * The base implementation of `_.sample`.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to sample.
    +     * @returns {*} Returns the random element.
    +     */
    +    function baseSample(collection) {
    +      return arraySample(values(collection));
    +    }
    +
    +    /**
    +     * The base implementation of `_.sampleSize` without param guards.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to sample.
    +     * @param {number} n The number of elements to sample.
    +     * @returns {Array} Returns the random elements.
    +     */
    +    function baseSampleSize(collection, n) {
    +      var array = values(collection);
    +      return shuffleSelf(array, baseClamp(n, 0, array.length));
    +    }
    +
    +    /**
    +     * The base implementation of `_.set`.
    +     *
    +     * @private
    +     * @param {Object} object The object to modify.
    +     * @param {Array|string} path The path of the property to set.
    +     * @param {*} value The value to set.
    +     * @param {Function} [customizer] The function to customize path creation.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function baseSet(object, path, value, customizer) {
    +      if (!isObject(object)) {
    +        return object;
    +      }
    +      path = castPath(path, object);
    +
    +      var index = -1,
    +          length = path.length,
    +          lastIndex = length - 1,
    +          nested = object;
    +
    +      while (nested != null && ++index < length) {
    +        var key = toKey(path[index]),
    +            newValue = value;
    +
    +        if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
    +          return object;
    +        }
    +
    +        if (index != lastIndex) {
    +          var objValue = nested[key];
    +          newValue = customizer ? customizer(objValue, key, nested) : undefined$1;
    +          if (newValue === undefined$1) {
    +            newValue = isObject(objValue)
    +              ? objValue
    +              : (isIndex(path[index + 1]) ? [] : {});
    +          }
    +        }
    +        assignValue(nested, key, newValue);
    +        nested = nested[key];
    +      }
    +      return object;
    +    }
    +
    +    /**
    +     * The base implementation of `setData` without support for hot loop shorting.
    +     *
    +     * @private
    +     * @param {Function} func The function to associate metadata with.
    +     * @param {*} data The metadata.
    +     * @returns {Function} Returns `func`.
    +     */
    +    var baseSetData = !metaMap ? identity : function(func, data) {
    +      metaMap.set(func, data);
    +      return func;
    +    };
    +
    +    /**
    +     * The base implementation of `setToString` without support for hot loop shorting.
    +     *
    +     * @private
    +     * @param {Function} func The function to modify.
    +     * @param {Function} string The `toString` result.
    +     * @returns {Function} Returns `func`.
    +     */
    +    var baseSetToString = !defineProperty ? identity : function(func, string) {
    +      return defineProperty(func, 'toString', {
    +        'configurable': true,
    +        'enumerable': false,
    +        'value': constant(string),
    +        'writable': true
    +      });
    +    };
    +
    +    /**
    +     * The base implementation of `_.shuffle`.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to shuffle.
    +     * @returns {Array} Returns the new shuffled array.
    +     */
    +    function baseShuffle(collection) {
    +      return shuffleSelf(values(collection));
    +    }
    +
    +    /**
    +     * The base implementation of `_.slice` without an iteratee call guard.
    +     *
    +     * @private
    +     * @param {Array} array The array to slice.
    +     * @param {number} [start=0] The start position.
    +     * @param {number} [end=array.length] The end position.
    +     * @returns {Array} Returns the slice of `array`.
    +     */
    +    function baseSlice(array, start, end) {
    +      var index = -1,
    +          length = array.length;
    +
    +      if (start < 0) {
    +        start = -start > length ? 0 : (length + start);
    +      }
    +      end = end > length ? length : end;
    +      if (end < 0) {
    +        end += length;
    +      }
    +      length = start > end ? 0 : ((end - start) >>> 0);
    +      start >>>= 0;
    +
    +      var result = Array(length);
    +      while (++index < length) {
    +        result[index] = array[index + start];
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.some` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} predicate The function invoked per iteration.
    +     * @returns {boolean} Returns `true` if any element passes the predicate check,
    +     *  else `false`.
    +     */
    +    function baseSome(collection, predicate) {
    +      var result;
    +
    +      baseEach(collection, function(value, index, collection) {
    +        result = predicate(value, index, collection);
    +        return !result;
    +      });
    +      return !!result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
    +     * performs a binary search of `array` to determine the index at which `value`
    +     * should be inserted into `array` in order to maintain its sort order.
    +     *
    +     * @private
    +     * @param {Array} array The sorted array to inspect.
    +     * @param {*} value The value to evaluate.
    +     * @param {boolean} [retHighest] Specify returning the highest qualified index.
    +     * @returns {number} Returns the index at which `value` should be inserted
    +     *  into `array`.
    +     */
    +    function baseSortedIndex(array, value, retHighest) {
    +      var low = 0,
    +          high = array == null ? low : array.length;
    +
    +      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
    +        while (low < high) {
    +          var mid = (low + high) >>> 1,
    +              computed = array[mid];
    +
    +          if (computed !== null && !isSymbol(computed) &&
    +              (retHighest ? (computed <= value) : (computed < value))) {
    +            low = mid + 1;
    +          } else {
    +            high = mid;
    +          }
    +        }
    +        return high;
    +      }
    +      return baseSortedIndexBy(array, value, identity, retHighest);
    +    }
    +
    +    /**
    +     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
    +     * which invokes `iteratee` for `value` and each element of `array` to compute
    +     * their sort ranking. The iteratee is invoked with one argument; (value).
    +     *
    +     * @private
    +     * @param {Array} array The sorted array to inspect.
    +     * @param {*} value The value to evaluate.
    +     * @param {Function} iteratee The iteratee invoked per element.
    +     * @param {boolean} [retHighest] Specify returning the highest qualified index.
    +     * @returns {number} Returns the index at which `value` should be inserted
    +     *  into `array`.
    +     */
    +    function baseSortedIndexBy(array, value, iteratee, retHighest) {
    +      var low = 0,
    +          high = array == null ? 0 : array.length;
    +      if (high === 0) {
    +        return 0;
    +      }
    +
    +      value = iteratee(value);
    +      var valIsNaN = value !== value,
    +          valIsNull = value === null,
    +          valIsSymbol = isSymbol(value),
    +          valIsUndefined = value === undefined$1;
    +
    +      while (low < high) {
    +        var mid = nativeFloor((low + high) / 2),
    +            computed = iteratee(array[mid]),
    +            othIsDefined = computed !== undefined$1,
    +            othIsNull = computed === null,
    +            othIsReflexive = computed === computed,
    +            othIsSymbol = isSymbol(computed);
    +
    +        if (valIsNaN) {
    +          var setLow = retHighest || othIsReflexive;
    +        } else if (valIsUndefined) {
    +          setLow = othIsReflexive && (retHighest || othIsDefined);
    +        } else if (valIsNull) {
    +          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
    +        } else if (valIsSymbol) {
    +          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
    +        } else if (othIsNull || othIsSymbol) {
    +          setLow = false;
    +        } else {
    +          setLow = retHighest ? (computed <= value) : (computed < value);
    +        }
    +        if (setLow) {
    +          low = mid + 1;
    +        } else {
    +          high = mid;
    +        }
    +      }
    +      return nativeMin(high, MAX_ARRAY_INDEX);
    +    }
    +
    +    /**
    +     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
    +     * support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @returns {Array} Returns the new duplicate free array.
    +     */
    +    function baseSortedUniq(array, iteratee) {
    +      var index = -1,
    +          length = array.length,
    +          resIndex = 0,
    +          result = [];
    +
    +      while (++index < length) {
    +        var value = array[index],
    +            computed = iteratee ? iteratee(value) : value;
    +
    +        if (!index || !eq(computed, seen)) {
    +          var seen = computed;
    +          result[resIndex++] = value === 0 ? 0 : value;
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.toNumber` which doesn't ensure correct
    +     * conversions of binary, hexadecimal, or octal string values.
    +     *
    +     * @private
    +     * @param {*} value The value to process.
    +     * @returns {number} Returns the number.
    +     */
    +    function baseToNumber(value) {
    +      if (typeof value == 'number') {
    +        return value;
    +      }
    +      if (isSymbol(value)) {
    +        return NAN;
    +      }
    +      return +value;
    +    }
    +
    +    /**
    +     * The base implementation of `_.toString` which doesn't convert nullish
    +     * values to empty strings.
    +     *
    +     * @private
    +     * @param {*} value The value to process.
    +     * @returns {string} Returns the string.
    +     */
    +    function baseToString(value) {
    +      // Exit early for strings to avoid a performance hit in some environments.
    +      if (typeof value == 'string') {
    +        return value;
    +      }
    +      if (isArray(value)) {
    +        // Recursively convert values (susceptible to call stack limits).
    +        return arrayMap(value, baseToString) + '';
    +      }
    +      if (isSymbol(value)) {
    +        return symbolToString ? symbolToString.call(value) : '';
    +      }
    +      var result = (value + '');
    +      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new duplicate free array.
    +     */
    +    function baseUniq(array, iteratee, comparator) {
    +      var index = -1,
    +          includes = arrayIncludes,
    +          length = array.length,
    +          isCommon = true,
    +          result = [],
    +          seen = result;
    +
    +      if (comparator) {
    +        isCommon = false;
    +        includes = arrayIncludesWith;
    +      }
    +      else if (length >= LARGE_ARRAY_SIZE) {
    +        var set = iteratee ? null : createSet(array);
    +        if (set) {
    +          return setToArray(set);
    +        }
    +        isCommon = false;
    +        includes = cacheHas;
    +        seen = new SetCache;
    +      }
    +      else {
    +        seen = iteratee ? [] : result;
    +      }
    +      outer:
    +      while (++index < length) {
    +        var value = array[index],
    +            computed = iteratee ? iteratee(value) : value;
    +
    +        value = (comparator || value !== 0) ? value : 0;
    +        if (isCommon && computed === computed) {
    +          var seenIndex = seen.length;
    +          while (seenIndex--) {
    +            if (seen[seenIndex] === computed) {
    +              continue outer;
    +            }
    +          }
    +          if (iteratee) {
    +            seen.push(computed);
    +          }
    +          result.push(value);
    +        }
    +        else if (!includes(seen, computed, comparator)) {
    +          if (seen !== result) {
    +            seen.push(computed);
    +          }
    +          result.push(value);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * The base implementation of `_.unset`.
    +     *
    +     * @private
    +     * @param {Object} object The object to modify.
    +     * @param {Array|string} path The property path to unset.
    +     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
    +     */
    +    function baseUnset(object, path) {
    +      path = castPath(path, object);
    +      object = parent(object, path);
    +      return object == null || delete object[toKey(last(path))];
    +    }
    +
    +    /**
    +     * The base implementation of `_.update`.
    +     *
    +     * @private
    +     * @param {Object} object The object to modify.
    +     * @param {Array|string} path The path of the property to update.
    +     * @param {Function} updater The function to produce the updated value.
    +     * @param {Function} [customizer] The function to customize path creation.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function baseUpdate(object, path, updater, customizer) {
    +      return baseSet(object, path, updater(baseGet(object, path)), customizer);
    +    }
    +
    +    /**
    +     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
    +     * without support for iteratee shorthands.
    +     *
    +     * @private
    +     * @param {Array} array The array to query.
    +     * @param {Function} predicate The function invoked per iteration.
    +     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
    +     * @param {boolean} [fromRight] Specify iterating from right to left.
    +     * @returns {Array} Returns the slice of `array`.
    +     */
    +    function baseWhile(array, predicate, isDrop, fromRight) {
    +      var length = array.length,
    +          index = fromRight ? length : -1;
    +
    +      while ((fromRight ? index-- : ++index < length) &&
    +        predicate(array[index], index, array)) {}
    +
    +      return isDrop
    +        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
    +        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
    +    }
    +
    +    /**
    +     * The base implementation of `wrapperValue` which returns the result of
    +     * performing a sequence of actions on the unwrapped `value`, where each
    +     * successive action is supplied the return value of the previous.
    +     *
    +     * @private
    +     * @param {*} value The unwrapped value.
    +     * @param {Array} actions Actions to perform to resolve the unwrapped value.
    +     * @returns {*} Returns the resolved value.
    +     */
    +    function baseWrapperValue(value, actions) {
    +      var result = value;
    +      if (result instanceof LazyWrapper) {
    +        result = result.value();
    +      }
    +      return arrayReduce(actions, function(result, action) {
    +        return action.func.apply(action.thisArg, arrayPush([result], action.args));
    +      }, result);
    +    }
    +
    +    /**
    +     * The base implementation of methods like `_.xor`, without support for
    +     * iteratee shorthands, that accepts an array of arrays to inspect.
    +     *
    +     * @private
    +     * @param {Array} arrays The arrays to inspect.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of values.
    +     */
    +    function baseXor(arrays, iteratee, comparator) {
    +      var length = arrays.length;
    +      if (length < 2) {
    +        return length ? baseUniq(arrays[0]) : [];
    +      }
    +      var index = -1,
    +          result = Array(length);
    +
    +      while (++index < length) {
    +        var array = arrays[index],
    +            othIndex = -1;
    +
    +        while (++othIndex < length) {
    +          if (othIndex != index) {
    +            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
    +          }
    +        }
    +      }
    +      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
    +    }
    +
    +    /**
    +     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
    +     *
    +     * @private
    +     * @param {Array} props The property identifiers.
    +     * @param {Array} values The property values.
    +     * @param {Function} assignFunc The function to assign values.
    +     * @returns {Object} Returns the new object.
    +     */
    +    function baseZipObject(props, values, assignFunc) {
    +      var index = -1,
    +          length = props.length,
    +          valsLength = values.length,
    +          result = {};
    +
    +      while (++index < length) {
    +        var value = index < valsLength ? values[index] : undefined$1;
    +        assignFunc(result, props[index], value);
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Casts `value` to an empty array if it's not an array like object.
    +     *
    +     * @private
    +     * @param {*} value The value to inspect.
    +     * @returns {Array|Object} Returns the cast array-like object.
    +     */
    +    function castArrayLikeObject(value) {
    +      return isArrayLikeObject(value) ? value : [];
    +    }
    +
    +    /**
    +     * Casts `value` to `identity` if it's not a function.
    +     *
    +     * @private
    +     * @param {*} value The value to inspect.
    +     * @returns {Function} Returns cast function.
    +     */
    +    function castFunction(value) {
    +      return typeof value == 'function' ? value : identity;
    +    }
    +
    +    /**
    +     * Casts `value` to a path array if it's not one.
    +     *
    +     * @private
    +     * @param {*} value The value to inspect.
    +     * @param {Object} [object] The object to query keys on.
    +     * @returns {Array} Returns the cast property path array.
    +     */
    +    function castPath(value, object) {
    +      if (isArray(value)) {
    +        return value;
    +      }
    +      return isKey(value, object) ? [value] : stringToPath(toString(value));
    +    }
    +
    +    /**
    +     * A `baseRest` alias which can be replaced with `identity` by module
    +     * replacement plugins.
    +     *
    +     * @private
    +     * @type {Function}
    +     * @param {Function} func The function to apply a rest parameter to.
    +     * @returns {Function} Returns the new function.
    +     */
    +    var castRest = baseRest;
    +
    +    /**
    +     * Casts `array` to a slice if it's needed.
    +     *
    +     * @private
    +     * @param {Array} array The array to inspect.
    +     * @param {number} start The start position.
    +     * @param {number} [end=array.length] The end position.
    +     * @returns {Array} Returns the cast slice.
    +     */
    +    function castSlice(array, start, end) {
    +      var length = array.length;
    +      end = end === undefined$1 ? length : end;
    +      return (!start && end >= length) ? array : baseSlice(array, start, end);
    +    }
    +
    +    /**
    +     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
    +     *
    +     * @private
    +     * @param {number|Object} id The timer id or timeout object of the timer to clear.
    +     */
    +    var clearTimeout = ctxClearTimeout || function(id) {
    +      return root.clearTimeout(id);
    +    };
    +
    +    /**
    +     * Creates a clone of  `buffer`.
    +     *
    +     * @private
    +     * @param {Buffer} buffer The buffer to clone.
    +     * @param {boolean} [isDeep] Specify a deep clone.
    +     * @returns {Buffer} Returns the cloned buffer.
    +     */
    +    function cloneBuffer(buffer, isDeep) {
    +      if (isDeep) {
    +        return buffer.slice();
    +      }
    +      var length = buffer.length,
    +          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
    +
    +      buffer.copy(result);
    +      return result;
    +    }
    +
    +    /**
    +     * Creates a clone of `arrayBuffer`.
    +     *
    +     * @private
    +     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
    +     * @returns {ArrayBuffer} Returns the cloned array buffer.
    +     */
    +    function cloneArrayBuffer(arrayBuffer) {
    +      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
    +      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
    +      return result;
    +    }
    +
    +    /**
    +     * Creates a clone of `dataView`.
    +     *
    +     * @private
    +     * @param {Object} dataView The data view to clone.
    +     * @param {boolean} [isDeep] Specify a deep clone.
    +     * @returns {Object} Returns the cloned data view.
    +     */
    +    function cloneDataView(dataView, isDeep) {
    +      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
    +      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
    +    }
    +
    +    /**
    +     * Creates a clone of `regexp`.
    +     *
    +     * @private
    +     * @param {Object} regexp The regexp to clone.
    +     * @returns {Object} Returns the cloned regexp.
    +     */
    +    function cloneRegExp(regexp) {
    +      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
    +      result.lastIndex = regexp.lastIndex;
    +      return result;
    +    }
    +
    +    /**
    +     * Creates a clone of the `symbol` object.
    +     *
    +     * @private
    +     * @param {Object} symbol The symbol object to clone.
    +     * @returns {Object} Returns the cloned symbol object.
    +     */
    +    function cloneSymbol(symbol) {
    +      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
    +    }
    +
    +    /**
    +     * Creates a clone of `typedArray`.
    +     *
    +     * @private
    +     * @param {Object} typedArray The typed array to clone.
    +     * @param {boolean} [isDeep] Specify a deep clone.
    +     * @returns {Object} Returns the cloned typed array.
    +     */
    +    function cloneTypedArray(typedArray, isDeep) {
    +      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
    +      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
    +    }
    +
    +    /**
    +     * Compares values to sort them in ascending order.
    +     *
    +     * @private
    +     * @param {*} value The value to compare.
    +     * @param {*} other The other value to compare.
    +     * @returns {number} Returns the sort order indicator for `value`.
    +     */
    +    function compareAscending(value, other) {
    +      if (value !== other) {
    +        var valIsDefined = value !== undefined$1,
    +            valIsNull = value === null,
    +            valIsReflexive = value === value,
    +            valIsSymbol = isSymbol(value);
    +
    +        var othIsDefined = other !== undefined$1,
    +            othIsNull = other === null,
    +            othIsReflexive = other === other,
    +            othIsSymbol = isSymbol(other);
    +
    +        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
    +            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
    +            (valIsNull && othIsDefined && othIsReflexive) ||
    +            (!valIsDefined && othIsReflexive) ||
    +            !valIsReflexive) {
    +          return 1;
    +        }
    +        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
    +            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
    +            (othIsNull && valIsDefined && valIsReflexive) ||
    +            (!othIsDefined && valIsReflexive) ||
    +            !othIsReflexive) {
    +          return -1;
    +        }
    +      }
    +      return 0;
    +    }
    +
    +    /**
    +     * Used by `_.orderBy` to compare multiple properties of a value to another
    +     * and stable sort them.
    +     *
    +     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
    +     * specify an order of "desc" for descending or "asc" for ascending sort order
    +     * of corresponding values.
    +     *
    +     * @private
    +     * @param {Object} object The object to compare.
    +     * @param {Object} other The other object to compare.
    +     * @param {boolean[]|string[]} orders The order to sort by for each property.
    +     * @returns {number} Returns the sort order indicator for `object`.
    +     */
    +    function compareMultiple(object, other, orders) {
    +      var index = -1,
    +          objCriteria = object.criteria,
    +          othCriteria = other.criteria,
    +          length = objCriteria.length,
    +          ordersLength = orders.length;
    +
    +      while (++index < length) {
    +        var result = compareAscending(objCriteria[index], othCriteria[index]);
    +        if (result) {
    +          if (index >= ordersLength) {
    +            return result;
    +          }
    +          var order = orders[index];
    +          return result * (order == 'desc' ? -1 : 1);
    +        }
    +      }
    +      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
    +      // that causes it, under certain circumstances, to provide the same value for
    +      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
    +      // for more details.
    +      //
    +      // This also ensures a stable sort in V8 and other engines.
    +      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
    +      return object.index - other.index;
    +    }
    +
    +    /**
    +     * Creates an array that is the composition of partially applied arguments,
    +     * placeholders, and provided arguments into a single array of arguments.
    +     *
    +     * @private
    +     * @param {Array} args The provided arguments.
    +     * @param {Array} partials The arguments to prepend to those provided.
    +     * @param {Array} holders The `partials` placeholder indexes.
    +     * @params {boolean} [isCurried] Specify composing for a curried function.
    +     * @returns {Array} Returns the new array of composed arguments.
    +     */
    +    function composeArgs(args, partials, holders, isCurried) {
    +      var argsIndex = -1,
    +          argsLength = args.length,
    +          holdersLength = holders.length,
    +          leftIndex = -1,
    +          leftLength = partials.length,
    +          rangeLength = nativeMax(argsLength - holdersLength, 0),
    +          result = Array(leftLength + rangeLength),
    +          isUncurried = !isCurried;
    +
    +      while (++leftIndex < leftLength) {
    +        result[leftIndex] = partials[leftIndex];
    +      }
    +      while (++argsIndex < holdersLength) {
    +        if (isUncurried || argsIndex < argsLength) {
    +          result[holders[argsIndex]] = args[argsIndex];
    +        }
    +      }
    +      while (rangeLength--) {
    +        result[leftIndex++] = args[argsIndex++];
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * This function is like `composeArgs` except that the arguments composition
    +     * is tailored for `_.partialRight`.
    +     *
    +     * @private
    +     * @param {Array} args The provided arguments.
    +     * @param {Array} partials The arguments to append to those provided.
    +     * @param {Array} holders The `partials` placeholder indexes.
    +     * @params {boolean} [isCurried] Specify composing for a curried function.
    +     * @returns {Array} Returns the new array of composed arguments.
    +     */
    +    function composeArgsRight(args, partials, holders, isCurried) {
    +      var argsIndex = -1,
    +          argsLength = args.length,
    +          holdersIndex = -1,
    +          holdersLength = holders.length,
    +          rightIndex = -1,
    +          rightLength = partials.length,
    +          rangeLength = nativeMax(argsLength - holdersLength, 0),
    +          result = Array(rangeLength + rightLength),
    +          isUncurried = !isCurried;
    +
    +      while (++argsIndex < rangeLength) {
    +        result[argsIndex] = args[argsIndex];
    +      }
    +      var offset = argsIndex;
    +      while (++rightIndex < rightLength) {
    +        result[offset + rightIndex] = partials[rightIndex];
    +      }
    +      while (++holdersIndex < holdersLength) {
    +        if (isUncurried || argsIndex < argsLength) {
    +          result[offset + holders[holdersIndex]] = args[argsIndex++];
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Copies the values of `source` to `array`.
    +     *
    +     * @private
    +     * @param {Array} source The array to copy values from.
    +     * @param {Array} [array=[]] The array to copy values to.
    +     * @returns {Array} Returns `array`.
    +     */
    +    function copyArray(source, array) {
    +      var index = -1,
    +          length = source.length;
    +
    +      array || (array = Array(length));
    +      while (++index < length) {
    +        array[index] = source[index];
    +      }
    +      return array;
    +    }
    +
    +    /**
    +     * Copies properties of `source` to `object`.
    +     *
    +     * @private
    +     * @param {Object} source The object to copy properties from.
    +     * @param {Array} props The property identifiers to copy.
    +     * @param {Object} [object={}] The object to copy properties to.
    +     * @param {Function} [customizer] The function to customize copied values.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function copyObject(source, props, object, customizer) {
    +      var isNew = !object;
    +      object || (object = {});
    +
    +      var index = -1,
    +          length = props.length;
    +
    +      while (++index < length) {
    +        var key = props[index];
    +
    +        var newValue = customizer
    +          ? customizer(object[key], source[key], key, object, source)
    +          : undefined$1;
    +
    +        if (newValue === undefined$1) {
    +          newValue = source[key];
    +        }
    +        if (isNew) {
    +          baseAssignValue(object, key, newValue);
    +        } else {
    +          assignValue(object, key, newValue);
    +        }
    +      }
    +      return object;
    +    }
    +
    +    /**
    +     * Copies own symbols of `source` to `object`.
    +     *
    +     * @private
    +     * @param {Object} source The object to copy symbols from.
    +     * @param {Object} [object={}] The object to copy symbols to.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function copySymbols(source, object) {
    +      return copyObject(source, getSymbols(source), object);
    +    }
    +
    +    /**
    +     * Copies own and inherited symbols of `source` to `object`.
    +     *
    +     * @private
    +     * @param {Object} source The object to copy symbols from.
    +     * @param {Object} [object={}] The object to copy symbols to.
    +     * @returns {Object} Returns `object`.
    +     */
    +    function copySymbolsIn(source, object) {
    +      return copyObject(source, getSymbolsIn(source), object);
    +    }
    +
    +    /**
    +     * Creates a function like `_.groupBy`.
    +     *
    +     * @private
    +     * @param {Function} setter The function to set accumulator values.
    +     * @param {Function} [initializer] The accumulator object initializer.
    +     * @returns {Function} Returns the new aggregator function.
    +     */
    +    function createAggregator(setter, initializer) {
    +      return function(collection, iteratee) {
    +        var func = isArray(collection) ? arrayAggregator : baseAggregator,
    +            accumulator = initializer ? initializer() : {};
    +
    +        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
    +      };
    +    }
    +
    +    /**
    +     * Creates a function like `_.assign`.
    +     *
    +     * @private
    +     * @param {Function} assigner The function to assign values.
    +     * @returns {Function} Returns the new assigner function.
    +     */
    +    function createAssigner(assigner) {
    +      return baseRest(function(object, sources) {
    +        var index = -1,
    +            length = sources.length,
    +            customizer = length > 1 ? sources[length - 1] : undefined$1,
    +            guard = length > 2 ? sources[2] : undefined$1;
    +
    +        customizer = (assigner.length > 3 && typeof customizer == 'function')
    +          ? (length--, customizer)
    +          : undefined$1;
    +
    +        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
    +          customizer = length < 3 ? undefined$1 : customizer;
    +          length = 1;
    +        }
    +        object = Object(object);
    +        while (++index < length) {
    +          var source = sources[index];
    +          if (source) {
    +            assigner(object, source, index, customizer);
    +          }
    +        }
    +        return object;
    +      });
    +    }
    +
    +    /**
    +     * Creates a `baseEach` or `baseEachRight` function.
    +     *
    +     * @private
    +     * @param {Function} eachFunc The function to iterate over a collection.
    +     * @param {boolean} [fromRight] Specify iterating from right to left.
    +     * @returns {Function} Returns the new base function.
    +     */
    +    function createBaseEach(eachFunc, fromRight) {
    +      return function(collection, iteratee) {
    +        if (collection == null) {
    +          return collection;
    +        }
    +        if (!isArrayLike(collection)) {
    +          return eachFunc(collection, iteratee);
    +        }
    +        var length = collection.length,
    +            index = fromRight ? length : -1,
    +            iterable = Object(collection);
    +
    +        while ((fromRight ? index-- : ++index < length)) {
    +          if (iteratee(iterable[index], index, iterable) === false) {
    +            break;
    +          }
    +        }
    +        return collection;
    +      };
    +    }
    +
    +    /**
    +     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
    +     *
    +     * @private
    +     * @param {boolean} [fromRight] Specify iterating from right to left.
    +     * @returns {Function} Returns the new base function.
    +     */
    +    function createBaseFor(fromRight) {
    +      return function(object, iteratee, keysFunc) {
    +        var index = -1,
    +            iterable = Object(object),
    +            props = keysFunc(object),
    +            length = props.length;
    +
    +        while (length--) {
    +          var key = props[fromRight ? length : ++index];
    +          if (iteratee(iterable[key], key, iterable) === false) {
    +            break;
    +          }
    +        }
    +        return object;
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that wraps `func` to invoke it with the optional `this`
    +     * binding of `thisArg`.
    +     *
    +     * @private
    +     * @param {Function} func The function to wrap.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @param {*} [thisArg] The `this` binding of `func`.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createBind(func, bitmask, thisArg) {
    +      var isBind = bitmask & WRAP_BIND_FLAG,
    +          Ctor = createCtor(func);
    +
    +      function wrapper() {
    +        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
    +        return fn.apply(isBind ? thisArg : this, arguments);
    +      }
    +      return wrapper;
    +    }
    +
    +    /**
    +     * Creates a function like `_.lowerFirst`.
    +     *
    +     * @private
    +     * @param {string} methodName The name of the `String` case method to use.
    +     * @returns {Function} Returns the new case function.
    +     */
    +    function createCaseFirst(methodName) {
    +      return function(string) {
    +        string = toString(string);
    +
    +        var strSymbols = hasUnicode(string)
    +          ? stringToArray(string)
    +          : undefined$1;
    +
    +        var chr = strSymbols
    +          ? strSymbols[0]
    +          : string.charAt(0);
    +
    +        var trailing = strSymbols
    +          ? castSlice(strSymbols, 1).join('')
    +          : string.slice(1);
    +
    +        return chr[methodName]() + trailing;
    +      };
    +    }
    +
    +    /**
    +     * Creates a function like `_.camelCase`.
    +     *
    +     * @private
    +     * @param {Function} callback The function to combine each word.
    +     * @returns {Function} Returns the new compounder function.
    +     */
    +    function createCompounder(callback) {
    +      return function(string) {
    +        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that produces an instance of `Ctor` regardless of
    +     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
    +     *
    +     * @private
    +     * @param {Function} Ctor The constructor to wrap.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createCtor(Ctor) {
    +      return function() {
    +        // Use a `switch` statement to work with class constructors. See
    +        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
    +        // for more details.
    +        var args = arguments;
    +        switch (args.length) {
    +          case 0: return new Ctor;
    +          case 1: return new Ctor(args[0]);
    +          case 2: return new Ctor(args[0], args[1]);
    +          case 3: return new Ctor(args[0], args[1], args[2]);
    +          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
    +          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
    +          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
    +          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
    +        }
    +        var thisBinding = baseCreate(Ctor.prototype),
    +            result = Ctor.apply(thisBinding, args);
    +
    +        // Mimic the constructor's `return` behavior.
    +        // See https://es5.github.io/#x13.2.2 for more details.
    +        return isObject(result) ? result : thisBinding;
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that wraps `func` to enable currying.
    +     *
    +     * @private
    +     * @param {Function} func The function to wrap.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @param {number} arity The arity of `func`.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createCurry(func, bitmask, arity) {
    +      var Ctor = createCtor(func);
    +
    +      function wrapper() {
    +        var length = arguments.length,
    +            args = Array(length),
    +            index = length,
    +            placeholder = getHolder(wrapper);
    +
    +        while (index--) {
    +          args[index] = arguments[index];
    +        }
    +        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
    +          ? []
    +          : replaceHolders(args, placeholder);
    +
    +        length -= holders.length;
    +        if (length < arity) {
    +          return createRecurry(
    +            func, bitmask, createHybrid, wrapper.placeholder, undefined$1,
    +            args, holders, undefined$1, undefined$1, arity - length);
    +        }
    +        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
    +        return apply(fn, this, args);
    +      }
    +      return wrapper;
    +    }
    +
    +    /**
    +     * Creates a `_.find` or `_.findLast` function.
    +     *
    +     * @private
    +     * @param {Function} findIndexFunc The function to find the collection index.
    +     * @returns {Function} Returns the new find function.
    +     */
    +    function createFind(findIndexFunc) {
    +      return function(collection, predicate, fromIndex) {
    +        var iterable = Object(collection);
    +        if (!isArrayLike(collection)) {
    +          var iteratee = getIteratee(predicate, 3);
    +          collection = keys(collection);
    +          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
    +        }
    +        var index = findIndexFunc(collection, predicate, fromIndex);
    +        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined$1;
    +      };
    +    }
    +
    +    /**
    +     * Creates a `_.flow` or `_.flowRight` function.
    +     *
    +     * @private
    +     * @param {boolean} [fromRight] Specify iterating from right to left.
    +     * @returns {Function} Returns the new flow function.
    +     */
    +    function createFlow(fromRight) {
    +      return flatRest(function(funcs) {
    +        var length = funcs.length,
    +            index = length,
    +            prereq = LodashWrapper.prototype.thru;
    +
    +        if (fromRight) {
    +          funcs.reverse();
    +        }
    +        while (index--) {
    +          var func = funcs[index];
    +          if (typeof func != 'function') {
    +            throw new TypeError(FUNC_ERROR_TEXT);
    +          }
    +          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
    +            var wrapper = new LodashWrapper([], true);
    +          }
    +        }
    +        index = wrapper ? index : length;
    +        while (++index < length) {
    +          func = funcs[index];
    +
    +          var funcName = getFuncName(func),
    +              data = funcName == 'wrapper' ? getData(func) : undefined$1;
    +
    +          if (data && isLaziable(data[0]) &&
    +                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
    +                !data[4].length && data[9] == 1
    +              ) {
    +            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
    +          } else {
    +            wrapper = (func.length == 1 && isLaziable(func))
    +              ? wrapper[funcName]()
    +              : wrapper.thru(func);
    +          }
    +        }
    +        return function() {
    +          var args = arguments,
    +              value = args[0];
    +
    +          if (wrapper && args.length == 1 && isArray(value)) {
    +            return wrapper.plant(value).value();
    +          }
    +          var index = 0,
    +              result = length ? funcs[index].apply(this, args) : value;
    +
    +          while (++index < length) {
    +            result = funcs[index].call(this, result);
    +          }
    +          return result;
    +        };
    +      });
    +    }
    +
    +    /**
    +     * Creates a function that wraps `func` to invoke it with optional `this`
    +     * binding of `thisArg`, partial application, and currying.
    +     *
    +     * @private
    +     * @param {Function|string} func The function or method name to wrap.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @param {*} [thisArg] The `this` binding of `func`.
    +     * @param {Array} [partials] The arguments to prepend to those provided to
    +     *  the new function.
    +     * @param {Array} [holders] The `partials` placeholder indexes.
    +     * @param {Array} [partialsRight] The arguments to append to those provided
    +     *  to the new function.
    +     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
    +     * @param {Array} [argPos] The argument positions of the new function.
    +     * @param {number} [ary] The arity cap of `func`.
    +     * @param {number} [arity] The arity of `func`.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
    +      var isAry = bitmask & WRAP_ARY_FLAG,
    +          isBind = bitmask & WRAP_BIND_FLAG,
    +          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
    +          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
    +          isFlip = bitmask & WRAP_FLIP_FLAG,
    +          Ctor = isBindKey ? undefined$1 : createCtor(func);
    +
    +      function wrapper() {
    +        var length = arguments.length,
    +            args = Array(length),
    +            index = length;
    +
    +        while (index--) {
    +          args[index] = arguments[index];
    +        }
    +        if (isCurried) {
    +          var placeholder = getHolder(wrapper),
    +              holdersCount = countHolders(args, placeholder);
    +        }
    +        if (partials) {
    +          args = composeArgs(args, partials, holders, isCurried);
    +        }
    +        if (partialsRight) {
    +          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
    +        }
    +        length -= holdersCount;
    +        if (isCurried && length < arity) {
    +          var newHolders = replaceHolders(args, placeholder);
    +          return createRecurry(
    +            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
    +            args, newHolders, argPos, ary, arity - length
    +          );
    +        }
    +        var thisBinding = isBind ? thisArg : this,
    +            fn = isBindKey ? thisBinding[func] : func;
    +
    +        length = args.length;
    +        if (argPos) {
    +          args = reorder(args, argPos);
    +        } else if (isFlip && length > 1) {
    +          args.reverse();
    +        }
    +        if (isAry && ary < length) {
    +          args.length = ary;
    +        }
    +        if (this && this !== root && this instanceof wrapper) {
    +          fn = Ctor || createCtor(fn);
    +        }
    +        return fn.apply(thisBinding, args);
    +      }
    +      return wrapper;
    +    }
    +
    +    /**
    +     * Creates a function like `_.invertBy`.
    +     *
    +     * @private
    +     * @param {Function} setter The function to set accumulator values.
    +     * @param {Function} toIteratee The function to resolve iteratees.
    +     * @returns {Function} Returns the new inverter function.
    +     */
    +    function createInverter(setter, toIteratee) {
    +      return function(object, iteratee) {
    +        return baseInverter(object, setter, toIteratee(iteratee), {});
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that performs a mathematical operation on two values.
    +     *
    +     * @private
    +     * @param {Function} operator The function to perform the operation.
    +     * @param {number} [defaultValue] The value used for `undefined` arguments.
    +     * @returns {Function} Returns the new mathematical operation function.
    +     */
    +    function createMathOperation(operator, defaultValue) {
    +      return function(value, other) {
    +        var result;
    +        if (value === undefined$1 && other === undefined$1) {
    +          return defaultValue;
    +        }
    +        if (value !== undefined$1) {
    +          result = value;
    +        }
    +        if (other !== undefined$1) {
    +          if (result === undefined$1) {
    +            return other;
    +          }
    +          if (typeof value == 'string' || typeof other == 'string') {
    +            value = baseToString(value);
    +            other = baseToString(other);
    +          } else {
    +            value = baseToNumber(value);
    +            other = baseToNumber(other);
    +          }
    +          result = operator(value, other);
    +        }
    +        return result;
    +      };
    +    }
    +
    +    /**
    +     * Creates a function like `_.over`.
    +     *
    +     * @private
    +     * @param {Function} arrayFunc The function to iterate over iteratees.
    +     * @returns {Function} Returns the new over function.
    +     */
    +    function createOver(arrayFunc) {
    +      return flatRest(function(iteratees) {
    +        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
    +        return baseRest(function(args) {
    +          var thisArg = this;
    +          return arrayFunc(iteratees, function(iteratee) {
    +            return apply(iteratee, thisArg, args);
    +          });
    +        });
    +      });
    +    }
    +
    +    /**
    +     * Creates the padding for `string` based on `length`. The `chars` string
    +     * is truncated if the number of characters exceeds `length`.
    +     *
    +     * @private
    +     * @param {number} length The padding length.
    +     * @param {string} [chars=' '] The string used as padding.
    +     * @returns {string} Returns the padding for `string`.
    +     */
    +    function createPadding(length, chars) {
    +      chars = chars === undefined$1 ? ' ' : baseToString(chars);
    +
    +      var charsLength = chars.length;
    +      if (charsLength < 2) {
    +        return charsLength ? baseRepeat(chars, length) : chars;
    +      }
    +      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
    +      return hasUnicode(chars)
    +        ? castSlice(stringToArray(result), 0, length).join('')
    +        : result.slice(0, length);
    +    }
    +
    +    /**
    +     * Creates a function that wraps `func` to invoke it with the `this` binding
    +     * of `thisArg` and `partials` prepended to the arguments it receives.
    +     *
    +     * @private
    +     * @param {Function} func The function to wrap.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @param {*} thisArg The `this` binding of `func`.
    +     * @param {Array} partials The arguments to prepend to those provided to
    +     *  the new function.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createPartial(func, bitmask, thisArg, partials) {
    +      var isBind = bitmask & WRAP_BIND_FLAG,
    +          Ctor = createCtor(func);
    +
    +      function wrapper() {
    +        var argsIndex = -1,
    +            argsLength = arguments.length,
    +            leftIndex = -1,
    +            leftLength = partials.length,
    +            args = Array(leftLength + argsLength),
    +            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
    +
    +        while (++leftIndex < leftLength) {
    +          args[leftIndex] = partials[leftIndex];
    +        }
    +        while (argsLength--) {
    +          args[leftIndex++] = arguments[++argsIndex];
    +        }
    +        return apply(fn, isBind ? thisArg : this, args);
    +      }
    +      return wrapper;
    +    }
    +
    +    /**
    +     * Creates a `_.range` or `_.rangeRight` function.
    +     *
    +     * @private
    +     * @param {boolean} [fromRight] Specify iterating from right to left.
    +     * @returns {Function} Returns the new range function.
    +     */
    +    function createRange(fromRight) {
    +      return function(start, end, step) {
    +        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
    +          end = step = undefined$1;
    +        }
    +        // Ensure the sign of `-0` is preserved.
    +        start = toFinite(start);
    +        if (end === undefined$1) {
    +          end = start;
    +          start = 0;
    +        } else {
    +          end = toFinite(end);
    +        }
    +        step = step === undefined$1 ? (start < end ? 1 : -1) : toFinite(step);
    +        return baseRange(start, end, step, fromRight);
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that performs a relational operation on two values.
    +     *
    +     * @private
    +     * @param {Function} operator The function to perform the operation.
    +     * @returns {Function} Returns the new relational operation function.
    +     */
    +    function createRelationalOperation(operator) {
    +      return function(value, other) {
    +        if (!(typeof value == 'string' && typeof other == 'string')) {
    +          value = toNumber(value);
    +          other = toNumber(other);
    +        }
    +        return operator(value, other);
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that wraps `func` to continue currying.
    +     *
    +     * @private
    +     * @param {Function} func The function to wrap.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @param {Function} wrapFunc The function to create the `func` wrapper.
    +     * @param {*} placeholder The placeholder value.
    +     * @param {*} [thisArg] The `this` binding of `func`.
    +     * @param {Array} [partials] The arguments to prepend to those provided to
    +     *  the new function.
    +     * @param {Array} [holders] The `partials` placeholder indexes.
    +     * @param {Array} [argPos] The argument positions of the new function.
    +     * @param {number} [ary] The arity cap of `func`.
    +     * @param {number} [arity] The arity of `func`.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
    +      var isCurry = bitmask & WRAP_CURRY_FLAG,
    +          newHolders = isCurry ? holders : undefined$1,
    +          newHoldersRight = isCurry ? undefined$1 : holders,
    +          newPartials = isCurry ? partials : undefined$1,
    +          newPartialsRight = isCurry ? undefined$1 : partials;
    +
    +      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
    +      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
    +
    +      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
    +        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
    +      }
    +      var newData = [
    +        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
    +        newHoldersRight, argPos, ary, arity
    +      ];
    +
    +      var result = wrapFunc.apply(undefined$1, newData);
    +      if (isLaziable(func)) {
    +        setData(result, newData);
    +      }
    +      result.placeholder = placeholder;
    +      return setWrapToString(result, func, bitmask);
    +    }
    +
    +    /**
    +     * Creates a function like `_.round`.
    +     *
    +     * @private
    +     * @param {string} methodName The name of the `Math` method to use when rounding.
    +     * @returns {Function} Returns the new round function.
    +     */
    +    function createRound(methodName) {
    +      var func = Math[methodName];
    +      return function(number, precision) {
    +        number = toNumber(number);
    +        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
    +        if (precision && nativeIsFinite(number)) {
    +          // Shift with exponential notation to avoid floating-point issues.
    +          // See [MDN](https://mdn.io/round#Examples) for more details.
    +          var pair = (toString(number) + 'e').split('e'),
    +              value = func(pair[0] + 'e' + (+pair[1] + precision));
    +
    +          pair = (toString(value) + 'e').split('e');
    +          return +(pair[0] + 'e' + (+pair[1] - precision));
    +        }
    +        return func(number);
    +      };
    +    }
    +
    +    /**
    +     * Creates a set object of `values`.
    +     *
    +     * @private
    +     * @param {Array} values The values to add to the set.
    +     * @returns {Object} Returns the new set.
    +     */
    +    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
    +      return new Set(values);
    +    };
    +
    +    /**
    +     * Creates a `_.toPairs` or `_.toPairsIn` function.
    +     *
    +     * @private
    +     * @param {Function} keysFunc The function to get the keys of a given object.
    +     * @returns {Function} Returns the new pairs function.
    +     */
    +    function createToPairs(keysFunc) {
    +      return function(object) {
    +        var tag = getTag(object);
    +        if (tag == mapTag) {
    +          return mapToArray(object);
    +        }
    +        if (tag == setTag) {
    +          return setToPairs(object);
    +        }
    +        return baseToPairs(object, keysFunc(object));
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that either curries or invokes `func` with optional
    +     * `this` binding and partially applied arguments.
    +     *
    +     * @private
    +     * @param {Function|string} func The function or method name to wrap.
    +     * @param {number} bitmask The bitmask flags.
    +     *    1 - `_.bind`
    +     *    2 - `_.bindKey`
    +     *    4 - `_.curry` or `_.curryRight` of a bound function
    +     *    8 - `_.curry`
    +     *   16 - `_.curryRight`
    +     *   32 - `_.partial`
    +     *   64 - `_.partialRight`
    +     *  128 - `_.rearg`
    +     *  256 - `_.ary`
    +     *  512 - `_.flip`
    +     * @param {*} [thisArg] The `this` binding of `func`.
    +     * @param {Array} [partials] The arguments to be partially applied.
    +     * @param {Array} [holders] The `partials` placeholder indexes.
    +     * @param {Array} [argPos] The argument positions of the new function.
    +     * @param {number} [ary] The arity cap of `func`.
    +     * @param {number} [arity] The arity of `func`.
    +     * @returns {Function} Returns the new wrapped function.
    +     */
    +    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
    +      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
    +      if (!isBindKey && typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      var length = partials ? partials.length : 0;
    +      if (!length) {
    +        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
    +        partials = holders = undefined$1;
    +      }
    +      ary = ary === undefined$1 ? ary : nativeMax(toInteger(ary), 0);
    +      arity = arity === undefined$1 ? arity : toInteger(arity);
    +      length -= holders ? holders.length : 0;
    +
    +      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
    +        var partialsRight = partials,
    +            holdersRight = holders;
    +
    +        partials = holders = undefined$1;
    +      }
    +      var data = isBindKey ? undefined$1 : getData(func);
    +
    +      var newData = [
    +        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
    +        argPos, ary, arity
    +      ];
    +
    +      if (data) {
    +        mergeData(newData, data);
    +      }
    +      func = newData[0];
    +      bitmask = newData[1];
    +      thisArg = newData[2];
    +      partials = newData[3];
    +      holders = newData[4];
    +      arity = newData[9] = newData[9] === undefined$1
    +        ? (isBindKey ? 0 : func.length)
    +        : nativeMax(newData[9] - length, 0);
    +
    +      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
    +        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
    +      }
    +      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
    +        var result = createBind(func, bitmask, thisArg);
    +      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
    +        result = createCurry(func, bitmask, arity);
    +      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
    +        result = createPartial(func, bitmask, thisArg, partials);
    +      } else {
    +        result = createHybrid.apply(undefined$1, newData);
    +      }
    +      var setter = data ? baseSetData : setData;
    +      return setWrapToString(setter(result, newData), func, bitmask);
    +    }
    +
    +    /**
    +     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
    +     * of source objects to the destination object for all destination properties
    +     * that resolve to `undefined`.
    +     *
    +     * @private
    +     * @param {*} objValue The destination value.
    +     * @param {*} srcValue The source value.
    +     * @param {string} key The key of the property to assign.
    +     * @param {Object} object The parent object of `objValue`.
    +     * @returns {*} Returns the value to assign.
    +     */
    +    function customDefaultsAssignIn(objValue, srcValue, key, object) {
    +      if (objValue === undefined$1 ||
    +          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
    +        return srcValue;
    +      }
    +      return objValue;
    +    }
    +
    +    /**
    +     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
    +     * objects into destination objects that are passed thru.
    +     *
    +     * @private
    +     * @param {*} objValue The destination value.
    +     * @param {*} srcValue The source value.
    +     * @param {string} key The key of the property to merge.
    +     * @param {Object} object The parent object of `objValue`.
    +     * @param {Object} source The parent object of `srcValue`.
    +     * @param {Object} [stack] Tracks traversed source values and their merged
    +     *  counterparts.
    +     * @returns {*} Returns the value to assign.
    +     */
    +    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
    +      if (isObject(objValue) && isObject(srcValue)) {
    +        // Recursively merge objects and arrays (susceptible to call stack limits).
    +        stack.set(srcValue, objValue);
    +        baseMerge(objValue, srcValue, undefined$1, customDefaultsMerge, stack);
    +        stack['delete'](srcValue);
    +      }
    +      return objValue;
    +    }
    +
    +    /**
    +     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
    +     * objects.
    +     *
    +     * @private
    +     * @param {*} value The value to inspect.
    +     * @param {string} key The key of the property to inspect.
    +     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
    +     */
    +    function customOmitClone(value) {
    +      return isPlainObject(value) ? undefined$1 : value;
    +    }
    +
    +    /**
    +     * A specialized version of `baseIsEqualDeep` for arrays with support for
    +     * partial deep comparisons.
    +     *
    +     * @private
    +     * @param {Array} array The array to compare.
    +     * @param {Array} other The other array to compare.
    +     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
    +     * @param {Function} customizer The function to customize comparisons.
    +     * @param {Function} equalFunc The function to determine equivalents of values.
    +     * @param {Object} stack Tracks traversed `array` and `other` objects.
    +     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
    +     */
    +    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
    +      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
    +          arrLength = array.length,
    +          othLength = other.length;
    +
    +      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
    +        return false;
    +      }
    +      // Check that cyclic values are equal.
    +      var arrStacked = stack.get(array);
    +      var othStacked = stack.get(other);
    +      if (arrStacked && othStacked) {
    +        return arrStacked == other && othStacked == array;
    +      }
    +      var index = -1,
    +          result = true,
    +          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined$1;
    +
    +      stack.set(array, other);
    +      stack.set(other, array);
    +
    +      // Ignore non-index properties.
    +      while (++index < arrLength) {
    +        var arrValue = array[index],
    +            othValue = other[index];
    +
    +        if (customizer) {
    +          var compared = isPartial
    +            ? customizer(othValue, arrValue, index, other, array, stack)
    +            : customizer(arrValue, othValue, index, array, other, stack);
    +        }
    +        if (compared !== undefined$1) {
    +          if (compared) {
    +            continue;
    +          }
    +          result = false;
    +          break;
    +        }
    +        // Recursively compare arrays (susceptible to call stack limits).
    +        if (seen) {
    +          if (!arraySome(other, function(othValue, othIndex) {
    +                if (!cacheHas(seen, othIndex) &&
    +                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
    +                  return seen.push(othIndex);
    +                }
    +              })) {
    +            result = false;
    +            break;
    +          }
    +        } else if (!(
    +              arrValue === othValue ||
    +                equalFunc(arrValue, othValue, bitmask, customizer, stack)
    +            )) {
    +          result = false;
    +          break;
    +        }
    +      }
    +      stack['delete'](array);
    +      stack['delete'](other);
    +      return result;
    +    }
    +
    +    /**
    +     * A specialized version of `baseIsEqualDeep` for comparing objects of
    +     * the same `toStringTag`.
    +     *
    +     * **Note:** This function only supports comparing values with tags of
    +     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
    +     *
    +     * @private
    +     * @param {Object} object The object to compare.
    +     * @param {Object} other The other object to compare.
    +     * @param {string} tag The `toStringTag` of the objects to compare.
    +     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
    +     * @param {Function} customizer The function to customize comparisons.
    +     * @param {Function} equalFunc The function to determine equivalents of values.
    +     * @param {Object} stack Tracks traversed `object` and `other` objects.
    +     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
    +     */
    +    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
    +      switch (tag) {
    +        case dataViewTag:
    +          if ((object.byteLength != other.byteLength) ||
    +              (object.byteOffset != other.byteOffset)) {
    +            return false;
    +          }
    +          object = object.buffer;
    +          other = other.buffer;
    +
    +        case arrayBufferTag:
    +          if ((object.byteLength != other.byteLength) ||
    +              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
    +            return false;
    +          }
    +          return true;
    +
    +        case boolTag:
    +        case dateTag:
    +        case numberTag:
    +          // Coerce booleans to `1` or `0` and dates to milliseconds.
    +          // Invalid dates are coerced to `NaN`.
    +          return eq(+object, +other);
    +
    +        case errorTag:
    +          return object.name == other.name && object.message == other.message;
    +
    +        case regexpTag:
    +        case stringTag:
    +          // Coerce regexes to strings and treat strings, primitives and objects,
    +          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
    +          // for more details.
    +          return object == (other + '');
    +
    +        case mapTag:
    +          var convert = mapToArray;
    +
    +        case setTag:
    +          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
    +          convert || (convert = setToArray);
    +
    +          if (object.size != other.size && !isPartial) {
    +            return false;
    +          }
    +          // Assume cyclic values are equal.
    +          var stacked = stack.get(object);
    +          if (stacked) {
    +            return stacked == other;
    +          }
    +          bitmask |= COMPARE_UNORDERED_FLAG;
    +
    +          // Recursively compare objects (susceptible to call stack limits).
    +          stack.set(object, other);
    +          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
    +          stack['delete'](object);
    +          return result;
    +
    +        case symbolTag:
    +          if (symbolValueOf) {
    +            return symbolValueOf.call(object) == symbolValueOf.call(other);
    +          }
    +      }
    +      return false;
    +    }
    +
    +    /**
    +     * A specialized version of `baseIsEqualDeep` for objects with support for
    +     * partial deep comparisons.
    +     *
    +     * @private
    +     * @param {Object} object The object to compare.
    +     * @param {Object} other The other object to compare.
    +     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
    +     * @param {Function} customizer The function to customize comparisons.
    +     * @param {Function} equalFunc The function to determine equivalents of values.
    +     * @param {Object} stack Tracks traversed `object` and `other` objects.
    +     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
    +     */
    +    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
    +      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
    +          objProps = getAllKeys(object),
    +          objLength = objProps.length,
    +          othProps = getAllKeys(other),
    +          othLength = othProps.length;
    +
    +      if (objLength != othLength && !isPartial) {
    +        return false;
    +      }
    +      var index = objLength;
    +      while (index--) {
    +        var key = objProps[index];
    +        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
    +          return false;
    +        }
    +      }
    +      // Check that cyclic values are equal.
    +      var objStacked = stack.get(object);
    +      var othStacked = stack.get(other);
    +      if (objStacked && othStacked) {
    +        return objStacked == other && othStacked == object;
    +      }
    +      var result = true;
    +      stack.set(object, other);
    +      stack.set(other, object);
    +
    +      var skipCtor = isPartial;
    +      while (++index < objLength) {
    +        key = objProps[index];
    +        var objValue = object[key],
    +            othValue = other[key];
    +
    +        if (customizer) {
    +          var compared = isPartial
    +            ? customizer(othValue, objValue, key, other, object, stack)
    +            : customizer(objValue, othValue, key, object, other, stack);
    +        }
    +        // Recursively compare objects (susceptible to call stack limits).
    +        if (!(compared === undefined$1
    +              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
    +              : compared
    +            )) {
    +          result = false;
    +          break;
    +        }
    +        skipCtor || (skipCtor = key == 'constructor');
    +      }
    +      if (result && !skipCtor) {
    +        var objCtor = object.constructor,
    +            othCtor = other.constructor;
    +
    +        // Non `Object` object instances with different constructors are not equal.
    +        if (objCtor != othCtor &&
    +            ('constructor' in object && 'constructor' in other) &&
    +            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
    +              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
    +          result = false;
    +        }
    +      }
    +      stack['delete'](object);
    +      stack['delete'](other);
    +      return result;
    +    }
    +
    +    /**
    +     * A specialized version of `baseRest` which flattens the rest array.
    +     *
    +     * @private
    +     * @param {Function} func The function to apply a rest parameter to.
    +     * @returns {Function} Returns the new function.
    +     */
    +    function flatRest(func) {
    +      return setToString(overRest(func, undefined$1, flatten), func + '');
    +    }
    +
    +    /**
    +     * Creates an array of own enumerable property names and symbols of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of property names and symbols.
    +     */
    +    function getAllKeys(object) {
    +      return baseGetAllKeys(object, keys, getSymbols);
    +    }
    +
    +    /**
    +     * Creates an array of own and inherited enumerable property names and
    +     * symbols of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of property names and symbols.
    +     */
    +    function getAllKeysIn(object) {
    +      return baseGetAllKeys(object, keysIn, getSymbolsIn);
    +    }
    +
    +    /**
    +     * Gets metadata for `func`.
    +     *
    +     * @private
    +     * @param {Function} func The function to query.
    +     * @returns {*} Returns the metadata for `func`.
    +     */
    +    var getData = !metaMap ? noop : function(func) {
    +      return metaMap.get(func);
    +    };
    +
    +    /**
    +     * Gets the name of `func`.
    +     *
    +     * @private
    +     * @param {Function} func The function to query.
    +     * @returns {string} Returns the function name.
    +     */
    +    function getFuncName(func) {
    +      var result = (func.name + ''),
    +          array = realNames[result],
    +          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
    +
    +      while (length--) {
    +        var data = array[length],
    +            otherFunc = data.func;
    +        if (otherFunc == null || otherFunc == func) {
    +          return data.name;
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Gets the argument placeholder value for `func`.
    +     *
    +     * @private
    +     * @param {Function} func The function to inspect.
    +     * @returns {*} Returns the placeholder value.
    +     */
    +    function getHolder(func) {
    +      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
    +      return object.placeholder;
    +    }
    +
    +    /**
    +     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
    +     * this function returns the custom method, otherwise it returns `baseIteratee`.
    +     * If arguments are provided, the chosen function is invoked with them and
    +     * its result is returned.
    +     *
    +     * @private
    +     * @param {*} [value] The value to convert to an iteratee.
    +     * @param {number} [arity] The arity of the created iteratee.
    +     * @returns {Function} Returns the chosen function or its result.
    +     */
    +    function getIteratee() {
    +      var result = lodash.iteratee || iteratee;
    +      result = result === iteratee ? baseIteratee : result;
    +      return arguments.length ? result(arguments[0], arguments[1]) : result;
    +    }
    +
    +    /**
    +     * Gets the data for `map`.
    +     *
    +     * @private
    +     * @param {Object} map The map to query.
    +     * @param {string} key The reference key.
    +     * @returns {*} Returns the map data.
    +     */
    +    function getMapData(map, key) {
    +      var data = map.__data__;
    +      return isKeyable(key)
    +        ? data[typeof key == 'string' ? 'string' : 'hash']
    +        : data.map;
    +    }
    +
    +    /**
    +     * Gets the property names, values, and compare flags of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the match data of `object`.
    +     */
    +    function getMatchData(object) {
    +      var result = keys(object),
    +          length = result.length;
    +
    +      while (length--) {
    +        var key = result[length],
    +            value = object[key];
    +
    +        result[length] = [key, value, isStrictComparable(value)];
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Gets the native function at `key` of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {string} key The key of the method to get.
    +     * @returns {*} Returns the function if it's native, else `undefined`.
    +     */
    +    function getNative(object, key) {
    +      var value = getValue(object, key);
    +      return baseIsNative(value) ? value : undefined$1;
    +    }
    +
    +    /**
    +     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
    +     *
    +     * @private
    +     * @param {*} value The value to query.
    +     * @returns {string} Returns the raw `toStringTag`.
    +     */
    +    function getRawTag(value) {
    +      var isOwn = hasOwnProperty.call(value, symToStringTag),
    +          tag = value[symToStringTag];
    +
    +      try {
    +        value[symToStringTag] = undefined$1;
    +        var unmasked = true;
    +      } catch (e) {}
    +
    +      var result = nativeObjectToString.call(value);
    +      if (unmasked) {
    +        if (isOwn) {
    +          value[symToStringTag] = tag;
    +        } else {
    +          delete value[symToStringTag];
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Creates an array of the own enumerable symbols of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of symbols.
    +     */
    +    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
    +      if (object == null) {
    +        return [];
    +      }
    +      object = Object(object);
    +      return arrayFilter(nativeGetSymbols(object), function(symbol) {
    +        return propertyIsEnumerable.call(object, symbol);
    +      });
    +    };
    +
    +    /**
    +     * Creates an array of the own and inherited enumerable symbols of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of symbols.
    +     */
    +    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
    +      var result = [];
    +      while (object) {
    +        arrayPush(result, getSymbols(object));
    +        object = getPrototype(object);
    +      }
    +      return result;
    +    };
    +
    +    /**
    +     * Gets the `toStringTag` of `value`.
    +     *
    +     * @private
    +     * @param {*} value The value to query.
    +     * @returns {string} Returns the `toStringTag`.
    +     */
    +    var getTag = baseGetTag;
    +
    +    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
    +    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
    +        (Map && getTag(new Map) != mapTag) ||
    +        (Promise && getTag(Promise.resolve()) != promiseTag) ||
    +        (Set && getTag(new Set) != setTag) ||
    +        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
    +      getTag = function(value) {
    +        var result = baseGetTag(value),
    +            Ctor = result == objectTag ? value.constructor : undefined$1,
    +            ctorString = Ctor ? toSource(Ctor) : '';
    +
    +        if (ctorString) {
    +          switch (ctorString) {
    +            case dataViewCtorString: return dataViewTag;
    +            case mapCtorString: return mapTag;
    +            case promiseCtorString: return promiseTag;
    +            case setCtorString: return setTag;
    +            case weakMapCtorString: return weakMapTag;
    +          }
    +        }
    +        return result;
    +      };
    +    }
    +
    +    /**
    +     * Gets the view, applying any `transforms` to the `start` and `end` positions.
    +     *
    +     * @private
    +     * @param {number} start The start of the view.
    +     * @param {number} end The end of the view.
    +     * @param {Array} transforms The transformations to apply to the view.
    +     * @returns {Object} Returns an object containing the `start` and `end`
    +     *  positions of the view.
    +     */
    +    function getView(start, end, transforms) {
    +      var index = -1,
    +          length = transforms.length;
    +
    +      while (++index < length) {
    +        var data = transforms[index],
    +            size = data.size;
    +
    +        switch (data.type) {
    +          case 'drop':      start += size; break;
    +          case 'dropRight': end -= size; break;
    +          case 'take':      end = nativeMin(end, start + size); break;
    +          case 'takeRight': start = nativeMax(start, end - size); break;
    +        }
    +      }
    +      return { 'start': start, 'end': end };
    +    }
    +
    +    /**
    +     * Extracts wrapper details from the `source` body comment.
    +     *
    +     * @private
    +     * @param {string} source The source to inspect.
    +     * @returns {Array} Returns the wrapper details.
    +     */
    +    function getWrapDetails(source) {
    +      var match = source.match(reWrapDetails);
    +      return match ? match[1].split(reSplitDetails) : [];
    +    }
    +
    +    /**
    +     * Checks if `path` exists on `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {Array|string} path The path to check.
    +     * @param {Function} hasFunc The function to check properties.
    +     * @returns {boolean} Returns `true` if `path` exists, else `false`.
    +     */
    +    function hasPath(object, path, hasFunc) {
    +      path = castPath(path, object);
    +
    +      var index = -1,
    +          length = path.length,
    +          result = false;
    +
    +      while (++index < length) {
    +        var key = toKey(path[index]);
    +        if (!(result = object != null && hasFunc(object, key))) {
    +          break;
    +        }
    +        object = object[key];
    +      }
    +      if (result || ++index != length) {
    +        return result;
    +      }
    +      length = object == null ? 0 : object.length;
    +      return !!length && isLength(length) && isIndex(key, length) &&
    +        (isArray(object) || isArguments(object));
    +    }
    +
    +    /**
    +     * Initializes an array clone.
    +     *
    +     * @private
    +     * @param {Array} array The array to clone.
    +     * @returns {Array} Returns the initialized clone.
    +     */
    +    function initCloneArray(array) {
    +      var length = array.length,
    +          result = new array.constructor(length);
    +
    +      // Add properties assigned by `RegExp#exec`.
    +      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
    +        result.index = array.index;
    +        result.input = array.input;
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Initializes an object clone.
    +     *
    +     * @private
    +     * @param {Object} object The object to clone.
    +     * @returns {Object} Returns the initialized clone.
    +     */
    +    function initCloneObject(object) {
    +      return (typeof object.constructor == 'function' && !isPrototype(object))
    +        ? baseCreate(getPrototype(object))
    +        : {};
    +    }
    +
    +    /**
    +     * Initializes an object clone based on its `toStringTag`.
    +     *
    +     * **Note:** This function only supports cloning values with tags of
    +     * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
    +     *
    +     * @private
    +     * @param {Object} object The object to clone.
    +     * @param {string} tag The `toStringTag` of the object to clone.
    +     * @param {boolean} [isDeep] Specify a deep clone.
    +     * @returns {Object} Returns the initialized clone.
    +     */
    +    function initCloneByTag(object, tag, isDeep) {
    +      var Ctor = object.constructor;
    +      switch (tag) {
    +        case arrayBufferTag:
    +          return cloneArrayBuffer(object);
    +
    +        case boolTag:
    +        case dateTag:
    +          return new Ctor(+object);
    +
    +        case dataViewTag:
    +          return cloneDataView(object, isDeep);
    +
    +        case float32Tag: case float64Tag:
    +        case int8Tag: case int16Tag: case int32Tag:
    +        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
    +          return cloneTypedArray(object, isDeep);
    +
    +        case mapTag:
    +          return new Ctor;
    +
    +        case numberTag:
    +        case stringTag:
    +          return new Ctor(object);
    +
    +        case regexpTag:
    +          return cloneRegExp(object);
    +
    +        case setTag:
    +          return new Ctor;
    +
    +        case symbolTag:
    +          return cloneSymbol(object);
    +      }
    +    }
    +
    +    /**
    +     * Inserts wrapper `details` in a comment at the top of the `source` body.
    +     *
    +     * @private
    +     * @param {string} source The source to modify.
    +     * @returns {Array} details The details to insert.
    +     * @returns {string} Returns the modified source.
    +     */
    +    function insertWrapDetails(source, details) {
    +      var length = details.length;
    +      if (!length) {
    +        return source;
    +      }
    +      var lastIndex = length - 1;
    +      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
    +      details = details.join(length > 2 ? ', ' : ' ');
    +      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
    +    }
    +
    +    /**
    +     * Checks if `value` is a flattenable `arguments` object or array.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
    +     */
    +    function isFlattenable(value) {
    +      return isArray(value) || isArguments(value) ||
    +        !!(spreadableSymbol && value && value[spreadableSymbol]);
    +    }
    +
    +    /**
    +     * Checks if `value` is a valid array-like index.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
    +     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
    +     */
    +    function isIndex(value, length) {
    +      var type = typeof value;
    +      length = length == null ? MAX_SAFE_INTEGER : length;
    +
    +      return !!length &&
    +        (type == 'number' ||
    +          (type != 'symbol' && reIsUint.test(value))) &&
    +            (value > -1 && value % 1 == 0 && value < length);
    +    }
    +
    +    /**
    +     * Checks if the given arguments are from an iteratee call.
    +     *
    +     * @private
    +     * @param {*} value The potential iteratee value argument.
    +     * @param {*} index The potential iteratee index or key argument.
    +     * @param {*} object The potential iteratee object argument.
    +     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
    +     *  else `false`.
    +     */
    +    function isIterateeCall(value, index, object) {
    +      if (!isObject(object)) {
    +        return false;
    +      }
    +      var type = typeof index;
    +      if (type == 'number'
    +            ? (isArrayLike(object) && isIndex(index, object.length))
    +            : (type == 'string' && index in object)
    +          ) {
    +        return eq(object[index], value);
    +      }
    +      return false;
    +    }
    +
    +    /**
    +     * Checks if `value` is a property name and not a property path.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @param {Object} [object] The object to query keys on.
    +     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
    +     */
    +    function isKey(value, object) {
    +      if (isArray(value)) {
    +        return false;
    +      }
    +      var type = typeof value;
    +      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
    +          value == null || isSymbol(value)) {
    +        return true;
    +      }
    +      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
    +        (object != null && value in Object(object));
    +    }
    +
    +    /**
    +     * Checks if `value` is suitable for use as unique object key.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
    +     */
    +    function isKeyable(value) {
    +      var type = typeof value;
    +      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
    +        ? (value !== '__proto__')
    +        : (value === null);
    +    }
    +
    +    /**
    +     * Checks if `func` has a lazy counterpart.
    +     *
    +     * @private
    +     * @param {Function} func The function to check.
    +     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
    +     *  else `false`.
    +     */
    +    function isLaziable(func) {
    +      var funcName = getFuncName(func),
    +          other = lodash[funcName];
    +
    +      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
    +        return false;
    +      }
    +      if (func === other) {
    +        return true;
    +      }
    +      var data = getData(other);
    +      return !!data && func === data[0];
    +    }
    +
    +    /**
    +     * Checks if `func` has its source masked.
    +     *
    +     * @private
    +     * @param {Function} func The function to check.
    +     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
    +     */
    +    function isMasked(func) {
    +      return !!maskSrcKey && (maskSrcKey in func);
    +    }
    +
    +    /**
    +     * Checks if `func` is capable of being masked.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
    +     */
    +    var isMaskable = coreJsData ? isFunction : stubFalse;
    +
    +    /**
    +     * Checks if `value` is likely a prototype object.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
    +     */
    +    function isPrototype(value) {
    +      var Ctor = value && value.constructor,
    +          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
    +
    +      return value === proto;
    +    }
    +
    +    /**
    +     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
    +     *
    +     * @private
    +     * @param {*} value The value to check.
    +     * @returns {boolean} Returns `true` if `value` if suitable for strict
    +     *  equality comparisons, else `false`.
    +     */
    +    function isStrictComparable(value) {
    +      return value === value && !isObject(value);
    +    }
    +
    +    /**
    +     * A specialized version of `matchesProperty` for source values suitable
    +     * for strict equality comparisons, i.e. `===`.
    +     *
    +     * @private
    +     * @param {string} key The key of the property to get.
    +     * @param {*} srcValue The value to match.
    +     * @returns {Function} Returns the new spec function.
    +     */
    +    function matchesStrictComparable(key, srcValue) {
    +      return function(object) {
    +        if (object == null) {
    +          return false;
    +        }
    +        return object[key] === srcValue &&
    +          (srcValue !== undefined$1 || (key in Object(object)));
    +      };
    +    }
    +
    +    /**
    +     * A specialized version of `_.memoize` which clears the memoized function's
    +     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
    +     *
    +     * @private
    +     * @param {Function} func The function to have its output memoized.
    +     * @returns {Function} Returns the new memoized function.
    +     */
    +    function memoizeCapped(func) {
    +      var result = memoize(func, function(key) {
    +        if (cache.size === MAX_MEMOIZE_SIZE) {
    +          cache.clear();
    +        }
    +        return key;
    +      });
    +
    +      var cache = result.cache;
    +      return result;
    +    }
    +
    +    /**
    +     * Merges the function metadata of `source` into `data`.
    +     *
    +     * Merging metadata reduces the number of wrappers used to invoke a function.
    +     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
    +     * may be applied regardless of execution order. Methods like `_.ary` and
    +     * `_.rearg` modify function arguments, making the order in which they are
    +     * executed important, preventing the merging of metadata. However, we make
    +     * an exception for a safe combined case where curried functions have `_.ary`
    +     * and or `_.rearg` applied.
    +     *
    +     * @private
    +     * @param {Array} data The destination metadata.
    +     * @param {Array} source The source metadata.
    +     * @returns {Array} Returns `data`.
    +     */
    +    function mergeData(data, source) {
    +      var bitmask = data[1],
    +          srcBitmask = source[1],
    +          newBitmask = bitmask | srcBitmask,
    +          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
    +
    +      var isCombo =
    +        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
    +        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
    +        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
    +
    +      // Exit early if metadata can't be merged.
    +      if (!(isCommon || isCombo)) {
    +        return data;
    +      }
    +      // Use source `thisArg` if available.
    +      if (srcBitmask & WRAP_BIND_FLAG) {
    +        data[2] = source[2];
    +        // Set when currying a bound function.
    +        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
    +      }
    +      // Compose partial arguments.
    +      var value = source[3];
    +      if (value) {
    +        var partials = data[3];
    +        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
    +        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
    +      }
    +      // Compose partial right arguments.
    +      value = source[5];
    +      if (value) {
    +        partials = data[5];
    +        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
    +        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
    +      }
    +      // Use source `argPos` if available.
    +      value = source[7];
    +      if (value) {
    +        data[7] = value;
    +      }
    +      // Use source `ary` if it's smaller.
    +      if (srcBitmask & WRAP_ARY_FLAG) {
    +        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
    +      }
    +      // Use source `arity` if one is not provided.
    +      if (data[9] == null) {
    +        data[9] = source[9];
    +      }
    +      // Use source `func` and merge bitmasks.
    +      data[0] = source[0];
    +      data[1] = newBitmask;
    +
    +      return data;
    +    }
    +
    +    /**
    +     * This function is like
    +     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
    +     * except that it includes inherited enumerable properties.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @returns {Array} Returns the array of property names.
    +     */
    +    function nativeKeysIn(object) {
    +      var result = [];
    +      if (object != null) {
    +        for (var key in Object(object)) {
    +          result.push(key);
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Converts `value` to a string using `Object.prototype.toString`.
    +     *
    +     * @private
    +     * @param {*} value The value to convert.
    +     * @returns {string} Returns the converted string.
    +     */
    +    function objectToString(value) {
    +      return nativeObjectToString.call(value);
    +    }
    +
    +    /**
    +     * A specialized version of `baseRest` which transforms the rest array.
    +     *
    +     * @private
    +     * @param {Function} func The function to apply a rest parameter to.
    +     * @param {number} [start=func.length-1] The start position of the rest parameter.
    +     * @param {Function} transform The rest array transform.
    +     * @returns {Function} Returns the new function.
    +     */
    +    function overRest(func, start, transform) {
    +      start = nativeMax(start === undefined$1 ? (func.length - 1) : start, 0);
    +      return function() {
    +        var args = arguments,
    +            index = -1,
    +            length = nativeMax(args.length - start, 0),
    +            array = Array(length);
    +
    +        while (++index < length) {
    +          array[index] = args[start + index];
    +        }
    +        index = -1;
    +        var otherArgs = Array(start + 1);
    +        while (++index < start) {
    +          otherArgs[index] = args[index];
    +        }
    +        otherArgs[start] = transform(array);
    +        return apply(func, this, otherArgs);
    +      };
    +    }
    +
    +    /**
    +     * Gets the parent value at `path` of `object`.
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {Array} path The path to get the parent value of.
    +     * @returns {*} Returns the parent value.
    +     */
    +    function parent(object, path) {
    +      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
    +    }
    +
    +    /**
    +     * Reorder `array` according to the specified indexes where the element at
    +     * the first index is assigned as the first element, the element at
    +     * the second index is assigned as the second element, and so on.
    +     *
    +     * @private
    +     * @param {Array} array The array to reorder.
    +     * @param {Array} indexes The arranged array indexes.
    +     * @returns {Array} Returns `array`.
    +     */
    +    function reorder(array, indexes) {
    +      var arrLength = array.length,
    +          length = nativeMin(indexes.length, arrLength),
    +          oldArray = copyArray(array);
    +
    +      while (length--) {
    +        var index = indexes[length];
    +        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined$1;
    +      }
    +      return array;
    +    }
    +
    +    /**
    +     * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
    +     *
    +     * @private
    +     * @param {Object} object The object to query.
    +     * @param {string} key The key of the property to get.
    +     * @returns {*} Returns the property value.
    +     */
    +    function safeGet(object, key) {
    +      if (key === 'constructor' && typeof object[key] === 'function') {
    +        return;
    +      }
    +
    +      if (key == '__proto__') {
    +        return;
    +      }
    +
    +      return object[key];
    +    }
    +
    +    /**
    +     * Sets metadata for `func`.
    +     *
    +     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
    +     * period of time, it will trip its breaker and transition to an identity
    +     * function to avoid garbage collection pauses in V8. See
    +     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
    +     * for more details.
    +     *
    +     * @private
    +     * @param {Function} func The function to associate metadata with.
    +     * @param {*} data The metadata.
    +     * @returns {Function} Returns `func`.
    +     */
    +    var setData = shortOut(baseSetData);
    +
    +    /**
    +     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
    +     *
    +     * @private
    +     * @param {Function} func The function to delay.
    +     * @param {number} wait The number of milliseconds to delay invocation.
    +     * @returns {number|Object} Returns the timer id or timeout object.
    +     */
    +    var setTimeout = ctxSetTimeout || function(func, wait) {
    +      return root.setTimeout(func, wait);
    +    };
    +
    +    /**
    +     * Sets the `toString` method of `func` to return `string`.
    +     *
    +     * @private
    +     * @param {Function} func The function to modify.
    +     * @param {Function} string The `toString` result.
    +     * @returns {Function} Returns `func`.
    +     */
    +    var setToString = shortOut(baseSetToString);
    +
    +    /**
    +     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
    +     * with wrapper details in a comment at the top of the source body.
    +     *
    +     * @private
    +     * @param {Function} wrapper The function to modify.
    +     * @param {Function} reference The reference function.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @returns {Function} Returns `wrapper`.
    +     */
    +    function setWrapToString(wrapper, reference, bitmask) {
    +      var source = (reference + '');
    +      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
    +    }
    +
    +    /**
    +     * Creates a function that'll short out and invoke `identity` instead
    +     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
    +     * milliseconds.
    +     *
    +     * @private
    +     * @param {Function} func The function to restrict.
    +     * @returns {Function} Returns the new shortable function.
    +     */
    +    function shortOut(func) {
    +      var count = 0,
    +          lastCalled = 0;
    +
    +      return function() {
    +        var stamp = nativeNow(),
    +            remaining = HOT_SPAN - (stamp - lastCalled);
    +
    +        lastCalled = stamp;
    +        if (remaining > 0) {
    +          if (++count >= HOT_COUNT) {
    +            return arguments[0];
    +          }
    +        } else {
    +          count = 0;
    +        }
    +        return func.apply(undefined$1, arguments);
    +      };
    +    }
    +
    +    /**
    +     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
    +     *
    +     * @private
    +     * @param {Array} array The array to shuffle.
    +     * @param {number} [size=array.length] The size of `array`.
    +     * @returns {Array} Returns `array`.
    +     */
    +    function shuffleSelf(array, size) {
    +      var index = -1,
    +          length = array.length,
    +          lastIndex = length - 1;
    +
    +      size = size === undefined$1 ? length : size;
    +      while (++index < size) {
    +        var rand = baseRandom(index, lastIndex),
    +            value = array[rand];
    +
    +        array[rand] = array[index];
    +        array[index] = value;
    +      }
    +      array.length = size;
    +      return array;
    +    }
    +
    +    /**
    +     * Converts `string` to a property path array.
    +     *
    +     * @private
    +     * @param {string} string The string to convert.
    +     * @returns {Array} Returns the property path array.
    +     */
    +    var stringToPath = memoizeCapped(function(string) {
    +      var result = [];
    +      if (string.charCodeAt(0) === 46 /* . */) {
    +        result.push('');
    +      }
    +      string.replace(rePropName, function(match, number, quote, subString) {
    +        result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
    +      });
    +      return result;
    +    });
    +
    +    /**
    +     * Converts `value` to a string key if it's not a string or symbol.
    +     *
    +     * @private
    +     * @param {*} value The value to inspect.
    +     * @returns {string|symbol} Returns the key.
    +     */
    +    function toKey(value) {
    +      if (typeof value == 'string' || isSymbol(value)) {
    +        return value;
    +      }
    +      var result = (value + '');
    +      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
    +    }
    +
    +    /**
    +     * Converts `func` to its source code.
    +     *
    +     * @private
    +     * @param {Function} func The function to convert.
    +     * @returns {string} Returns the source code.
    +     */
    +    function toSource(func) {
    +      if (func != null) {
    +        try {
    +          return funcToString.call(func);
    +        } catch (e) {}
    +        try {
    +          return (func + '');
    +        } catch (e) {}
    +      }
    +      return '';
    +    }
    +
    +    /**
    +     * Updates wrapper `details` based on `bitmask` flags.
    +     *
    +     * @private
    +     * @returns {Array} details The details to modify.
    +     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
    +     * @returns {Array} Returns `details`.
    +     */
    +    function updateWrapDetails(details, bitmask) {
    +      arrayEach(wrapFlags, function(pair) {
    +        var value = '_.' + pair[0];
    +        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
    +          details.push(value);
    +        }
    +      });
    +      return details.sort();
    +    }
    +
    +    /**
    +     * Creates a clone of `wrapper`.
    +     *
    +     * @private
    +     * @param {Object} wrapper The wrapper to clone.
    +     * @returns {Object} Returns the cloned wrapper.
    +     */
    +    function wrapperClone(wrapper) {
    +      if (wrapper instanceof LazyWrapper) {
    +        return wrapper.clone();
    +      }
    +      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
    +      result.__actions__ = copyArray(wrapper.__actions__);
    +      result.__index__  = wrapper.__index__;
    +      result.__values__ = wrapper.__values__;
    +      return result;
    +    }
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates an array of elements split into groups the length of `size`.
    +     * If `array` can't be split evenly, the final chunk will be the remaining
    +     * elements.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to process.
    +     * @param {number} [size=1] The length of each chunk
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Array} Returns the new array of chunks.
    +     * @example
    +     *
    +     * _.chunk(['a', 'b', 'c', 'd'], 2);
    +     * // => [['a', 'b'], ['c', 'd']]
    +     *
    +     * _.chunk(['a', 'b', 'c', 'd'], 3);
    +     * // => [['a', 'b', 'c'], ['d']]
    +     */
    +    function chunk(array, size, guard) {
    +      if ((guard ? isIterateeCall(array, size, guard) : size === undefined$1)) {
    +        size = 1;
    +      } else {
    +        size = nativeMax(toInteger(size), 0);
    +      }
    +      var length = array == null ? 0 : array.length;
    +      if (!length || size < 1) {
    +        return [];
    +      }
    +      var index = 0,
    +          resIndex = 0,
    +          result = Array(nativeCeil(length / size));
    +
    +      while (index < length) {
    +        result[resIndex++] = baseSlice(array, index, (index += size));
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Creates an array with all falsey values removed. The values `false`, `null`,
    +     * `0`, `""`, `undefined`, and `NaN` are falsey.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to compact.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @example
    +     *
    +     * _.compact([0, 1, false, 2, '', 3]);
    +     * // => [1, 2, 3]
    +     */
    +    function compact(array) {
    +      var index = -1,
    +          length = array == null ? 0 : array.length,
    +          resIndex = 0,
    +          result = [];
    +
    +      while (++index < length) {
    +        var value = array[index];
    +        if (value) {
    +          result[resIndex++] = value;
    +        }
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Creates a new array concatenating `array` with any additional arrays
    +     * and/or values.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to concatenate.
    +     * @param {...*} [values] The values to concatenate.
    +     * @returns {Array} Returns the new concatenated array.
    +     * @example
    +     *
    +     * var array = [1];
    +     * var other = _.concat(array, 2, [3], [[4]]);
    +     *
    +     * console.log(other);
    +     * // => [1, 2, 3, [4]]
    +     *
    +     * console.log(array);
    +     * // => [1]
    +     */
    +    function concat() {
    +      var length = arguments.length;
    +      if (!length) {
    +        return [];
    +      }
    +      var args = Array(length - 1),
    +          array = arguments[0],
    +          index = length;
    +
    +      while (index--) {
    +        args[index - 1] = arguments[index];
    +      }
    +      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
    +    }
    +
    +    /**
    +     * Creates an array of `array` values not included in the other given arrays
    +     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons. The order and references of result values are
    +     * determined by the first array.
    +     *
    +     * **Note:** Unlike `_.pullAll`, this method returns a new array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {...Array} [values] The values to exclude.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @see _.without, _.xor
    +     * @example
    +     *
    +     * _.difference([2, 1], [2, 3]);
    +     * // => [1]
    +     */
    +    var difference = baseRest(function(array, values) {
    +      return isArrayLikeObject(array)
    +        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
    +        : [];
    +    });
    +
    +    /**
    +     * This method is like `_.difference` except that it accepts `iteratee` which
    +     * is invoked for each element of `array` and `values` to generate the criterion
    +     * by which they're compared. The order and references of result values are
    +     * determined by the first array. The iteratee is invoked with one argument:
    +     * (value).
    +     *
    +     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {...Array} [values] The values to exclude.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @example
    +     *
    +     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
    +     * // => [1.2]
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
    +     * // => [{ 'x': 2 }]
    +     */
    +    var differenceBy = baseRest(function(array, values) {
    +      var iteratee = last(values);
    +      if (isArrayLikeObject(iteratee)) {
    +        iteratee = undefined$1;
    +      }
    +      return isArrayLikeObject(array)
    +        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
    +        : [];
    +    });
    +
    +    /**
    +     * This method is like `_.difference` except that it accepts `comparator`
    +     * which is invoked to compare elements of `array` to `values`. The order and
    +     * references of result values are determined by the first array. The comparator
    +     * is invoked with two arguments: (arrVal, othVal).
    +     *
    +     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {...Array} [values] The values to exclude.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    +     *
    +     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
    +     * // => [{ 'x': 2, 'y': 1 }]
    +     */
    +    var differenceWith = baseRest(function(array, values) {
    +      var comparator = last(values);
    +      if (isArrayLikeObject(comparator)) {
    +        comparator = undefined$1;
    +      }
    +      return isArrayLikeObject(array)
    +        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined$1, comparator)
    +        : [];
    +    });
    +
    +    /**
    +     * Creates a slice of `array` with `n` elements dropped from the beginning.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.5.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {number} [n=1] The number of elements to drop.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * _.drop([1, 2, 3]);
    +     * // => [2, 3]
    +     *
    +     * _.drop([1, 2, 3], 2);
    +     * // => [3]
    +     *
    +     * _.drop([1, 2, 3], 5);
    +     * // => []
    +     *
    +     * _.drop([1, 2, 3], 0);
    +     * // => [1, 2, 3]
    +     */
    +    function drop(array, n, guard) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return [];
    +      }
    +      n = (guard || n === undefined$1) ? 1 : toInteger(n);
    +      return baseSlice(array, n < 0 ? 0 : n, length);
    +    }
    +
    +    /**
    +     * Creates a slice of `array` with `n` elements dropped from the end.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {number} [n=1] The number of elements to drop.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * _.dropRight([1, 2, 3]);
    +     * // => [1, 2]
    +     *
    +     * _.dropRight([1, 2, 3], 2);
    +     * // => [1]
    +     *
    +     * _.dropRight([1, 2, 3], 5);
    +     * // => []
    +     *
    +     * _.dropRight([1, 2, 3], 0);
    +     * // => [1, 2, 3]
    +     */
    +    function dropRight(array, n, guard) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return [];
    +      }
    +      n = (guard || n === undefined$1) ? 1 : toInteger(n);
    +      n = length - n;
    +      return baseSlice(array, 0, n < 0 ? 0 : n);
    +    }
    +
    +    /**
    +     * Creates a slice of `array` excluding elements dropped from the end.
    +     * Elements are dropped until `predicate` returns falsey. The predicate is
    +     * invoked with three arguments: (value, index, array).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'active': true },
    +     *   { 'user': 'fred',    'active': false },
    +     *   { 'user': 'pebbles', 'active': false }
    +     * ];
    +     *
    +     * _.dropRightWhile(users, function(o) { return !o.active; });
    +     * // => objects for ['barney']
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
    +     * // => objects for ['barney', 'fred']
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.dropRightWhile(users, ['active', false]);
    +     * // => objects for ['barney']
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.dropRightWhile(users, 'active');
    +     * // => objects for ['barney', 'fred', 'pebbles']
    +     */
    +    function dropRightWhile(array, predicate) {
    +      return (array && array.length)
    +        ? baseWhile(array, getIteratee(predicate, 3), true, true)
    +        : [];
    +    }
    +
    +    /**
    +     * Creates a slice of `array` excluding elements dropped from the beginning.
    +     * Elements are dropped until `predicate` returns falsey. The predicate is
    +     * invoked with three arguments: (value, index, array).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'active': false },
    +     *   { 'user': 'fred',    'active': false },
    +     *   { 'user': 'pebbles', 'active': true }
    +     * ];
    +     *
    +     * _.dropWhile(users, function(o) { return !o.active; });
    +     * // => objects for ['pebbles']
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.dropWhile(users, { 'user': 'barney', 'active': false });
    +     * // => objects for ['fred', 'pebbles']
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.dropWhile(users, ['active', false]);
    +     * // => objects for ['pebbles']
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.dropWhile(users, 'active');
    +     * // => objects for ['barney', 'fred', 'pebbles']
    +     */
    +    function dropWhile(array, predicate) {
    +      return (array && array.length)
    +        ? baseWhile(array, getIteratee(predicate, 3), true)
    +        : [];
    +    }
    +
    +    /**
    +     * Fills elements of `array` with `value` from `start` up to, but not
    +     * including, `end`.
    +     *
    +     * **Note:** This method mutates `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.2.0
    +     * @category Array
    +     * @param {Array} array The array to fill.
    +     * @param {*} value The value to fill `array` with.
    +     * @param {number} [start=0] The start position.
    +     * @param {number} [end=array.length] The end position.
    +     * @returns {Array} Returns `array`.
    +     * @example
    +     *
    +     * var array = [1, 2, 3];
    +     *
    +     * _.fill(array, 'a');
    +     * console.log(array);
    +     * // => ['a', 'a', 'a']
    +     *
    +     * _.fill(Array(3), 2);
    +     * // => [2, 2, 2]
    +     *
    +     * _.fill([4, 6, 8, 10], '*', 1, 3);
    +     * // => [4, '*', '*', 10]
    +     */
    +    function fill(array, value, start, end) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return [];
    +      }
    +      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
    +        start = 0;
    +        end = length;
    +      }
    +      return baseFill(array, value, start, end);
    +    }
    +
    +    /**
    +     * This method is like `_.find` except that it returns the index of the first
    +     * element `predicate` returns truthy for instead of the element itself.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 1.1.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @param {number} [fromIndex=0] The index to search from.
    +     * @returns {number} Returns the index of the found element, else `-1`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'active': false },
    +     *   { 'user': 'fred',    'active': false },
    +     *   { 'user': 'pebbles', 'active': true }
    +     * ];
    +     *
    +     * _.findIndex(users, function(o) { return o.user == 'barney'; });
    +     * // => 0
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.findIndex(users, { 'user': 'fred', 'active': false });
    +     * // => 1
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.findIndex(users, ['active', false]);
    +     * // => 0
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.findIndex(users, 'active');
    +     * // => 2
    +     */
    +    function findIndex(array, predicate, fromIndex) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return -1;
    +      }
    +      var index = fromIndex == null ? 0 : toInteger(fromIndex);
    +      if (index < 0) {
    +        index = nativeMax(length + index, 0);
    +      }
    +      return baseFindIndex(array, getIteratee(predicate, 3), index);
    +    }
    +
    +    /**
    +     * This method is like `_.findIndex` except that it iterates over elements
    +     * of `collection` from right to left.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @param {number} [fromIndex=array.length-1] The index to search from.
    +     * @returns {number} Returns the index of the found element, else `-1`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'active': true },
    +     *   { 'user': 'fred',    'active': false },
    +     *   { 'user': 'pebbles', 'active': false }
    +     * ];
    +     *
    +     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
    +     * // => 2
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
    +     * // => 0
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.findLastIndex(users, ['active', false]);
    +     * // => 2
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.findLastIndex(users, 'active');
    +     * // => 0
    +     */
    +    function findLastIndex(array, predicate, fromIndex) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return -1;
    +      }
    +      var index = length - 1;
    +      if (fromIndex !== undefined$1) {
    +        index = toInteger(fromIndex);
    +        index = fromIndex < 0
    +          ? nativeMax(length + index, 0)
    +          : nativeMin(index, length - 1);
    +      }
    +      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
    +    }
    +
    +    /**
    +     * Flattens `array` a single level deep.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to flatten.
    +     * @returns {Array} Returns the new flattened array.
    +     * @example
    +     *
    +     * _.flatten([1, [2, [3, [4]], 5]]);
    +     * // => [1, 2, [3, [4]], 5]
    +     */
    +    function flatten(array) {
    +      var length = array == null ? 0 : array.length;
    +      return length ? baseFlatten(array, 1) : [];
    +    }
    +
    +    /**
    +     * Recursively flattens `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to flatten.
    +     * @returns {Array} Returns the new flattened array.
    +     * @example
    +     *
    +     * _.flattenDeep([1, [2, [3, [4]], 5]]);
    +     * // => [1, 2, 3, 4, 5]
    +     */
    +    function flattenDeep(array) {
    +      var length = array == null ? 0 : array.length;
    +      return length ? baseFlatten(array, INFINITY) : [];
    +    }
    +
    +    /**
    +     * Recursively flatten `array` up to `depth` times.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.4.0
    +     * @category Array
    +     * @param {Array} array The array to flatten.
    +     * @param {number} [depth=1] The maximum recursion depth.
    +     * @returns {Array} Returns the new flattened array.
    +     * @example
    +     *
    +     * var array = [1, [2, [3, [4]], 5]];
    +     *
    +     * _.flattenDepth(array, 1);
    +     * // => [1, 2, [3, [4]], 5]
    +     *
    +     * _.flattenDepth(array, 2);
    +     * // => [1, 2, 3, [4], 5]
    +     */
    +    function flattenDepth(array, depth) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return [];
    +      }
    +      depth = depth === undefined$1 ? 1 : toInteger(depth);
    +      return baseFlatten(array, depth);
    +    }
    +
    +    /**
    +     * The inverse of `_.toPairs`; this method returns an object composed
    +     * from key-value `pairs`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} pairs The key-value pairs.
    +     * @returns {Object} Returns the new object.
    +     * @example
    +     *
    +     * _.fromPairs([['a', 1], ['b', 2]]);
    +     * // => { 'a': 1, 'b': 2 }
    +     */
    +    function fromPairs(pairs) {
    +      var index = -1,
    +          length = pairs == null ? 0 : pairs.length,
    +          result = {};
    +
    +      while (++index < length) {
    +        var pair = pairs[index];
    +        result[pair[0]] = pair[1];
    +      }
    +      return result;
    +    }
    +
    +    /**
    +     * Gets the first element of `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @alias first
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @returns {*} Returns the first element of `array`.
    +     * @example
    +     *
    +     * _.head([1, 2, 3]);
    +     * // => 1
    +     *
    +     * _.head([]);
    +     * // => undefined
    +     */
    +    function head(array) {
    +      return (array && array.length) ? array[0] : undefined$1;
    +    }
    +
    +    /**
    +     * Gets the index at which the first occurrence of `value` is found in `array`
    +     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons. If `fromIndex` is negative, it's used as the
    +     * offset from the end of `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {*} value The value to search for.
    +     * @param {number} [fromIndex=0] The index to search from.
    +     * @returns {number} Returns the index of the matched value, else `-1`.
    +     * @example
    +     *
    +     * _.indexOf([1, 2, 1, 2], 2);
    +     * // => 1
    +     *
    +     * // Search from the `fromIndex`.
    +     * _.indexOf([1, 2, 1, 2], 2, 2);
    +     * // => 3
    +     */
    +    function indexOf(array, value, fromIndex) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return -1;
    +      }
    +      var index = fromIndex == null ? 0 : toInteger(fromIndex);
    +      if (index < 0) {
    +        index = nativeMax(length + index, 0);
    +      }
    +      return baseIndexOf(array, value, index);
    +    }
    +
    +    /**
    +     * Gets all but the last element of `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * _.initial([1, 2, 3]);
    +     * // => [1, 2]
    +     */
    +    function initial(array) {
    +      var length = array == null ? 0 : array.length;
    +      return length ? baseSlice(array, 0, -1) : [];
    +    }
    +
    +    /**
    +     * Creates an array of unique values that are included in all given arrays
    +     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons. The order and references of result values are
    +     * determined by the first array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @returns {Array} Returns the new array of intersecting values.
    +     * @example
    +     *
    +     * _.intersection([2, 1], [2, 3]);
    +     * // => [2]
    +     */
    +    var intersection = baseRest(function(arrays) {
    +      var mapped = arrayMap(arrays, castArrayLikeObject);
    +      return (mapped.length && mapped[0] === arrays[0])
    +        ? baseIntersection(mapped)
    +        : [];
    +    });
    +
    +    /**
    +     * This method is like `_.intersection` except that it accepts `iteratee`
    +     * which is invoked for each element of each `arrays` to generate the criterion
    +     * by which they're compared. The order and references of result values are
    +     * determined by the first array. The iteratee is invoked with one argument:
    +     * (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {Array} Returns the new array of intersecting values.
    +     * @example
    +     *
    +     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
    +     * // => [2.1]
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
    +     * // => [{ 'x': 1 }]
    +     */
    +    var intersectionBy = baseRest(function(arrays) {
    +      var iteratee = last(arrays),
    +          mapped = arrayMap(arrays, castArrayLikeObject);
    +
    +      if (iteratee === last(mapped)) {
    +        iteratee = undefined$1;
    +      } else {
    +        mapped.pop();
    +      }
    +      return (mapped.length && mapped[0] === arrays[0])
    +        ? baseIntersection(mapped, getIteratee(iteratee, 2))
    +        : [];
    +    });
    +
    +    /**
    +     * This method is like `_.intersection` except that it accepts `comparator`
    +     * which is invoked to compare elements of `arrays`. The order and references
    +     * of result values are determined by the first array. The comparator is
    +     * invoked with two arguments: (arrVal, othVal).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of intersecting values.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    +     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    +     *
    +     * _.intersectionWith(objects, others, _.isEqual);
    +     * // => [{ 'x': 1, 'y': 2 }]
    +     */
    +    var intersectionWith = baseRest(function(arrays) {
    +      var comparator = last(arrays),
    +          mapped = arrayMap(arrays, castArrayLikeObject);
    +
    +      comparator = typeof comparator == 'function' ? comparator : undefined$1;
    +      if (comparator) {
    +        mapped.pop();
    +      }
    +      return (mapped.length && mapped[0] === arrays[0])
    +        ? baseIntersection(mapped, undefined$1, comparator)
    +        : [];
    +    });
    +
    +    /**
    +     * Converts all elements in `array` into a string separated by `separator`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to convert.
    +     * @param {string} [separator=','] The element separator.
    +     * @returns {string} Returns the joined string.
    +     * @example
    +     *
    +     * _.join(['a', 'b', 'c'], '~');
    +     * // => 'a~b~c'
    +     */
    +    function join(array, separator) {
    +      return array == null ? '' : nativeJoin.call(array, separator);
    +    }
    +
    +    /**
    +     * Gets the last element of `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @returns {*} Returns the last element of `array`.
    +     * @example
    +     *
    +     * _.last([1, 2, 3]);
    +     * // => 3
    +     */
    +    function last(array) {
    +      var length = array == null ? 0 : array.length;
    +      return length ? array[length - 1] : undefined$1;
    +    }
    +
    +    /**
    +     * This method is like `_.indexOf` except that it iterates over elements of
    +     * `array` from right to left.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {*} value The value to search for.
    +     * @param {number} [fromIndex=array.length-1] The index to search from.
    +     * @returns {number} Returns the index of the matched value, else `-1`.
    +     * @example
    +     *
    +     * _.lastIndexOf([1, 2, 1, 2], 2);
    +     * // => 3
    +     *
    +     * // Search from the `fromIndex`.
    +     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
    +     * // => 1
    +     */
    +    function lastIndexOf(array, value, fromIndex) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return -1;
    +      }
    +      var index = length;
    +      if (fromIndex !== undefined$1) {
    +        index = toInteger(fromIndex);
    +        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
    +      }
    +      return value === value
    +        ? strictLastIndexOf(array, value, index)
    +        : baseFindIndex(array, baseIsNaN, index, true);
    +    }
    +
    +    /**
    +     * Gets the element at index `n` of `array`. If `n` is negative, the nth
    +     * element from the end is returned.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.11.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {number} [n=0] The index of the element to return.
    +     * @returns {*} Returns the nth element of `array`.
    +     * @example
    +     *
    +     * var array = ['a', 'b', 'c', 'd'];
    +     *
    +     * _.nth(array, 1);
    +     * // => 'b'
    +     *
    +     * _.nth(array, -2);
    +     * // => 'c';
    +     */
    +    function nth(array, n) {
    +      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined$1;
    +    }
    +
    +    /**
    +     * Removes all given values from `array` using
    +     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons.
    +     *
    +     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
    +     * to remove elements from an array by predicate.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @param {...*} [values] The values to remove.
    +     * @returns {Array} Returns `array`.
    +     * @example
    +     *
    +     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
    +     *
    +     * _.pull(array, 'a', 'c');
    +     * console.log(array);
    +     * // => ['b', 'b']
    +     */
    +    var pull = baseRest(pullAll);
    +
    +    /**
    +     * This method is like `_.pull` except that it accepts an array of values to remove.
    +     *
    +     * **Note:** Unlike `_.difference`, this method mutates `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @param {Array} values The values to remove.
    +     * @returns {Array} Returns `array`.
    +     * @example
    +     *
    +     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
    +     *
    +     * _.pullAll(array, ['a', 'c']);
    +     * console.log(array);
    +     * // => ['b', 'b']
    +     */
    +    function pullAll(array, values) {
    +      return (array && array.length && values && values.length)
    +        ? basePullAll(array, values)
    +        : array;
    +    }
    +
    +    /**
    +     * This method is like `_.pullAll` except that it accepts `iteratee` which is
    +     * invoked for each element of `array` and `values` to generate the criterion
    +     * by which they're compared. The iteratee is invoked with one argument: (value).
    +     *
    +     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @param {Array} values The values to remove.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {Array} Returns `array`.
    +     * @example
    +     *
    +     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
    +     *
    +     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
    +     * console.log(array);
    +     * // => [{ 'x': 2 }]
    +     */
    +    function pullAllBy(array, values, iteratee) {
    +      return (array && array.length && values && values.length)
    +        ? basePullAll(array, values, getIteratee(iteratee, 2))
    +        : array;
    +    }
    +
    +    /**
    +     * This method is like `_.pullAll` except that it accepts `comparator` which
    +     * is invoked to compare elements of `array` to `values`. The comparator is
    +     * invoked with two arguments: (arrVal, othVal).
    +     *
    +     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.6.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @param {Array} values The values to remove.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns `array`.
    +     * @example
    +     *
    +     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
    +     *
    +     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
    +     * console.log(array);
    +     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
    +     */
    +    function pullAllWith(array, values, comparator) {
    +      return (array && array.length && values && values.length)
    +        ? basePullAll(array, values, undefined$1, comparator)
    +        : array;
    +    }
    +
    +    /**
    +     * Removes elements from `array` corresponding to `indexes` and returns an
    +     * array of removed elements.
    +     *
    +     * **Note:** Unlike `_.at`, this method mutates `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
    +     * @returns {Array} Returns the new array of removed elements.
    +     * @example
    +     *
    +     * var array = ['a', 'b', 'c', 'd'];
    +     * var pulled = _.pullAt(array, [1, 3]);
    +     *
    +     * console.log(array);
    +     * // => ['a', 'c']
    +     *
    +     * console.log(pulled);
    +     * // => ['b', 'd']
    +     */
    +    var pullAt = flatRest(function(array, indexes) {
    +      var length = array == null ? 0 : array.length,
    +          result = baseAt(array, indexes);
    +
    +      basePullAt(array, arrayMap(indexes, function(index) {
    +        return isIndex(index, length) ? +index : index;
    +      }).sort(compareAscending));
    +
    +      return result;
    +    });
    +
    +    /**
    +     * Removes all elements from `array` that `predicate` returns truthy for
    +     * and returns an array of the removed elements. The predicate is invoked
    +     * with three arguments: (value, index, array).
    +     *
    +     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
    +     * to pull elements from an array by value.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the new array of removed elements.
    +     * @example
    +     *
    +     * var array = [1, 2, 3, 4];
    +     * var evens = _.remove(array, function(n) {
    +     *   return n % 2 == 0;
    +     * });
    +     *
    +     * console.log(array);
    +     * // => [1, 3]
    +     *
    +     * console.log(evens);
    +     * // => [2, 4]
    +     */
    +    function remove(array, predicate) {
    +      var result = [];
    +      if (!(array && array.length)) {
    +        return result;
    +      }
    +      var index = -1,
    +          indexes = [],
    +          length = array.length;
    +
    +      predicate = getIteratee(predicate, 3);
    +      while (++index < length) {
    +        var value = array[index];
    +        if (predicate(value, index, array)) {
    +          result.push(value);
    +          indexes.push(index);
    +        }
    +      }
    +      basePullAt(array, indexes);
    +      return result;
    +    }
    +
    +    /**
    +     * Reverses `array` so that the first element becomes the last, the second
    +     * element becomes the second to last, and so on.
    +     *
    +     * **Note:** This method mutates `array` and is based on
    +     * [`Array#reverse`](https://mdn.io/Array/reverse).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to modify.
    +     * @returns {Array} Returns `array`.
    +     * @example
    +     *
    +     * var array = [1, 2, 3];
    +     *
    +     * _.reverse(array);
    +     * // => [3, 2, 1]
    +     *
    +     * console.log(array);
    +     * // => [3, 2, 1]
    +     */
    +    function reverse(array) {
    +      return array == null ? array : nativeReverse.call(array);
    +    }
    +
    +    /**
    +     * Creates a slice of `array` from `start` up to, but not including, `end`.
    +     *
    +     * **Note:** This method is used instead of
    +     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
    +     * returned.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to slice.
    +     * @param {number} [start=0] The start position.
    +     * @param {number} [end=array.length] The end position.
    +     * @returns {Array} Returns the slice of `array`.
    +     */
    +    function slice(array, start, end) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return [];
    +      }
    +      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
    +        start = 0;
    +        end = length;
    +      }
    +      else {
    +        start = start == null ? 0 : toInteger(start);
    +        end = end === undefined$1 ? length : toInteger(end);
    +      }
    +      return baseSlice(array, start, end);
    +    }
    +
    +    /**
    +     * Uses a binary search to determine the lowest index at which `value`
    +     * should be inserted into `array` in order to maintain its sort order.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The sorted array to inspect.
    +     * @param {*} value The value to evaluate.
    +     * @returns {number} Returns the index at which `value` should be inserted
    +     *  into `array`.
    +     * @example
    +     *
    +     * _.sortedIndex([30, 50], 40);
    +     * // => 1
    +     */
    +    function sortedIndex(array, value) {
    +      return baseSortedIndex(array, value);
    +    }
    +
    +    /**
    +     * This method is like `_.sortedIndex` except that it accepts `iteratee`
    +     * which is invoked for `value` and each element of `array` to compute their
    +     * sort ranking. The iteratee is invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The sorted array to inspect.
    +     * @param {*} value The value to evaluate.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {number} Returns the index at which `value` should be inserted
    +     *  into `array`.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 4 }, { 'x': 5 }];
    +     *
    +     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
    +     * // => 0
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
    +     * // => 0
    +     */
    +    function sortedIndexBy(array, value, iteratee) {
    +      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
    +    }
    +
    +    /**
    +     * This method is like `_.indexOf` except that it performs a binary
    +     * search on a sorted `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {*} value The value to search for.
    +     * @returns {number} Returns the index of the matched value, else `-1`.
    +     * @example
    +     *
    +     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
    +     * // => 1
    +     */
    +    function sortedIndexOf(array, value) {
    +      var length = array == null ? 0 : array.length;
    +      if (length) {
    +        var index = baseSortedIndex(array, value);
    +        if (index < length && eq(array[index], value)) {
    +          return index;
    +        }
    +      }
    +      return -1;
    +    }
    +
    +    /**
    +     * This method is like `_.sortedIndex` except that it returns the highest
    +     * index at which `value` should be inserted into `array` in order to
    +     * maintain its sort order.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The sorted array to inspect.
    +     * @param {*} value The value to evaluate.
    +     * @returns {number} Returns the index at which `value` should be inserted
    +     *  into `array`.
    +     * @example
    +     *
    +     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
    +     * // => 4
    +     */
    +    function sortedLastIndex(array, value) {
    +      return baseSortedIndex(array, value, true);
    +    }
    +
    +    /**
    +     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
    +     * which is invoked for `value` and each element of `array` to compute their
    +     * sort ranking. The iteratee is invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The sorted array to inspect.
    +     * @param {*} value The value to evaluate.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {number} Returns the index at which `value` should be inserted
    +     *  into `array`.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 4 }, { 'x': 5 }];
    +     *
    +     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
    +     * // => 1
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
    +     * // => 1
    +     */
    +    function sortedLastIndexBy(array, value, iteratee) {
    +      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
    +    }
    +
    +    /**
    +     * This method is like `_.lastIndexOf` except that it performs a binary
    +     * search on a sorted `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {*} value The value to search for.
    +     * @returns {number} Returns the index of the matched value, else `-1`.
    +     * @example
    +     *
    +     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
    +     * // => 3
    +     */
    +    function sortedLastIndexOf(array, value) {
    +      var length = array == null ? 0 : array.length;
    +      if (length) {
    +        var index = baseSortedIndex(array, value, true) - 1;
    +        if (eq(array[index], value)) {
    +          return index;
    +        }
    +      }
    +      return -1;
    +    }
    +
    +    /**
    +     * This method is like `_.uniq` except that it's designed and optimized
    +     * for sorted arrays.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @returns {Array} Returns the new duplicate free array.
    +     * @example
    +     *
    +     * _.sortedUniq([1, 1, 2]);
    +     * // => [1, 2]
    +     */
    +    function sortedUniq(array) {
    +      return (array && array.length)
    +        ? baseSortedUniq(array)
    +        : [];
    +    }
    +
    +    /**
    +     * This method is like `_.uniqBy` except that it's designed and optimized
    +     * for sorted arrays.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [iteratee] The iteratee invoked per element.
    +     * @returns {Array} Returns the new duplicate free array.
    +     * @example
    +     *
    +     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
    +     * // => [1.1, 2.3]
    +     */
    +    function sortedUniqBy(array, iteratee) {
    +      return (array && array.length)
    +        ? baseSortedUniq(array, getIteratee(iteratee, 2))
    +        : [];
    +    }
    +
    +    /**
    +     * Gets all but the first element of `array`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * _.tail([1, 2, 3]);
    +     * // => [2, 3]
    +     */
    +    function tail(array) {
    +      var length = array == null ? 0 : array.length;
    +      return length ? baseSlice(array, 1, length) : [];
    +    }
    +
    +    /**
    +     * Creates a slice of `array` with `n` elements taken from the beginning.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {number} [n=1] The number of elements to take.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * _.take([1, 2, 3]);
    +     * // => [1]
    +     *
    +     * _.take([1, 2, 3], 2);
    +     * // => [1, 2]
    +     *
    +     * _.take([1, 2, 3], 5);
    +     * // => [1, 2, 3]
    +     *
    +     * _.take([1, 2, 3], 0);
    +     * // => []
    +     */
    +    function take(array, n, guard) {
    +      if (!(array && array.length)) {
    +        return [];
    +      }
    +      n = (guard || n === undefined$1) ? 1 : toInteger(n);
    +      return baseSlice(array, 0, n < 0 ? 0 : n);
    +    }
    +
    +    /**
    +     * Creates a slice of `array` with `n` elements taken from the end.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {number} [n=1] The number of elements to take.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * _.takeRight([1, 2, 3]);
    +     * // => [3]
    +     *
    +     * _.takeRight([1, 2, 3], 2);
    +     * // => [2, 3]
    +     *
    +     * _.takeRight([1, 2, 3], 5);
    +     * // => [1, 2, 3]
    +     *
    +     * _.takeRight([1, 2, 3], 0);
    +     * // => []
    +     */
    +    function takeRight(array, n, guard) {
    +      var length = array == null ? 0 : array.length;
    +      if (!length) {
    +        return [];
    +      }
    +      n = (guard || n === undefined$1) ? 1 : toInteger(n);
    +      n = length - n;
    +      return baseSlice(array, n < 0 ? 0 : n, length);
    +    }
    +
    +    /**
    +     * Creates a slice of `array` with elements taken from the end. Elements are
    +     * taken until `predicate` returns falsey. The predicate is invoked with
    +     * three arguments: (value, index, array).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'active': true },
    +     *   { 'user': 'fred',    'active': false },
    +     *   { 'user': 'pebbles', 'active': false }
    +     * ];
    +     *
    +     * _.takeRightWhile(users, function(o) { return !o.active; });
    +     * // => objects for ['fred', 'pebbles']
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
    +     * // => objects for ['pebbles']
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.takeRightWhile(users, ['active', false]);
    +     * // => objects for ['fred', 'pebbles']
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.takeRightWhile(users, 'active');
    +     * // => []
    +     */
    +    function takeRightWhile(array, predicate) {
    +      return (array && array.length)
    +        ? baseWhile(array, getIteratee(predicate, 3), false, true)
    +        : [];
    +    }
    +
    +    /**
    +     * Creates a slice of `array` with elements taken from the beginning. Elements
    +     * are taken until `predicate` returns falsey. The predicate is invoked with
    +     * three arguments: (value, index, array).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Array
    +     * @param {Array} array The array to query.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the slice of `array`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'active': false },
    +     *   { 'user': 'fred',    'active': false },
    +     *   { 'user': 'pebbles', 'active': true }
    +     * ];
    +     *
    +     * _.takeWhile(users, function(o) { return !o.active; });
    +     * // => objects for ['barney', 'fred']
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.takeWhile(users, { 'user': 'barney', 'active': false });
    +     * // => objects for ['barney']
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.takeWhile(users, ['active', false]);
    +     * // => objects for ['barney', 'fred']
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.takeWhile(users, 'active');
    +     * // => []
    +     */
    +    function takeWhile(array, predicate) {
    +      return (array && array.length)
    +        ? baseWhile(array, getIteratee(predicate, 3))
    +        : [];
    +    }
    +
    +    /**
    +     * Creates an array of unique values, in order, from all given arrays using
    +     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @returns {Array} Returns the new array of combined values.
    +     * @example
    +     *
    +     * _.union([2], [1, 2]);
    +     * // => [2, 1]
    +     */
    +    var union = baseRest(function(arrays) {
    +      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
    +    });
    +
    +    /**
    +     * This method is like `_.union` except that it accepts `iteratee` which is
    +     * invoked for each element of each `arrays` to generate the criterion by
    +     * which uniqueness is computed. Result values are chosen from the first
    +     * array in which the value occurs. The iteratee is invoked with one argument:
    +     * (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {Array} Returns the new array of combined values.
    +     * @example
    +     *
    +     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
    +     * // => [2.1, 1.2]
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
    +     * // => [{ 'x': 1 }, { 'x': 2 }]
    +     */
    +    var unionBy = baseRest(function(arrays) {
    +      var iteratee = last(arrays);
    +      if (isArrayLikeObject(iteratee)) {
    +        iteratee = undefined$1;
    +      }
    +      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
    +    });
    +
    +    /**
    +     * This method is like `_.union` except that it accepts `comparator` which
    +     * is invoked to compare elements of `arrays`. Result values are chosen from
    +     * the first array in which the value occurs. The comparator is invoked
    +     * with two arguments: (arrVal, othVal).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of combined values.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    +     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    +     *
    +     * _.unionWith(objects, others, _.isEqual);
    +     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
    +     */
    +    var unionWith = baseRest(function(arrays) {
    +      var comparator = last(arrays);
    +      comparator = typeof comparator == 'function' ? comparator : undefined$1;
    +      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined$1, comparator);
    +    });
    +
    +    /**
    +     * Creates a duplicate-free version of an array, using
    +     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons, in which only the first occurrence of each element
    +     * is kept. The order of result values is determined by the order they occur
    +     * in the array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @returns {Array} Returns the new duplicate free array.
    +     * @example
    +     *
    +     * _.uniq([2, 1, 2]);
    +     * // => [2, 1]
    +     */
    +    function uniq(array) {
    +      return (array && array.length) ? baseUniq(array) : [];
    +    }
    +
    +    /**
    +     * This method is like `_.uniq` except that it accepts `iteratee` which is
    +     * invoked for each element in `array` to generate the criterion by which
    +     * uniqueness is computed. The order of result values is determined by the
    +     * order they occur in the array. The iteratee is invoked with one argument:
    +     * (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {Array} Returns the new duplicate free array.
    +     * @example
    +     *
    +     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
    +     * // => [2.1, 1.2]
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
    +     * // => [{ 'x': 1 }, { 'x': 2 }]
    +     */
    +    function uniqBy(array, iteratee) {
    +      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
    +    }
    +
    +    /**
    +     * This method is like `_.uniq` except that it accepts `comparator` which
    +     * is invoked to compare elements of `array`. The order of result values is
    +     * determined by the order they occur in the array.The comparator is invoked
    +     * with two arguments: (arrVal, othVal).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new duplicate free array.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
    +     *
    +     * _.uniqWith(objects, _.isEqual);
    +     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
    +     */
    +    function uniqWith(array, comparator) {
    +      comparator = typeof comparator == 'function' ? comparator : undefined$1;
    +      return (array && array.length) ? baseUniq(array, undefined$1, comparator) : [];
    +    }
    +
    +    /**
    +     * This method is like `_.zip` except that it accepts an array of grouped
    +     * elements and creates an array regrouping the elements to their pre-zip
    +     * configuration.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 1.2.0
    +     * @category Array
    +     * @param {Array} array The array of grouped elements to process.
    +     * @returns {Array} Returns the new array of regrouped elements.
    +     * @example
    +     *
    +     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
    +     * // => [['a', 1, true], ['b', 2, false]]
    +     *
    +     * _.unzip(zipped);
    +     * // => [['a', 'b'], [1, 2], [true, false]]
    +     */
    +    function unzip(array) {
    +      if (!(array && array.length)) {
    +        return [];
    +      }
    +      var length = 0;
    +      array = arrayFilter(array, function(group) {
    +        if (isArrayLikeObject(group)) {
    +          length = nativeMax(group.length, length);
    +          return true;
    +        }
    +      });
    +      return baseTimes(length, function(index) {
    +        return arrayMap(array, baseProperty(index));
    +      });
    +    }
    +
    +    /**
    +     * This method is like `_.unzip` except that it accepts `iteratee` to specify
    +     * how regrouped values should be combined. The iteratee is invoked with the
    +     * elements of each group: (...group).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.8.0
    +     * @category Array
    +     * @param {Array} array The array of grouped elements to process.
    +     * @param {Function} [iteratee=_.identity] The function to combine
    +     *  regrouped values.
    +     * @returns {Array} Returns the new array of regrouped elements.
    +     * @example
    +     *
    +     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
    +     * // => [[1, 10, 100], [2, 20, 200]]
    +     *
    +     * _.unzipWith(zipped, _.add);
    +     * // => [3, 30, 300]
    +     */
    +    function unzipWith(array, iteratee) {
    +      if (!(array && array.length)) {
    +        return [];
    +      }
    +      var result = unzip(array);
    +      if (iteratee == null) {
    +        return result;
    +      }
    +      return arrayMap(result, function(group) {
    +        return apply(iteratee, undefined$1, group);
    +      });
    +    }
    +
    +    /**
    +     * Creates an array excluding all given values using
    +     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * for equality comparisons.
    +     *
    +     * **Note:** Unlike `_.pull`, this method returns a new array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {Array} array The array to inspect.
    +     * @param {...*} [values] The values to exclude.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @see _.difference, _.xor
    +     * @example
    +     *
    +     * _.without([2, 1, 2, 3], 1, 2);
    +     * // => [3]
    +     */
    +    var without = baseRest(function(array, values) {
    +      return isArrayLikeObject(array)
    +        ? baseDifference(array, values)
    +        : [];
    +    });
    +
    +    /**
    +     * Creates an array of unique values that is the
    +     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
    +     * of the given arrays. The order of result values is determined by the order
    +     * they occur in the arrays.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.4.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @see _.difference, _.without
    +     * @example
    +     *
    +     * _.xor([2, 1], [2, 3]);
    +     * // => [1, 3]
    +     */
    +    var xor = baseRest(function(arrays) {
    +      return baseXor(arrayFilter(arrays, isArrayLikeObject));
    +    });
    +
    +    /**
    +     * This method is like `_.xor` except that it accepts `iteratee` which is
    +     * invoked for each element of each `arrays` to generate the criterion by
    +     * which by which they're compared. The order of result values is determined
    +     * by the order they occur in the arrays. The iteratee is invoked with one
    +     * argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @example
    +     *
    +     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
    +     * // => [1.2, 3.4]
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
    +     * // => [{ 'x': 2 }]
    +     */
    +    var xorBy = baseRest(function(arrays) {
    +      var iteratee = last(arrays);
    +      if (isArrayLikeObject(iteratee)) {
    +        iteratee = undefined$1;
    +      }
    +      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
    +    });
    +
    +    /**
    +     * This method is like `_.xor` except that it accepts `comparator` which is
    +     * invoked to compare elements of `arrays`. The order of result values is
    +     * determined by the order they occur in the arrays. The comparator is invoked
    +     * with two arguments: (arrVal, othVal).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to inspect.
    +     * @param {Function} [comparator] The comparator invoked per element.
    +     * @returns {Array} Returns the new array of filtered values.
    +     * @example
    +     *
    +     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    +     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    +     *
    +     * _.xorWith(objects, others, _.isEqual);
    +     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
    +     */
    +    var xorWith = baseRest(function(arrays) {
    +      var comparator = last(arrays);
    +      comparator = typeof comparator == 'function' ? comparator : undefined$1;
    +      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined$1, comparator);
    +    });
    +
    +    /**
    +     * Creates an array of grouped elements, the first of which contains the
    +     * first elements of the given arrays, the second of which contains the
    +     * second elements of the given arrays, and so on.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to process.
    +     * @returns {Array} Returns the new array of grouped elements.
    +     * @example
    +     *
    +     * _.zip(['a', 'b'], [1, 2], [true, false]);
    +     * // => [['a', 1, true], ['b', 2, false]]
    +     */
    +    var zip = baseRest(unzip);
    +
    +    /**
    +     * This method is like `_.fromPairs` except that it accepts two arrays,
    +     * one of property identifiers and one of corresponding values.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.4.0
    +     * @category Array
    +     * @param {Array} [props=[]] The property identifiers.
    +     * @param {Array} [values=[]] The property values.
    +     * @returns {Object} Returns the new object.
    +     * @example
    +     *
    +     * _.zipObject(['a', 'b'], [1, 2]);
    +     * // => { 'a': 1, 'b': 2 }
    +     */
    +    function zipObject(props, values) {
    +      return baseZipObject(props || [], values || [], assignValue);
    +    }
    +
    +    /**
    +     * This method is like `_.zipObject` except that it supports property paths.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.1.0
    +     * @category Array
    +     * @param {Array} [props=[]] The property identifiers.
    +     * @param {Array} [values=[]] The property values.
    +     * @returns {Object} Returns the new object.
    +     * @example
    +     *
    +     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
    +     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
    +     */
    +    function zipObjectDeep(props, values) {
    +      return baseZipObject(props || [], values || [], baseSet);
    +    }
    +
    +    /**
    +     * This method is like `_.zip` except that it accepts `iteratee` to specify
    +     * how grouped values should be combined. The iteratee is invoked with the
    +     * elements of each group: (...group).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.8.0
    +     * @category Array
    +     * @param {...Array} [arrays] The arrays to process.
    +     * @param {Function} [iteratee=_.identity] The function to combine
    +     *  grouped values.
    +     * @returns {Array} Returns the new array of grouped elements.
    +     * @example
    +     *
    +     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
    +     *   return a + b + c;
    +     * });
    +     * // => [111, 222]
    +     */
    +    var zipWith = baseRest(function(arrays) {
    +      var length = arrays.length,
    +          iteratee = length > 1 ? arrays[length - 1] : undefined$1;
    +
    +      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined$1;
    +      return unzipWith(arrays, iteratee);
    +    });
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
    +     * chain sequences enabled. The result of such sequences must be unwrapped
    +     * with `_#value`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 1.3.0
    +     * @category Seq
    +     * @param {*} value The value to wrap.
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'age': 36 },
    +     *   { 'user': 'fred',    'age': 40 },
    +     *   { 'user': 'pebbles', 'age': 1 }
    +     * ];
    +     *
    +     * var youngest = _
    +     *   .chain(users)
    +     *   .sortBy('age')
    +     *   .map(function(o) {
    +     *     return o.user + ' is ' + o.age;
    +     *   })
    +     *   .head()
    +     *   .value();
    +     * // => 'pebbles is 1'
    +     */
    +    function chain(value) {
    +      var result = lodash(value);
    +      result.__chain__ = true;
    +      return result;
    +    }
    +
    +    /**
    +     * This method invokes `interceptor` and returns `value`. The interceptor
    +     * is invoked with one argument; (value). The purpose of this method is to
    +     * "tap into" a method chain sequence in order to modify intermediate results.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Seq
    +     * @param {*} value The value to provide to `interceptor`.
    +     * @param {Function} interceptor The function to invoke.
    +     * @returns {*} Returns `value`.
    +     * @example
    +     *
    +     * _([1, 2, 3])
    +     *  .tap(function(array) {
    +     *    // Mutate input array.
    +     *    array.pop();
    +     *  })
    +     *  .reverse()
    +     *  .value();
    +     * // => [2, 1]
    +     */
    +    function tap(value, interceptor) {
    +      interceptor(value);
    +      return value;
    +    }
    +
    +    /**
    +     * This method is like `_.tap` except that it returns the result of `interceptor`.
    +     * The purpose of this method is to "pass thru" values replacing intermediate
    +     * results in a method chain sequence.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Seq
    +     * @param {*} value The value to provide to `interceptor`.
    +     * @param {Function} interceptor The function to invoke.
    +     * @returns {*} Returns the result of `interceptor`.
    +     * @example
    +     *
    +     * _('  abc  ')
    +     *  .chain()
    +     *  .trim()
    +     *  .thru(function(value) {
    +     *    return [value];
    +     *  })
    +     *  .value();
    +     * // => ['abc']
    +     */
    +    function thru(value, interceptor) {
    +      return interceptor(value);
    +    }
    +
    +    /**
    +     * This method is the wrapper version of `_.at`.
    +     *
    +     * @name at
    +     * @memberOf _
    +     * @since 1.0.0
    +     * @category Seq
    +     * @param {...(string|string[])} [paths] The property paths to pick.
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
    +     *
    +     * _(object).at(['a[0].b.c', 'a[1]']).value();
    +     * // => [3, 4]
    +     */
    +    var wrapperAt = flatRest(function(paths) {
    +      var length = paths.length,
    +          start = length ? paths[0] : 0,
    +          value = this.__wrapped__,
    +          interceptor = function(object) { return baseAt(object, paths); };
    +
    +      if (length > 1 || this.__actions__.length ||
    +          !(value instanceof LazyWrapper) || !isIndex(start)) {
    +        return this.thru(interceptor);
    +      }
    +      value = value.slice(start, +start + (length ? 1 : 0));
    +      value.__actions__.push({
    +        'func': thru,
    +        'args': [interceptor],
    +        'thisArg': undefined$1
    +      });
    +      return new LodashWrapper(value, this.__chain__).thru(function(array) {
    +        if (length && !array.length) {
    +          array.push(undefined$1);
    +        }
    +        return array;
    +      });
    +    });
    +
    +    /**
    +     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
    +     *
    +     * @name chain
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Seq
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney', 'age': 36 },
    +     *   { 'user': 'fred',   'age': 40 }
    +     * ];
    +     *
    +     * // A sequence without explicit chaining.
    +     * _(users).head();
    +     * // => { 'user': 'barney', 'age': 36 }
    +     *
    +     * // A sequence with explicit chaining.
    +     * _(users)
    +     *   .chain()
    +     *   .head()
    +     *   .pick('user')
    +     *   .value();
    +     * // => { 'user': 'barney' }
    +     */
    +    function wrapperChain() {
    +      return chain(this);
    +    }
    +
    +    /**
    +     * Executes the chain sequence and returns the wrapped result.
    +     *
    +     * @name commit
    +     * @memberOf _
    +     * @since 3.2.0
    +     * @category Seq
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * var array = [1, 2];
    +     * var wrapped = _(array).push(3);
    +     *
    +     * console.log(array);
    +     * // => [1, 2]
    +     *
    +     * wrapped = wrapped.commit();
    +     * console.log(array);
    +     * // => [1, 2, 3]
    +     *
    +     * wrapped.last();
    +     * // => 3
    +     *
    +     * console.log(array);
    +     * // => [1, 2, 3]
    +     */
    +    function wrapperCommit() {
    +      return new LodashWrapper(this.value(), this.__chain__);
    +    }
    +
    +    /**
    +     * Gets the next value on a wrapped object following the
    +     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
    +     *
    +     * @name next
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Seq
    +     * @returns {Object} Returns the next iterator value.
    +     * @example
    +     *
    +     * var wrapped = _([1, 2]);
    +     *
    +     * wrapped.next();
    +     * // => { 'done': false, 'value': 1 }
    +     *
    +     * wrapped.next();
    +     * // => { 'done': false, 'value': 2 }
    +     *
    +     * wrapped.next();
    +     * // => { 'done': true, 'value': undefined }
    +     */
    +    function wrapperNext() {
    +      if (this.__values__ === undefined$1) {
    +        this.__values__ = toArray(this.value());
    +      }
    +      var done = this.__index__ >= this.__values__.length,
    +          value = done ? undefined$1 : this.__values__[this.__index__++];
    +
    +      return { 'done': done, 'value': value };
    +    }
    +
    +    /**
    +     * Enables the wrapper to be iterable.
    +     *
    +     * @name Symbol.iterator
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Seq
    +     * @returns {Object} Returns the wrapper object.
    +     * @example
    +     *
    +     * var wrapped = _([1, 2]);
    +     *
    +     * wrapped[Symbol.iterator]() === wrapped;
    +     * // => true
    +     *
    +     * Array.from(wrapped);
    +     * // => [1, 2]
    +     */
    +    function wrapperToIterator() {
    +      return this;
    +    }
    +
    +    /**
    +     * Creates a clone of the chain sequence planting `value` as the wrapped value.
    +     *
    +     * @name plant
    +     * @memberOf _
    +     * @since 3.2.0
    +     * @category Seq
    +     * @param {*} value The value to plant.
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * function square(n) {
    +     *   return n * n;
    +     * }
    +     *
    +     * var wrapped = _([1, 2]).map(square);
    +     * var other = wrapped.plant([3, 4]);
    +     *
    +     * other.value();
    +     * // => [9, 16]
    +     *
    +     * wrapped.value();
    +     * // => [1, 4]
    +     */
    +    function wrapperPlant(value) {
    +      var result,
    +          parent = this;
    +
    +      while (parent instanceof baseLodash) {
    +        var clone = wrapperClone(parent);
    +        clone.__index__ = 0;
    +        clone.__values__ = undefined$1;
    +        if (result) {
    +          previous.__wrapped__ = clone;
    +        } else {
    +          result = clone;
    +        }
    +        var previous = clone;
    +        parent = parent.__wrapped__;
    +      }
    +      previous.__wrapped__ = value;
    +      return result;
    +    }
    +
    +    /**
    +     * This method is the wrapper version of `_.reverse`.
    +     *
    +     * **Note:** This method mutates the wrapped array.
    +     *
    +     * @name reverse
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Seq
    +     * @returns {Object} Returns the new `lodash` wrapper instance.
    +     * @example
    +     *
    +     * var array = [1, 2, 3];
    +     *
    +     * _(array).reverse().value()
    +     * // => [3, 2, 1]
    +     *
    +     * console.log(array);
    +     * // => [3, 2, 1]
    +     */
    +    function wrapperReverse() {
    +      var value = this.__wrapped__;
    +      if (value instanceof LazyWrapper) {
    +        var wrapped = value;
    +        if (this.__actions__.length) {
    +          wrapped = new LazyWrapper(this);
    +        }
    +        wrapped = wrapped.reverse();
    +        wrapped.__actions__.push({
    +          'func': thru,
    +          'args': [reverse],
    +          'thisArg': undefined$1
    +        });
    +        return new LodashWrapper(wrapped, this.__chain__);
    +      }
    +      return this.thru(reverse);
    +    }
    +
    +    /**
    +     * Executes the chain sequence to resolve the unwrapped value.
    +     *
    +     * @name value
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @alias toJSON, valueOf
    +     * @category Seq
    +     * @returns {*} Returns the resolved unwrapped value.
    +     * @example
    +     *
    +     * _([1, 2, 3]).value();
    +     * // => [1, 2, 3]
    +     */
    +    function wrapperValue() {
    +      return baseWrapperValue(this.__wrapped__, this.__actions__);
    +    }
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Creates an object composed of keys generated from the results of running
    +     * each element of `collection` thru `iteratee`. The corresponding value of
    +     * each key is the number of times the key was returned by `iteratee`. The
    +     * iteratee is invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.5.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
    +     * @returns {Object} Returns the composed aggregate object.
    +     * @example
    +     *
    +     * _.countBy([6.1, 4.2, 6.3], Math.floor);
    +     * // => { '4': 1, '6': 2 }
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.countBy(['one', 'two', 'three'], 'length');
    +     * // => { '3': 2, '5': 1 }
    +     */
    +    var countBy = createAggregator(function(result, value, key) {
    +      if (hasOwnProperty.call(result, key)) {
    +        ++result[key];
    +      } else {
    +        baseAssignValue(result, key, 1);
    +      }
    +    });
    +
    +    /**
    +     * Checks if `predicate` returns truthy for **all** elements of `collection`.
    +     * Iteration is stopped once `predicate` returns falsey. The predicate is
    +     * invoked with three arguments: (value, index|key, collection).
    +     *
    +     * **Note:** This method returns `true` for
    +     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
    +     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
    +     * elements of empty collections.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {boolean} Returns `true` if all elements pass the predicate check,
    +     *  else `false`.
    +     * @example
    +     *
    +     * _.every([true, 1, null, 'yes'], Boolean);
    +     * // => false
    +     *
    +     * var users = [
    +     *   { 'user': 'barney', 'age': 36, 'active': false },
    +     *   { 'user': 'fred',   'age': 40, 'active': false }
    +     * ];
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.every(users, { 'user': 'barney', 'active': false });
    +     * // => false
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.every(users, ['active', false]);
    +     * // => true
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.every(users, 'active');
    +     * // => false
    +     */
    +    function every(collection, predicate, guard) {
    +      var func = isArray(collection) ? arrayEvery : baseEvery;
    +      if (guard && isIterateeCall(collection, predicate, guard)) {
    +        predicate = undefined$1;
    +      }
    +      return func(collection, getIteratee(predicate, 3));
    +    }
    +
    +    /**
    +     * Iterates over elements of `collection`, returning an array of all elements
    +     * `predicate` returns truthy for. The predicate is invoked with three
    +     * arguments: (value, index|key, collection).
    +     *
    +     * **Note:** Unlike `_.remove`, this method returns a new array.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the new filtered array.
    +     * @see _.reject
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney', 'age': 36, 'active': true },
    +     *   { 'user': 'fred',   'age': 40, 'active': false }
    +     * ];
    +     *
    +     * _.filter(users, function(o) { return !o.active; });
    +     * // => objects for ['fred']
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.filter(users, { 'age': 36, 'active': true });
    +     * // => objects for ['barney']
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.filter(users, ['active', false]);
    +     * // => objects for ['fred']
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.filter(users, 'active');
    +     * // => objects for ['barney']
    +     *
    +     * // Combining several predicates using `_.overEvery` or `_.overSome`.
    +     * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
    +     * // => objects for ['fred', 'barney']
    +     */
    +    function filter(collection, predicate) {
    +      var func = isArray(collection) ? arrayFilter : baseFilter;
    +      return func(collection, getIteratee(predicate, 3));
    +    }
    +
    +    /**
    +     * Iterates over elements of `collection`, returning the first element
    +     * `predicate` returns truthy for. The predicate is invoked with three
    +     * arguments: (value, index|key, collection).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to inspect.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @param {number} [fromIndex=0] The index to search from.
    +     * @returns {*} Returns the matched element, else `undefined`.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'age': 36, 'active': true },
    +     *   { 'user': 'fred',    'age': 40, 'active': false },
    +     *   { 'user': 'pebbles', 'age': 1,  'active': true }
    +     * ];
    +     *
    +     * _.find(users, function(o) { return o.age < 40; });
    +     * // => object for 'barney'
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.find(users, { 'age': 1, 'active': true });
    +     * // => object for 'pebbles'
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.find(users, ['active', false]);
    +     * // => object for 'fred'
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.find(users, 'active');
    +     * // => object for 'barney'
    +     */
    +    var find = createFind(findIndex);
    +
    +    /**
    +     * This method is like `_.find` except that it iterates over elements of
    +     * `collection` from right to left.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to inspect.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @param {number} [fromIndex=collection.length-1] The index to search from.
    +     * @returns {*} Returns the matched element, else `undefined`.
    +     * @example
    +     *
    +     * _.findLast([1, 2, 3, 4], function(n) {
    +     *   return n % 2 == 1;
    +     * });
    +     * // => 3
    +     */
    +    var findLast = createFind(findLastIndex);
    +
    +    /**
    +     * Creates a flattened array of values by running each element in `collection`
    +     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
    +     * with three arguments: (value, index|key, collection).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the new flattened array.
    +     * @example
    +     *
    +     * function duplicate(n) {
    +     *   return [n, n];
    +     * }
    +     *
    +     * _.flatMap([1, 2], duplicate);
    +     * // => [1, 1, 2, 2]
    +     */
    +    function flatMap(collection, iteratee) {
    +      return baseFlatten(map(collection, iteratee), 1);
    +    }
    +
    +    /**
    +     * This method is like `_.flatMap` except that it recursively flattens the
    +     * mapped results.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.7.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the new flattened array.
    +     * @example
    +     *
    +     * function duplicate(n) {
    +     *   return [[[n, n]]];
    +     * }
    +     *
    +     * _.flatMapDeep([1, 2], duplicate);
    +     * // => [1, 1, 2, 2]
    +     */
    +    function flatMapDeep(collection, iteratee) {
    +      return baseFlatten(map(collection, iteratee), INFINITY);
    +    }
    +
    +    /**
    +     * This method is like `_.flatMap` except that it recursively flattens the
    +     * mapped results up to `depth` times.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.7.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @param {number} [depth=1] The maximum recursion depth.
    +     * @returns {Array} Returns the new flattened array.
    +     * @example
    +     *
    +     * function duplicate(n) {
    +     *   return [[[n, n]]];
    +     * }
    +     *
    +     * _.flatMapDepth([1, 2], duplicate, 2);
    +     * // => [[1, 1], [2, 2]]
    +     */
    +    function flatMapDepth(collection, iteratee, depth) {
    +      depth = depth === undefined$1 ? 1 : toInteger(depth);
    +      return baseFlatten(map(collection, iteratee), depth);
    +    }
    +
    +    /**
    +     * Iterates over elements of `collection` and invokes `iteratee` for each element.
    +     * The iteratee is invoked with three arguments: (value, index|key, collection).
    +     * Iteratee functions may exit iteration early by explicitly returning `false`.
    +     *
    +     * **Note:** As with other "Collections" methods, objects with a "length"
    +     * property are iterated like arrays. To avoid this behavior use `_.forIn`
    +     * or `_.forOwn` for object iteration.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @alias each
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @returns {Array|Object} Returns `collection`.
    +     * @see _.forEachRight
    +     * @example
    +     *
    +     * _.forEach([1, 2], function(value) {
    +     *   console.log(value);
    +     * });
    +     * // => Logs `1` then `2`.
    +     *
    +     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
    +     *   console.log(key);
    +     * });
    +     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
    +     */
    +    function forEach(collection, iteratee) {
    +      var func = isArray(collection) ? arrayEach : baseEach;
    +      return func(collection, getIteratee(iteratee, 3));
    +    }
    +
    +    /**
    +     * This method is like `_.forEach` except that it iterates over elements of
    +     * `collection` from right to left.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @alias eachRight
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @returns {Array|Object} Returns `collection`.
    +     * @see _.forEach
    +     * @example
    +     *
    +     * _.forEachRight([1, 2], function(value) {
    +     *   console.log(value);
    +     * });
    +     * // => Logs `2` then `1`.
    +     */
    +    function forEachRight(collection, iteratee) {
    +      var func = isArray(collection) ? arrayEachRight : baseEachRight;
    +      return func(collection, getIteratee(iteratee, 3));
    +    }
    +
    +    /**
    +     * Creates an object composed of keys generated from the results of running
    +     * each element of `collection` thru `iteratee`. The order of grouped values
    +     * is determined by the order they occur in `collection`. The corresponding
    +     * value of each key is an array of elements responsible for generating the
    +     * key. The iteratee is invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
    +     * @returns {Object} Returns the composed aggregate object.
    +     * @example
    +     *
    +     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
    +     * // => { '4': [4.2], '6': [6.1, 6.3] }
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.groupBy(['one', 'two', 'three'], 'length');
    +     * // => { '3': ['one', 'two'], '5': ['three'] }
    +     */
    +    var groupBy = createAggregator(function(result, value, key) {
    +      if (hasOwnProperty.call(result, key)) {
    +        result[key].push(value);
    +      } else {
    +        baseAssignValue(result, key, [value]);
    +      }
    +    });
    +
    +    /**
    +     * Checks if `value` is in `collection`. If `collection` is a string, it's
    +     * checked for a substring of `value`, otherwise
    +     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
    +     * is used for equality comparisons. If `fromIndex` is negative, it's used as
    +     * the offset from the end of `collection`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object|string} collection The collection to inspect.
    +     * @param {*} value The value to search for.
    +     * @param {number} [fromIndex=0] The index to search from.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
    +     * @returns {boolean} Returns `true` if `value` is found, else `false`.
    +     * @example
    +     *
    +     * _.includes([1, 2, 3], 1);
    +     * // => true
    +     *
    +     * _.includes([1, 2, 3], 1, 2);
    +     * // => false
    +     *
    +     * _.includes({ 'a': 1, 'b': 2 }, 1);
    +     * // => true
    +     *
    +     * _.includes('abcd', 'bc');
    +     * // => true
    +     */
    +    function includes(collection, value, fromIndex, guard) {
    +      collection = isArrayLike(collection) ? collection : values(collection);
    +      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
    +
    +      var length = collection.length;
    +      if (fromIndex < 0) {
    +        fromIndex = nativeMax(length + fromIndex, 0);
    +      }
    +      return isString(collection)
    +        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
    +        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
    +    }
    +
    +    /**
    +     * Invokes the method at `path` of each element in `collection`, returning
    +     * an array of the results of each invoked method. Any additional arguments
    +     * are provided to each invoked method. If `path` is a function, it's invoked
    +     * for, and `this` bound to, each element in `collection`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Array|Function|string} path The path of the method to invoke or
    +     *  the function invoked per iteration.
    +     * @param {...*} [args] The arguments to invoke each method with.
    +     * @returns {Array} Returns the array of results.
    +     * @example
    +     *
    +     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
    +     * // => [[1, 5, 7], [1, 2, 3]]
    +     *
    +     * _.invokeMap([123, 456], String.prototype.split, '');
    +     * // => [['1', '2', '3'], ['4', '5', '6']]
    +     */
    +    var invokeMap = baseRest(function(collection, path, args) {
    +      var index = -1,
    +          isFunc = typeof path == 'function',
    +          result = isArrayLike(collection) ? Array(collection.length) : [];
    +
    +      baseEach(collection, function(value) {
    +        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
    +      });
    +      return result;
    +    });
    +
    +    /**
    +     * Creates an object composed of keys generated from the results of running
    +     * each element of `collection` thru `iteratee`. The corresponding value of
    +     * each key is the last element responsible for generating the key. The
    +     * iteratee is invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
    +     * @returns {Object} Returns the composed aggregate object.
    +     * @example
    +     *
    +     * var array = [
    +     *   { 'dir': 'left', 'code': 97 },
    +     *   { 'dir': 'right', 'code': 100 }
    +     * ];
    +     *
    +     * _.keyBy(array, function(o) {
    +     *   return String.fromCharCode(o.code);
    +     * });
    +     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
    +     *
    +     * _.keyBy(array, 'dir');
    +     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
    +     */
    +    var keyBy = createAggregator(function(result, value, key) {
    +      baseAssignValue(result, key, value);
    +    });
    +
    +    /**
    +     * Creates an array of values by running each element in `collection` thru
    +     * `iteratee`. The iteratee is invoked with three arguments:
    +     * (value, index|key, collection).
    +     *
    +     * Many lodash methods are guarded to work as iteratees for methods like
    +     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
    +     *
    +     * The guarded methods are:
    +     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
    +     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
    +     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
    +     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the new mapped array.
    +     * @example
    +     *
    +     * function square(n) {
    +     *   return n * n;
    +     * }
    +     *
    +     * _.map([4, 8], square);
    +     * // => [16, 64]
    +     *
    +     * _.map({ 'a': 4, 'b': 8 }, square);
    +     * // => [16, 64] (iteration order is not guaranteed)
    +     *
    +     * var users = [
    +     *   { 'user': 'barney' },
    +     *   { 'user': 'fred' }
    +     * ];
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.map(users, 'user');
    +     * // => ['barney', 'fred']
    +     */
    +    function map(collection, iteratee) {
    +      var func = isArray(collection) ? arrayMap : baseMap;
    +      return func(collection, getIteratee(iteratee, 3));
    +    }
    +
    +    /**
    +     * This method is like `_.sortBy` except that it allows specifying the sort
    +     * orders of the iteratees to sort by. If `orders` is unspecified, all values
    +     * are sorted in ascending order. Otherwise, specify an order of "desc" for
    +     * descending or "asc" for ascending sort order of corresponding values.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
    +     *  The iteratees to sort by.
    +     * @param {string[]} [orders] The sort orders of `iteratees`.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
    +     * @returns {Array} Returns the new sorted array.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'fred',   'age': 48 },
    +     *   { 'user': 'barney', 'age': 34 },
    +     *   { 'user': 'fred',   'age': 40 },
    +     *   { 'user': 'barney', 'age': 36 }
    +     * ];
    +     *
    +     * // Sort by `user` in ascending order and by `age` in descending order.
    +     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
    +     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
    +     */
    +    function orderBy(collection, iteratees, orders, guard) {
    +      if (collection == null) {
    +        return [];
    +      }
    +      if (!isArray(iteratees)) {
    +        iteratees = iteratees == null ? [] : [iteratees];
    +      }
    +      orders = guard ? undefined$1 : orders;
    +      if (!isArray(orders)) {
    +        orders = orders == null ? [] : [orders];
    +      }
    +      return baseOrderBy(collection, iteratees, orders);
    +    }
    +
    +    /**
    +     * Creates an array of elements split into two groups, the first of which
    +     * contains elements `predicate` returns truthy for, the second of which
    +     * contains elements `predicate` returns falsey for. The predicate is
    +     * invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the array of grouped elements.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney',  'age': 36, 'active': false },
    +     *   { 'user': 'fred',    'age': 40, 'active': true },
    +     *   { 'user': 'pebbles', 'age': 1,  'active': false }
    +     * ];
    +     *
    +     * _.partition(users, function(o) { return o.active; });
    +     * // => objects for [['fred'], ['barney', 'pebbles']]
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.partition(users, { 'age': 1, 'active': false });
    +     * // => objects for [['pebbles'], ['barney', 'fred']]
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.partition(users, ['active', false]);
    +     * // => objects for [['barney', 'pebbles'], ['fred']]
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.partition(users, 'active');
    +     * // => objects for [['fred'], ['barney', 'pebbles']]
    +     */
    +    var partition = createAggregator(function(result, value, key) {
    +      result[key ? 0 : 1].push(value);
    +    }, function() { return [[], []]; });
    +
    +    /**
    +     * Reduces `collection` to a value which is the accumulated result of running
    +     * each element in `collection` thru `iteratee`, where each successive
    +     * invocation is supplied the return value of the previous. If `accumulator`
    +     * is not given, the first element of `collection` is used as the initial
    +     * value. The iteratee is invoked with four arguments:
    +     * (accumulator, value, index|key, collection).
    +     *
    +     * Many lodash methods are guarded to work as iteratees for methods like
    +     * `_.reduce`, `_.reduceRight`, and `_.transform`.
    +     *
    +     * The guarded methods are:
    +     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
    +     * and `sortBy`
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @param {*} [accumulator] The initial value.
    +     * @returns {*} Returns the accumulated value.
    +     * @see _.reduceRight
    +     * @example
    +     *
    +     * _.reduce([1, 2], function(sum, n) {
    +     *   return sum + n;
    +     * }, 0);
    +     * // => 3
    +     *
    +     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
    +     *   (result[value] || (result[value] = [])).push(key);
    +     *   return result;
    +     * }, {});
    +     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
    +     */
    +    function reduce(collection, iteratee, accumulator) {
    +      var func = isArray(collection) ? arrayReduce : baseReduce,
    +          initAccum = arguments.length < 3;
    +
    +      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
    +    }
    +
    +    /**
    +     * This method is like `_.reduce` except that it iterates over elements of
    +     * `collection` from right to left.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
    +     * @param {*} [accumulator] The initial value.
    +     * @returns {*} Returns the accumulated value.
    +     * @see _.reduce
    +     * @example
    +     *
    +     * var array = [[0, 1], [2, 3], [4, 5]];
    +     *
    +     * _.reduceRight(array, function(flattened, other) {
    +     *   return flattened.concat(other);
    +     * }, []);
    +     * // => [4, 5, 2, 3, 0, 1]
    +     */
    +    function reduceRight(collection, iteratee, accumulator) {
    +      var func = isArray(collection) ? arrayReduceRight : baseReduce,
    +          initAccum = arguments.length < 3;
    +
    +      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
    +    }
    +
    +    /**
    +     * The opposite of `_.filter`; this method returns the elements of `collection`
    +     * that `predicate` does **not** return truthy for.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @returns {Array} Returns the new filtered array.
    +     * @see _.filter
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'barney', 'age': 36, 'active': false },
    +     *   { 'user': 'fred',   'age': 40, 'active': true }
    +     * ];
    +     *
    +     * _.reject(users, function(o) { return !o.active; });
    +     * // => objects for ['fred']
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.reject(users, { 'age': 40, 'active': true });
    +     * // => objects for ['barney']
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.reject(users, ['active', false]);
    +     * // => objects for ['fred']
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.reject(users, 'active');
    +     * // => objects for ['barney']
    +     */
    +    function reject(collection, predicate) {
    +      var func = isArray(collection) ? arrayFilter : baseFilter;
    +      return func(collection, negate(getIteratee(predicate, 3)));
    +    }
    +
    +    /**
    +     * Gets a random element from `collection`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to sample.
    +     * @returns {*} Returns the random element.
    +     * @example
    +     *
    +     * _.sample([1, 2, 3, 4]);
    +     * // => 2
    +     */
    +    function sample(collection) {
    +      var func = isArray(collection) ? arraySample : baseSample;
    +      return func(collection);
    +    }
    +
    +    /**
    +     * Gets `n` random elements at unique keys from `collection` up to the
    +     * size of `collection`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to sample.
    +     * @param {number} [n=1] The number of elements to sample.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Array} Returns the random elements.
    +     * @example
    +     *
    +     * _.sampleSize([1, 2, 3], 2);
    +     * // => [3, 1]
    +     *
    +     * _.sampleSize([1, 2, 3], 4);
    +     * // => [2, 3, 1]
    +     */
    +    function sampleSize(collection, n, guard) {
    +      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined$1)) {
    +        n = 1;
    +      } else {
    +        n = toInteger(n);
    +      }
    +      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
    +      return func(collection, n);
    +    }
    +
    +    /**
    +     * Creates an array of shuffled values, using a version of the
    +     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to shuffle.
    +     * @returns {Array} Returns the new shuffled array.
    +     * @example
    +     *
    +     * _.shuffle([1, 2, 3, 4]);
    +     * // => [4, 1, 3, 2]
    +     */
    +    function shuffle(collection) {
    +      var func = isArray(collection) ? arrayShuffle : baseShuffle;
    +      return func(collection);
    +    }
    +
    +    /**
    +     * Gets the size of `collection` by returning its length for array-like
    +     * values or the number of own enumerable string keyed properties for objects.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object|string} collection The collection to inspect.
    +     * @returns {number} Returns the collection size.
    +     * @example
    +     *
    +     * _.size([1, 2, 3]);
    +     * // => 3
    +     *
    +     * _.size({ 'a': 1, 'b': 2 });
    +     * // => 2
    +     *
    +     * _.size('pebbles');
    +     * // => 7
    +     */
    +    function size(collection) {
    +      if (collection == null) {
    +        return 0;
    +      }
    +      if (isArrayLike(collection)) {
    +        return isString(collection) ? stringSize(collection) : collection.length;
    +      }
    +      var tag = getTag(collection);
    +      if (tag == mapTag || tag == setTag) {
    +        return collection.size;
    +      }
    +      return baseKeys(collection).length;
    +    }
    +
    +    /**
    +     * Checks if `predicate` returns truthy for **any** element of `collection`.
    +     * Iteration is stopped once `predicate` returns truthy. The predicate is
    +     * invoked with three arguments: (value, index|key, collection).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {Function} [predicate=_.identity] The function invoked per iteration.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {boolean} Returns `true` if any element passes the predicate check,
    +     *  else `false`.
    +     * @example
    +     *
    +     * _.some([null, 0, 'yes', false], Boolean);
    +     * // => true
    +     *
    +     * var users = [
    +     *   { 'user': 'barney', 'active': true },
    +     *   { 'user': 'fred',   'active': false }
    +     * ];
    +     *
    +     * // The `_.matches` iteratee shorthand.
    +     * _.some(users, { 'user': 'barney', 'active': false });
    +     * // => false
    +     *
    +     * // The `_.matchesProperty` iteratee shorthand.
    +     * _.some(users, ['active', false]);
    +     * // => true
    +     *
    +     * // The `_.property` iteratee shorthand.
    +     * _.some(users, 'active');
    +     * // => true
    +     */
    +    function some(collection, predicate, guard) {
    +      var func = isArray(collection) ? arraySome : baseSome;
    +      if (guard && isIterateeCall(collection, predicate, guard)) {
    +        predicate = undefined$1;
    +      }
    +      return func(collection, getIteratee(predicate, 3));
    +    }
    +
    +    /**
    +     * Creates an array of elements, sorted in ascending order by the results of
    +     * running each element in a collection thru each iteratee. This method
    +     * performs a stable sort, that is, it preserves the original sort order of
    +     * equal elements. The iteratees are invoked with one argument: (value).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Collection
    +     * @param {Array|Object} collection The collection to iterate over.
    +     * @param {...(Function|Function[])} [iteratees=[_.identity]]
    +     *  The iteratees to sort by.
    +     * @returns {Array} Returns the new sorted array.
    +     * @example
    +     *
    +     * var users = [
    +     *   { 'user': 'fred',   'age': 48 },
    +     *   { 'user': 'barney', 'age': 36 },
    +     *   { 'user': 'fred',   'age': 30 },
    +     *   { 'user': 'barney', 'age': 34 }
    +     * ];
    +     *
    +     * _.sortBy(users, [function(o) { return o.user; }]);
    +     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
    +     *
    +     * _.sortBy(users, ['user', 'age']);
    +     * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
    +     */
    +    var sortBy = baseRest(function(collection, iteratees) {
    +      if (collection == null) {
    +        return [];
    +      }
    +      var length = iteratees.length;
    +      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
    +        iteratees = [];
    +      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
    +        iteratees = [iteratees[0]];
    +      }
    +      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
    +    });
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * Gets the timestamp of the number of milliseconds that have elapsed since
    +     * the Unix epoch (1 January 1970 00:00:00 UTC).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.4.0
    +     * @category Date
    +     * @returns {number} Returns the timestamp.
    +     * @example
    +     *
    +     * _.defer(function(stamp) {
    +     *   console.log(_.now() - stamp);
    +     * }, _.now());
    +     * // => Logs the number of milliseconds it took for the deferred invocation.
    +     */
    +    var now = ctxNow || function() {
    +      return root.Date.now();
    +    };
    +
    +    /*------------------------------------------------------------------------*/
    +
    +    /**
    +     * The opposite of `_.before`; this method creates a function that invokes
    +     * `func` once it's called `n` or more times.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {number} n The number of calls before `func` is invoked.
    +     * @param {Function} func The function to restrict.
    +     * @returns {Function} Returns the new restricted function.
    +     * @example
    +     *
    +     * var saves = ['profile', 'settings'];
    +     *
    +     * var done = _.after(saves.length, function() {
    +     *   console.log('done saving!');
    +     * });
    +     *
    +     * _.forEach(saves, function(type) {
    +     *   asyncSave({ 'type': type, 'complete': done });
    +     * });
    +     * // => Logs 'done saving!' after the two async saves have completed.
    +     */
    +    function after(n, func) {
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      n = toInteger(n);
    +      return function() {
    +        if (--n < 1) {
    +          return func.apply(this, arguments);
    +        }
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that invokes `func`, with up to `n` arguments,
    +     * ignoring any additional arguments.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Function
    +     * @param {Function} func The function to cap arguments for.
    +     * @param {number} [n=func.length] The arity cap.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Function} Returns the new capped function.
    +     * @example
    +     *
    +     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
    +     * // => [6, 8, 10]
    +     */
    +    function ary(func, n, guard) {
    +      n = guard ? undefined$1 : n;
    +      n = (func && n == null) ? func.length : n;
    +      return createWrap(func, WRAP_ARY_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, n);
    +    }
    +
    +    /**
    +     * Creates a function that invokes `func`, with the `this` binding and arguments
    +     * of the created function, while it's called less than `n` times. Subsequent
    +     * calls to the created function return the result of the last `func` invocation.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Function
    +     * @param {number} n The number of calls at which `func` is no longer invoked.
    +     * @param {Function} func The function to restrict.
    +     * @returns {Function} Returns the new restricted function.
    +     * @example
    +     *
    +     * jQuery(element).on('click', _.before(5, addContactToList));
    +     * // => Allows adding up to 4 contacts to the list.
    +     */
    +    function before(n, func) {
    +      var result;
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      n = toInteger(n);
    +      return function() {
    +        if (--n > 0) {
    +          result = func.apply(this, arguments);
    +        }
    +        if (n <= 1) {
    +          func = undefined$1;
    +        }
    +        return result;
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that invokes `func` with the `this` binding of `thisArg`
    +     * and `partials` prepended to the arguments it receives.
    +     *
    +     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
    +     * may be used as a placeholder for partially applied arguments.
    +     *
    +     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
    +     * property of bound functions.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to bind.
    +     * @param {*} thisArg The `this` binding of `func`.
    +     * @param {...*} [partials] The arguments to be partially applied.
    +     * @returns {Function} Returns the new bound function.
    +     * @example
    +     *
    +     * function greet(greeting, punctuation) {
    +     *   return greeting + ' ' + this.user + punctuation;
    +     * }
    +     *
    +     * var object = { 'user': 'fred' };
    +     *
    +     * var bound = _.bind(greet, object, 'hi');
    +     * bound('!');
    +     * // => 'hi fred!'
    +     *
    +     * // Bound with placeholders.
    +     * var bound = _.bind(greet, object, _, '!');
    +     * bound('hi');
    +     * // => 'hi fred!'
    +     */
    +    var bind = baseRest(function(func, thisArg, partials) {
    +      var bitmask = WRAP_BIND_FLAG;
    +      if (partials.length) {
    +        var holders = replaceHolders(partials, getHolder(bind));
    +        bitmask |= WRAP_PARTIAL_FLAG;
    +      }
    +      return createWrap(func, bitmask, thisArg, partials, holders);
    +    });
    +
    +    /**
    +     * Creates a function that invokes the method at `object[key]` with `partials`
    +     * prepended to the arguments it receives.
    +     *
    +     * This method differs from `_.bind` by allowing bound functions to reference
    +     * methods that may be redefined or don't yet exist. See
    +     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
    +     * for more details.
    +     *
    +     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
    +     * builds, may be used as a placeholder for partially applied arguments.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.10.0
    +     * @category Function
    +     * @param {Object} object The object to invoke the method on.
    +     * @param {string} key The key of the method.
    +     * @param {...*} [partials] The arguments to be partially applied.
    +     * @returns {Function} Returns the new bound function.
    +     * @example
    +     *
    +     * var object = {
    +     *   'user': 'fred',
    +     *   'greet': function(greeting, punctuation) {
    +     *     return greeting + ' ' + this.user + punctuation;
    +     *   }
    +     * };
    +     *
    +     * var bound = _.bindKey(object, 'greet', 'hi');
    +     * bound('!');
    +     * // => 'hi fred!'
    +     *
    +     * object.greet = function(greeting, punctuation) {
    +     *   return greeting + 'ya ' + this.user + punctuation;
    +     * };
    +     *
    +     * bound('!');
    +     * // => 'hiya fred!'
    +     *
    +     * // Bound with placeholders.
    +     * var bound = _.bindKey(object, 'greet', _, '!');
    +     * bound('hi');
    +     * // => 'hiya fred!'
    +     */
    +    var bindKey = baseRest(function(object, key, partials) {
    +      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
    +      if (partials.length) {
    +        var holders = replaceHolders(partials, getHolder(bindKey));
    +        bitmask |= WRAP_PARTIAL_FLAG;
    +      }
    +      return createWrap(key, bitmask, object, partials, holders);
    +    });
    +
    +    /**
    +     * Creates a function that accepts arguments of `func` and either invokes
    +     * `func` returning its result, if at least `arity` number of arguments have
    +     * been provided, or returns a function that accepts the remaining `func`
    +     * arguments, and so on. The arity of `func` may be specified if `func.length`
    +     * is not sufficient.
    +     *
    +     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
    +     * may be used as a placeholder for provided arguments.
    +     *
    +     * **Note:** This method doesn't set the "length" property of curried functions.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 2.0.0
    +     * @category Function
    +     * @param {Function} func The function to curry.
    +     * @param {number} [arity=func.length] The arity of `func`.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Function} Returns the new curried function.
    +     * @example
    +     *
    +     * var abc = function(a, b, c) {
    +     *   return [a, b, c];
    +     * };
    +     *
    +     * var curried = _.curry(abc);
    +     *
    +     * curried(1)(2)(3);
    +     * // => [1, 2, 3]
    +     *
    +     * curried(1, 2)(3);
    +     * // => [1, 2, 3]
    +     *
    +     * curried(1, 2, 3);
    +     * // => [1, 2, 3]
    +     *
    +     * // Curried with placeholders.
    +     * curried(1)(_, 3)(2);
    +     * // => [1, 2, 3]
    +     */
    +    function curry(func, arity, guard) {
    +      arity = guard ? undefined$1 : arity;
    +      var result = createWrap(func, WRAP_CURRY_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, undefined$1, arity);
    +      result.placeholder = curry.placeholder;
    +      return result;
    +    }
    +
    +    /**
    +     * This method is like `_.curry` except that arguments are applied to `func`
    +     * in the manner of `_.partialRight` instead of `_.partial`.
    +     *
    +     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
    +     * builds, may be used as a placeholder for provided arguments.
    +     *
    +     * **Note:** This method doesn't set the "length" property of curried functions.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Function
    +     * @param {Function} func The function to curry.
    +     * @param {number} [arity=func.length] The arity of `func`.
    +     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
    +     * @returns {Function} Returns the new curried function.
    +     * @example
    +     *
    +     * var abc = function(a, b, c) {
    +     *   return [a, b, c];
    +     * };
    +     *
    +     * var curried = _.curryRight(abc);
    +     *
    +     * curried(3)(2)(1);
    +     * // => [1, 2, 3]
    +     *
    +     * curried(2, 3)(1);
    +     * // => [1, 2, 3]
    +     *
    +     * curried(1, 2, 3);
    +     * // => [1, 2, 3]
    +     *
    +     * // Curried with placeholders.
    +     * curried(3)(1, _)(2);
    +     * // => [1, 2, 3]
    +     */
    +    function curryRight(func, arity, guard) {
    +      arity = guard ? undefined$1 : arity;
    +      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, undefined$1, arity);
    +      result.placeholder = curryRight.placeholder;
    +      return result;
    +    }
    +
    +    /**
    +     * Creates a debounced function that delays invoking `func` until after `wait`
    +     * milliseconds have elapsed since the last time the debounced function was
    +     * invoked. The debounced function comes with a `cancel` method to cancel
    +     * delayed `func` invocations and a `flush` method to immediately invoke them.
    +     * Provide `options` to indicate whether `func` should be invoked on the
    +     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
    +     * with the last arguments provided to the debounced function. Subsequent
    +     * calls to the debounced function return the result of the last `func`
    +     * invocation.
    +     *
    +     * **Note:** If `leading` and `trailing` options are `true`, `func` is
    +     * invoked on the trailing edge of the timeout only if the debounced function
    +     * is invoked more than once during the `wait` timeout.
    +     *
    +     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
    +     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
    +     *
    +     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
    +     * for details over the differences between `_.debounce` and `_.throttle`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to debounce.
    +     * @param {number} [wait=0] The number of milliseconds to delay.
    +     * @param {Object} [options={}] The options object.
    +     * @param {boolean} [options.leading=false]
    +     *  Specify invoking on the leading edge of the timeout.
    +     * @param {number} [options.maxWait]
    +     *  The maximum time `func` is allowed to be delayed before it's invoked.
    +     * @param {boolean} [options.trailing=true]
    +     *  Specify invoking on the trailing edge of the timeout.
    +     * @returns {Function} Returns the new debounced function.
    +     * @example
    +     *
    +     * // Avoid costly calculations while the window size is in flux.
    +     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
    +     *
    +     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
    +     * jQuery(element).on('click', _.debounce(sendMail, 300, {
    +     *   'leading': true,
    +     *   'trailing': false
    +     * }));
    +     *
    +     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
    +     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
    +     * var source = new EventSource('/stream');
    +     * jQuery(source).on('message', debounced);
    +     *
    +     * // Cancel the trailing debounced invocation.
    +     * jQuery(window).on('popstate', debounced.cancel);
    +     */
    +    function debounce(func, wait, options) {
    +      var lastArgs,
    +          lastThis,
    +          maxWait,
    +          result,
    +          timerId,
    +          lastCallTime,
    +          lastInvokeTime = 0,
    +          leading = false,
    +          maxing = false,
    +          trailing = true;
    +
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      wait = toNumber(wait) || 0;
    +      if (isObject(options)) {
    +        leading = !!options.leading;
    +        maxing = 'maxWait' in options;
    +        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
    +        trailing = 'trailing' in options ? !!options.trailing : trailing;
    +      }
    +
    +      function invokeFunc(time) {
    +        var args = lastArgs,
    +            thisArg = lastThis;
    +
    +        lastArgs = lastThis = undefined$1;
    +        lastInvokeTime = time;
    +        result = func.apply(thisArg, args);
    +        return result;
    +      }
    +
    +      function leadingEdge(time) {
    +        // Reset any `maxWait` timer.
    +        lastInvokeTime = time;
    +        // Start the timer for the trailing edge.
    +        timerId = setTimeout(timerExpired, wait);
    +        // Invoke the leading edge.
    +        return leading ? invokeFunc(time) : result;
    +      }
    +
    +      function remainingWait(time) {
    +        var timeSinceLastCall = time - lastCallTime,
    +            timeSinceLastInvoke = time - lastInvokeTime,
    +            timeWaiting = wait - timeSinceLastCall;
    +
    +        return maxing
    +          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
    +          : timeWaiting;
    +      }
    +
    +      function shouldInvoke(time) {
    +        var timeSinceLastCall = time - lastCallTime,
    +            timeSinceLastInvoke = time - lastInvokeTime;
    +
    +        // Either this is the first call, activity has stopped and we're at the
    +        // trailing edge, the system time has gone backwards and we're treating
    +        // it as the trailing edge, or we've hit the `maxWait` limit.
    +        return (lastCallTime === undefined$1 || (timeSinceLastCall >= wait) ||
    +          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
    +      }
    +
    +      function timerExpired() {
    +        var time = now();
    +        if (shouldInvoke(time)) {
    +          return trailingEdge(time);
    +        }
    +        // Restart the timer.
    +        timerId = setTimeout(timerExpired, remainingWait(time));
    +      }
    +
    +      function trailingEdge(time) {
    +        timerId = undefined$1;
    +
    +        // Only invoke if we have `lastArgs` which means `func` has been
    +        // debounced at least once.
    +        if (trailing && lastArgs) {
    +          return invokeFunc(time);
    +        }
    +        lastArgs = lastThis = undefined$1;
    +        return result;
    +      }
    +
    +      function cancel() {
    +        if (timerId !== undefined$1) {
    +          clearTimeout(timerId);
    +        }
    +        lastInvokeTime = 0;
    +        lastArgs = lastCallTime = lastThis = timerId = undefined$1;
    +      }
    +
    +      function flush() {
    +        return timerId === undefined$1 ? result : trailingEdge(now());
    +      }
    +
    +      function debounced() {
    +        var time = now(),
    +            isInvoking = shouldInvoke(time);
    +
    +        lastArgs = arguments;
    +        lastThis = this;
    +        lastCallTime = time;
    +
    +        if (isInvoking) {
    +          if (timerId === undefined$1) {
    +            return leadingEdge(lastCallTime);
    +          }
    +          if (maxing) {
    +            // Handle invocations in a tight loop.
    +            clearTimeout(timerId);
    +            timerId = setTimeout(timerExpired, wait);
    +            return invokeFunc(lastCallTime);
    +          }
    +        }
    +        if (timerId === undefined$1) {
    +          timerId = setTimeout(timerExpired, wait);
    +        }
    +        return result;
    +      }
    +      debounced.cancel = cancel;
    +      debounced.flush = flush;
    +      return debounced;
    +    }
    +
    +    /**
    +     * Defers invoking the `func` until the current call stack has cleared. Any
    +     * additional arguments are provided to `func` when it's invoked.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to defer.
    +     * @param {...*} [args] The arguments to invoke `func` with.
    +     * @returns {number} Returns the timer id.
    +     * @example
    +     *
    +     * _.defer(function(text) {
    +     *   console.log(text);
    +     * }, 'deferred');
    +     * // => Logs 'deferred' after one millisecond.
    +     */
    +    var defer = baseRest(function(func, args) {
    +      return baseDelay(func, 1, args);
    +    });
    +
    +    /**
    +     * Invokes `func` after `wait` milliseconds. Any additional arguments are
    +     * provided to `func` when it's invoked.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to delay.
    +     * @param {number} wait The number of milliseconds to delay invocation.
    +     * @param {...*} [args] The arguments to invoke `func` with.
    +     * @returns {number} Returns the timer id.
    +     * @example
    +     *
    +     * _.delay(function(text) {
    +     *   console.log(text);
    +     * }, 1000, 'later');
    +     * // => Logs 'later' after one second.
    +     */
    +    var delay = baseRest(function(func, wait, args) {
    +      return baseDelay(func, toNumber(wait) || 0, args);
    +    });
    +
    +    /**
    +     * Creates a function that invokes `func` with arguments reversed.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Function
    +     * @param {Function} func The function to flip arguments for.
    +     * @returns {Function} Returns the new flipped function.
    +     * @example
    +     *
    +     * var flipped = _.flip(function() {
    +     *   return _.toArray(arguments);
    +     * });
    +     *
    +     * flipped('a', 'b', 'c', 'd');
    +     * // => ['d', 'c', 'b', 'a']
    +     */
    +    function flip(func) {
    +      return createWrap(func, WRAP_FLIP_FLAG);
    +    }
    +
    +    /**
    +     * Creates a function that memoizes the result of `func`. If `resolver` is
    +     * provided, it determines the cache key for storing the result based on the
    +     * arguments provided to the memoized function. By default, the first argument
    +     * provided to the memoized function is used as the map cache key. The `func`
    +     * is invoked with the `this` binding of the memoized function.
    +     *
    +     * **Note:** The cache is exposed as the `cache` property on the memoized
    +     * function. Its creation may be customized by replacing the `_.memoize.Cache`
    +     * constructor with one whose instances implement the
    +     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
    +     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to have its output memoized.
    +     * @param {Function} [resolver] The function to resolve the cache key.
    +     * @returns {Function} Returns the new memoized function.
    +     * @example
    +     *
    +     * var object = { 'a': 1, 'b': 2 };
    +     * var other = { 'c': 3, 'd': 4 };
    +     *
    +     * var values = _.memoize(_.values);
    +     * values(object);
    +     * // => [1, 2]
    +     *
    +     * values(other);
    +     * // => [3, 4]
    +     *
    +     * object.a = 2;
    +     * values(object);
    +     * // => [1, 2]
    +     *
    +     * // Modify the result cache.
    +     * values.cache.set(object, ['a', 'b']);
    +     * values(object);
    +     * // => ['a', 'b']
    +     *
    +     * // Replace `_.memoize.Cache`.
    +     * _.memoize.Cache = WeakMap;
    +     */
    +    function memoize(func, resolver) {
    +      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      var memoized = function() {
    +        var args = arguments,
    +            key = resolver ? resolver.apply(this, args) : args[0],
    +            cache = memoized.cache;
    +
    +        if (cache.has(key)) {
    +          return cache.get(key);
    +        }
    +        var result = func.apply(this, args);
    +        memoized.cache = cache.set(key, result) || cache;
    +        return result;
    +      };
    +      memoized.cache = new (memoize.Cache || MapCache);
    +      return memoized;
    +    }
    +
    +    // Expose `MapCache`.
    +    memoize.Cache = MapCache;
    +
    +    /**
    +     * Creates a function that negates the result of the predicate `func`. The
    +     * `func` predicate is invoked with the `this` binding and arguments of the
    +     * created function.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Function
    +     * @param {Function} predicate The predicate to negate.
    +     * @returns {Function} Returns the new negated function.
    +     * @example
    +     *
    +     * function isEven(n) {
    +     *   return n % 2 == 0;
    +     * }
    +     *
    +     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
    +     * // => [1, 3, 5]
    +     */
    +    function negate(predicate) {
    +      if (typeof predicate != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      return function() {
    +        var args = arguments;
    +        switch (args.length) {
    +          case 0: return !predicate.call(this);
    +          case 1: return !predicate.call(this, args[0]);
    +          case 2: return !predicate.call(this, args[0], args[1]);
    +          case 3: return !predicate.call(this, args[0], args[1], args[2]);
    +        }
    +        return !predicate.apply(this, args);
    +      };
    +    }
    +
    +    /**
    +     * Creates a function that is restricted to invoking `func` once. Repeat calls
    +     * to the function return the value of the first invocation. The `func` is
    +     * invoked with the `this` binding and arguments of the created function.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to restrict.
    +     * @returns {Function} Returns the new restricted function.
    +     * @example
    +     *
    +     * var initialize = _.once(createApplication);
    +     * initialize();
    +     * initialize();
    +     * // => `createApplication` is invoked once
    +     */
    +    function once(func) {
    +      return before(2, func);
    +    }
    +
    +    /**
    +     * Creates a function that invokes `func` with its arguments transformed.
    +     *
    +     * @static
    +     * @since 4.0.0
    +     * @memberOf _
    +     * @category Function
    +     * @param {Function} func The function to wrap.
    +     * @param {...(Function|Function[])} [transforms=[_.identity]]
    +     *  The argument transforms.
    +     * @returns {Function} Returns the new function.
    +     * @example
    +     *
    +     * function doubled(n) {
    +     *   return n * 2;
    +     * }
    +     *
    +     * function square(n) {
    +     *   return n * n;
    +     * }
    +     *
    +     * var func = _.overArgs(function(x, y) {
    +     *   return [x, y];
    +     * }, [square, doubled]);
    +     *
    +     * func(9, 3);
    +     * // => [81, 6]
    +     *
    +     * func(10, 5);
    +     * // => [100, 10]
    +     */
    +    var overArgs = castRest(function(func, transforms) {
    +      transforms = (transforms.length == 1 && isArray(transforms[0]))
    +        ? arrayMap(transforms[0], baseUnary(getIteratee()))
    +        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
    +
    +      var funcsLength = transforms.length;
    +      return baseRest(function(args) {
    +        var index = -1,
    +            length = nativeMin(args.length, funcsLength);
    +
    +        while (++index < length) {
    +          args[index] = transforms[index].call(this, args[index]);
    +        }
    +        return apply(func, this, args);
    +      });
    +    });
    +
    +    /**
    +     * Creates a function that invokes `func` with `partials` prepended to the
    +     * arguments it receives. This method is like `_.bind` except it does **not**
    +     * alter the `this` binding.
    +     *
    +     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
    +     * builds, may be used as a placeholder for partially applied arguments.
    +     *
    +     * **Note:** This method doesn't set the "length" property of partially
    +     * applied functions.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.2.0
    +     * @category Function
    +     * @param {Function} func The function to partially apply arguments to.
    +     * @param {...*} [partials] The arguments to be partially applied.
    +     * @returns {Function} Returns the new partially applied function.
    +     * @example
    +     *
    +     * function greet(greeting, name) {
    +     *   return greeting + ' ' + name;
    +     * }
    +     *
    +     * var sayHelloTo = _.partial(greet, 'hello');
    +     * sayHelloTo('fred');
    +     * // => 'hello fred'
    +     *
    +     * // Partially applied with placeholders.
    +     * var greetFred = _.partial(greet, _, 'fred');
    +     * greetFred('hi');
    +     * // => 'hi fred'
    +     */
    +    var partial = baseRest(function(func, partials) {
    +      var holders = replaceHolders(partials, getHolder(partial));
    +      return createWrap(func, WRAP_PARTIAL_FLAG, undefined$1, partials, holders);
    +    });
    +
    +    /**
    +     * This method is like `_.partial` except that partially applied arguments
    +     * are appended to the arguments it receives.
    +     *
    +     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
    +     * builds, may be used as a placeholder for partially applied arguments.
    +     *
    +     * **Note:** This method doesn't set the "length" property of partially
    +     * applied functions.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 1.0.0
    +     * @category Function
    +     * @param {Function} func The function to partially apply arguments to.
    +     * @param {...*} [partials] The arguments to be partially applied.
    +     * @returns {Function} Returns the new partially applied function.
    +     * @example
    +     *
    +     * function greet(greeting, name) {
    +     *   return greeting + ' ' + name;
    +     * }
    +     *
    +     * var greetFred = _.partialRight(greet, 'fred');
    +     * greetFred('hi');
    +     * // => 'hi fred'
    +     *
    +     * // Partially applied with placeholders.
    +     * var sayHelloTo = _.partialRight(greet, 'hello', _);
    +     * sayHelloTo('fred');
    +     * // => 'hello fred'
    +     */
    +    var partialRight = baseRest(function(func, partials) {
    +      var holders = replaceHolders(partials, getHolder(partialRight));
    +      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined$1, partials, holders);
    +    });
    +
    +    /**
    +     * Creates a function that invokes `func` with arguments arranged according
    +     * to the specified `indexes` where the argument value at the first index is
    +     * provided as the first argument, the argument value at the second index is
    +     * provided as the second argument, and so on.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.0.0
    +     * @category Function
    +     * @param {Function} func The function to rearrange arguments for.
    +     * @param {...(number|number[])} indexes The arranged argument indexes.
    +     * @returns {Function} Returns the new function.
    +     * @example
    +     *
    +     * var rearged = _.rearg(function(a, b, c) {
    +     *   return [a, b, c];
    +     * }, [2, 0, 1]);
    +     *
    +     * rearged('b', 'c', 'a')
    +     * // => ['a', 'b', 'c']
    +     */
    +    var rearg = flatRest(function(func, indexes) {
    +      return createWrap(func, WRAP_REARG_FLAG, undefined$1, undefined$1, undefined$1, indexes);
    +    });
    +
    +    /**
    +     * Creates a function that invokes `func` with the `this` binding of the
    +     * created function and arguments from `start` and beyond provided as
    +     * an array.
    +     *
    +     * **Note:** This method is based on the
    +     * [rest parameter](https://mdn.io/rest_parameters).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Function
    +     * @param {Function} func The function to apply a rest parameter to.
    +     * @param {number} [start=func.length-1] The start position of the rest parameter.
    +     * @returns {Function} Returns the new function.
    +     * @example
    +     *
    +     * var say = _.rest(function(what, names) {
    +     *   return what + ' ' + _.initial(names).join(', ') +
    +     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
    +     * });
    +     *
    +     * say('hello', 'fred', 'barney', 'pebbles');
    +     * // => 'hello fred, barney, & pebbles'
    +     */
    +    function rest(func, start) {
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      start = start === undefined$1 ? start : toInteger(start);
    +      return baseRest(func, start);
    +    }
    +
    +    /**
    +     * Creates a function that invokes `func` with the `this` binding of the
    +     * create function and an array of arguments much like
    +     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
    +     *
    +     * **Note:** This method is based on the
    +     * [spread operator](https://mdn.io/spread_operator).
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 3.2.0
    +     * @category Function
    +     * @param {Function} func The function to spread arguments over.
    +     * @param {number} [start=0] The start position of the spread.
    +     * @returns {Function} Returns the new function.
    +     * @example
    +     *
    +     * var say = _.spread(function(who, what) {
    +     *   return who + ' says ' + what;
    +     * });
    +     *
    +     * say(['fred', 'hello']);
    +     * // => 'fred says hello'
    +     *
    +     * var numbers = Promise.all([
    +     *   Promise.resolve(40),
    +     *   Promise.resolve(36)
    +     * ]);
    +     *
    +     * numbers.then(_.spread(function(x, y) {
    +     *   return x + y;
    +     * }));
    +     * // => a Promise of 76
    +     */
    +    function spread(func, start) {
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      start = start == null ? 0 : nativeMax(toInteger(start), 0);
    +      return baseRest(function(args) {
    +        var array = args[start],
    +            otherArgs = castSlice(args, 0, start);
    +
    +        if (array) {
    +          arrayPush(otherArgs, array);
    +        }
    +        return apply(func, this, otherArgs);
    +      });
    +    }
    +
    +    /**
    +     * Creates a throttled function that only invokes `func` at most once per
    +     * every `wait` milliseconds. The throttled function comes with a `cancel`
    +     * method to cancel delayed `func` invocations and a `flush` method to
    +     * immediately invoke them. Provide `options` to indicate whether `func`
    +     * should be invoked on the leading and/or trailing edge of the `wait`
    +     * timeout. The `func` is invoked with the last arguments provided to the
    +     * throttled function. Subsequent calls to the throttled function return the
    +     * result of the last `func` invocation.
    +     *
    +     * **Note:** If `leading` and `trailing` options are `true`, `func` is
    +     * invoked on the trailing edge of the timeout only if the throttled function
    +     * is invoked more than once during the `wait` timeout.
    +     *
    +     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
    +     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
    +     *
    +     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
    +     * for details over the differences between `_.throttle` and `_.debounce`.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {Function} func The function to throttle.
    +     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
    +     * @param {Object} [options={}] The options object.
    +     * @param {boolean} [options.leading=true]
    +     *  Specify invoking on the leading edge of the timeout.
    +     * @param {boolean} [options.trailing=true]
    +     *  Specify invoking on the trailing edge of the timeout.
    +     * @returns {Function} Returns the new throttled function.
    +     * @example
    +     *
    +     * // Avoid excessively updating the position while scrolling.
    +     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
    +     *
    +     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
    +     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
    +     * jQuery(element).on('click', throttled);
    +     *
    +     * // Cancel the trailing throttled invocation.
    +     * jQuery(window).on('popstate', throttled.cancel);
    +     */
    +    function throttle(func, wait, options) {
    +      var leading = true,
    +          trailing = true;
    +
    +      if (typeof func != 'function') {
    +        throw new TypeError(FUNC_ERROR_TEXT);
    +      }
    +      if (isObject(options)) {
    +        leading = 'leading' in options ? !!options.leading : leading;
    +        trailing = 'trailing' in options ? !!options.trailing : trailing;
    +      }
    +      return debounce(func, wait, {
    +        'leading': leading,
    +        'maxWait': wait,
    +        'trailing': trailing
    +      });
    +    }
    +
    +    /**
    +     * Creates a function that accepts up to one argument, ignoring any
    +     * additional arguments.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 4.0.0
    +     * @category Function
    +     * @param {Function} func The function to cap arguments for.
    +     * @returns {Function} Returns the new capped function.
    +     * @example
    +     *
    +     * _.map(['6', '8', '10'], _.unary(parseInt));
    +     * // => [6, 8, 10]
    +     */
    +    function unary(func) {
    +      return ary(func, 1);
    +    }
    +
    +    /**
    +     * Creates a function that provides `value` to `wrapper` as its first
    +     * argument. Any additional arguments provided to the function are appended
    +     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
    +     * binding of the created function.
    +     *
    +     * @static
    +     * @memberOf _
    +     * @since 0.1.0
    +     * @category Function
    +     * @param {*} value The value to wrap.
    +     * @param {Function} [wrapper=identity] The wrapper function.
    +     * @returns {Function} Returns the new function.
    +     * @example
    +     *
    +     * var p = _.wrap(_.escape, function(func, text) {
    +     *   return '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ + function wrap(value, wrapper) { + return partial(castFunction(wrapper), value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ + function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + var gt = createRelationalOperation(baseGt); + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + var gte = createRelationalOperation(function(value, other) { + return value >= other; + }); + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + var result = customizer ? customizer(value, other) : undefined$1; + return result === undefined$1 ? baseIsEqual(value, other, undefined$1, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } + return baseIsNative(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined$1; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + * @see _.gt + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + var lt = createRelationalOperation(baseLt); + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to + * `other`, else `false`. + * @see _.gte + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + var lte = createRelationalOperation(function(value, other) { + return value <= other; + }); + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3.2); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3.2'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3.2); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3.2'); + * // => 3 + */ + function toSafeInteger(value) { + return value + ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) + : (value === 0 ? value : 0); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ + var assign = createAssigner(function(object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ + var at = flatRest(baseAt); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined$1; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined$1 || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ + var defaultsDeep = baseRest(function(args) { + args.push(undefined$1, customDefaultsMerge); + return apply(mergeWith, undefined$1, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); + } + + /** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined$1 : baseGet(object, path); + return result === undefined$1 ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = baseRest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(getIteratee(predicate))); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + path = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined$1; + } + while (++index < length) { + var value = object == null ? undefined$1 : object[toKey(path[index])]; + if (value === undefined$1) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable string keyed-value pairs for `object` + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entries + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + var toPairs = createToPairs(keys); + + /** + * Creates an array of own and inherited enumerable string keyed-value pairs + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entriesIn + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) + */ + var toPairsIn = createToPairs(keysIn); + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable string keyed properties thru `iteratee`, with each invocation + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + + iteratee = getIteratee(iteratee, 4); + if (accumulator == null) { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { + accumulator = {}; + } + } + (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, ['a', '0', 'b', 'c']); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, castFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable string keyed property + * values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined$1) { + upper = lower; + lower = undefined$1; + } + if (upper !== undefined$1) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined$1) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toFinite(start); + if (end === undefined$1) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined$1; + } + if (floating === undefined$1) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined$1; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined$1; + } + } + if (lower === undefined$1 && upper === undefined$1) { + lower = 0; + upper = 1; + } + else { + lower = toFinite(lower); + if (upper === undefined$1) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + + var length = string.length; + position = position === undefined$1 + ? length + : baseClamp(toInteger(position), 0, length); + + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; + } + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar--'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2; + return ( + createPadding(nativeFloor(mid), chars) + + string + + createPadding(nativeCeil(mid), chars) + ); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (string + createPadding(length - strLength, chars)) + : string; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (createPadding(length - strLength, chars) + string) + : string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a + * hexadecimal, in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the + * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=1] The number of times to repeat the string. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n, guard) { + if ((guard ? isIterateeCall(string, n, guard) : n === undefined$1)) { + n = 1; + } else { + n = toInteger(n); + } + return baseRepeat(toString(string), n); + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on + * [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on + * [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { + separator = limit = undefined$1; + } + limit = limit === undefined$1 ? MAX_ARRAY_LENGTH : limit >>> 0; + if (!limit) { + return []; + } + string = toString(string); + if (string && ( + typeof separator == 'string' || + (separator != null && !isRegExp(separator)) + )) { + separator = baseToString(separator); + if (!separator && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } + return string.split(separator, limit); + } + + /** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @since 3.1.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + upperFirst(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = position == null + ? 0 + : baseClamp(toInteger(position), 0, string.length); + + target = baseToString(target); + return string.slice(position, position + target.length) == target; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given, it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options={}] The options object. + * @param {RegExp} [options.escape=_.templateSettings.escape] + * The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] + * The "evaluate" delimiter. + * @param {Object} [options.imports=_.templateSettings.imports] + * An object to import into the template as free variables. + * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] + * The "interpolate" delimiter. + * @param {string} [options.sourceURL='lodash.templateSources[n]'] + * The sourceURL of the compiled template. + * @param {string} [options.variable='obj'] + * The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '