diff --git a/.gitattributes b/.gitattributes index 3aa4239..6661d28 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,7 @@ # bytes still match the upstream file it is attributed to. datasets/public/*.jsonl -text datasets/public/LICENSE-* -text + +# The vendored markdown renderer is pinned by sha256 in scripts/render_docs.mjs, +# so a line-ending conversion on checkout would fail the build. +site/vendor/** -text diff --git a/.github/workflows/site.yml b/.github/workflows/site.yml index dbd4ab9..1836e98 100644 --- a/.github/workflows/site.yml +++ b/.github/workflows/site.yml @@ -3,9 +3,9 @@ name: Site # The site at tmhsdigital.github.io/plumbline carries a JavaScript # reimplementation of the calibration floor. If it disagrees with the Python, # the site misreports the tool, which is worse than having no site. This -# workflow holds the two together; later jobs assemble and deploy the site, and -# they depend on this one, so a wrong calculator never ships. A stale site is -# the better failure. +# workflow holds the two together. The site is assembled inside this job, and +# the deploy job (not yet added) will need it, so a wrong calculator or a +# broken doc never ships. A stale site is the better failure. # # It is deliberately separate from ci.yml and release.yml: it shares no jobs, # no concurrency group, and no permissions with either. @@ -44,8 +44,15 @@ jobs: - name: The committed fixture is what the Python produces today run: uv run python scripts/floor_golden.py --check + # The renderer's refusals (raw HTML off the allowlist, broken links and + # anchors, remote images, a modified vendored file) each have a case. + - name: The doc renderer refuses what it should + run: node scripts/render_docs.mjs --self-test + # Regenerates the worked example from the mock adapter, by the command # docs/example-report.md records, and refuses if the report is stale. + # Renders the repository's docs from this commit, and refuses on a broken + # link or anchor, or raw HTML outside the allowlist. - name: Assemble the site run: uv run python scripts/build_site.py --out _site diff --git a/CHANGELOG.md b/CHANGELOG.md index 93eb29f..9e7b01d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,12 @@ different event from one that moved because it was wrong. `scripts/build_site.py` regenerates the example from the mock adapter at build time and refuses if `docs/example-report.md` no longer matches its own command. +- The site hosts the repository's docs (README, METHODOLOGY, PLAN, the example + report, CHANGELOG, CONTRIBUTING, SECURITY, and the dataset README), rendered + at build time from the commit being deployed by a vendored markdown-it under + the runner's Node. Each page names the commit and build time it came from. + The build fails on a broken link or anchor, on raw HTML outside a short + allowlist, and on a modified vendored renderer. ### Changed diff --git a/scripts/build_site.py b/scripts/build_site.py index 613c11a..4e1d411 100644 --- a/scripts/build_site.py +++ b/scripts/build_site.py @@ -10,6 +10,13 @@ rows, in JavaScript, and ``scripts/check_floor_parity.mjs`` fails the build if what it derives differs from the report by a single character. +``docs/`` + The repository's markdown docs as they are at the commit being built: each + one copied verbatim as ``.md`` and rendered to ``.html`` by + ``scripts/render_docs.mjs``, with a line naming the commit and build time it + came from. Nothing is written by hand and nothing is fetched at runtime, so + the pages cannot drift from ``main``: a deploy re-renders them. + The example is regenerated from the **mock** adapter and nothing else. The command is read from the report, and anything other than ``--adapter mock`` is refused, so a vendor run can never be published through this path. The run @@ -17,20 +24,26 @@ read; no existing results directory or artifact is ever opened. uv run python scripts/build_site.py --out _site + +Rendering needs ``node`` on the PATH (the runner's own; nothing is installed). """ from __future__ import annotations import argparse import contextlib +import html import io import json import os import re import shlex import shutil +import subprocess import sys import tempfile +from dataclasses import dataclass +from datetime import UTC, datetime from pathlib import Path from typing import Any @@ -41,10 +54,65 @@ ROOT = Path(__file__).resolve().parent.parent SITE = ROOT / "site" EXAMPLE_REPORT = ROOT / "docs" / "example-report.md" +RENDERER = ROOT / "scripts" / "render_docs.mjs" +REPO = "TMHSDigital/plumbline" #: The only adapter whose output this script will publish. ALLOWED_ADAPTER = "mock" + +@dataclass(frozen=True) +class Doc: + source: str # path in the repository + slug: str # docs/.html and docs/.md on the site + label: str # its name in the navigation + blurb: str # one line on the docs index + + +#: The docs the site hosts, in navigation order. A relative link between two of +#: these becomes a link between their pages; a link to any other file goes to +#: GitHub at the commit being built. +DOCS = ( + Doc( + "README.md", + "readme", + "README", + "What plumbline is, how to run it, and what it does not do.", + ), + Doc( + "METHODOLOGY.md", + "methodology", + "Methodology", + "How each figure is computed, and the floor each is reported against.", + ), + Doc( + "docs/example-report.md", + "example-report", + "Example report", + "Unedited output of one mock run: the report the explainer derives its example from.", + ), + Doc("docs/PLAN.md", "plan", "Plan", "What is built, what is deliberately not, and why."), + Doc("CHANGELOG.md", "changelog", "Changelog", "Notable changes per release."), + Doc( + "CONTRIBUTING.md", + "contributing", + "Contributing", + "How to work on the code and what CI checks.", + ), + Doc( + "SECURITY.md", + "security", + "Security", + "How to report a vulnerability, and what the scanners cover.", + ), + Doc( + "datasets/public/README.md", + "dataset", + "Dataset", + "The vendored JevBench fixture: where it comes from and its license.", + ), +) + ECE_LINE = re.compile( r"^- (ECE (?P\d\.\d{4}) over (?P\d+) rows \((?P\d+) equal width bins\), " r"against a calibrated-model floor of (?P\d\.\d{4}) " @@ -170,6 +238,175 @@ def build_example() -> dict[str, Any]: } +def _git(*arguments: str) -> str: + try: + done = subprocess.run( + ["git", *arguments], cwd=ROOT, capture_output=True, text=True, check=True + ) + except (OSError, subprocess.CalledProcessError) as failed: + raise BuildError(f"git {' '.join(arguments)} failed: {failed}") from failed + return done.stdout + + +@dataclass(frozen=True) +class Provenance: + sha: str + built: datetime + #: Hosted docs whose working copy differs from the commit. Always empty in + #: CI; a local build says so on the page rather than claiming the commit. + modified: frozenset[str] + + def line(self, doc: Doc) -> str: + short = self.sha[:7] + at = self.built.strftime("%Y-%m-%d %H:%M UTC") + source = f"https://github.com/{REPO}/blob/{self.sha}/{doc.source}" + commit = f"https://github.com/{REPO}/commit/{self.sha}" + dirty = ( + " plus uncommitted local changes" + if doc.source in self.modified + else "" + ) + return ( + f'Rendered from {html.escape(doc.source)} ' + f'at commit {short}{dirty}, built {at}. ' + f'Markdown source.' + ) + + +def provenance() -> Provenance: + sha = _git("rev-parse", "HEAD").strip() + status = _git("status", "--porcelain", "--", *(doc.source for doc in DOCS)) + modified = frozenset(line[3:].strip() for line in status.splitlines()) + # SOURCE_DATE_EPOCH makes the build reproducible when it is set. + epoch = os.environ.get("SOURCE_DATE_EPOCH") + built = datetime.fromtimestamp(int(epoch), UTC) if epoch else datetime.now(UTC) + return Provenance(sha, built, modified) + + +def render_docs(prov: Provenance) -> dict[str, dict[str, str]]: + """Markdown to HTML fragments, by the vendored renderer under the runner's Node.""" + job = { + "repo": REPO, + "sha": prov.sha, + "tracked": _git("ls-files").splitlines(), + "docs": [ + { + "source": doc.source, + "slug": doc.slug, + "markdown": (ROOT / doc.source).read_text(encoding="utf-8"), + } + for doc in DOCS + ], + } + try: + done = subprocess.run( + ["node", str(RENDERER)], + input=json.dumps(job), + capture_output=True, + text=True, + encoding="utf-8", + ) + except OSError as missing: + raise BuildError(f"could not run node to render the docs: {missing}") from missing + if done.returncode != 0: + raise BuildError(f"the docs did not render:\n{done.stderr.strip()}") + rendered: dict[str, dict[str, str]] = json.loads(done.stdout) + return rendered + + +def _nav(current: str | None, up: str) -> str: + items = [f'
  • The ECE floor
  • '] + for doc in DOCS: + mark = ' aria-current="page"' if doc.slug == current else "" + items.append(f'
  • {html.escape(doc.label)}
  • ') + joined = "\n ".join(items) + return f'' + + +# The explainer's plumb-bob icon, inline so the page makes no request for it. +ICON = ( + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E" + "%3Cpath d='M8 1v9' stroke='%23555' stroke-width='1.5'/%3E" + "%3Cpath d='M5 10h6l-3 5z' fill='%23555'/%3E%3C/svg%3E" +) + +PAGE = """ + + + + +{title} | plumbline + + + + + + + + +
    +

    plumbline

    +{nav} +
    +
    +{body} +
    +
    +

    Every page here is rendered from the repository at deploy time; none is edited by hand. +Source on GitHub, Apache-2.0 licensed. +No analytics, no trackers, no external requests.

    +
    + + +""" + + +def write_docs(out: Path, prov: Provenance, rendered: dict[str, dict[str, str]]) -> None: + docs = out / "docs" + docs.mkdir() + for doc in DOCS: + shutil.copyfile(ROOT / doc.source, docs / f"{doc.slug}.md") + body = ( + f'

    {prov.line(doc)}

    \n' + f'
    \n{rendered[doc.slug]["html"]}
    ' + ) + page = PAGE.format( + title=html.escape(doc.label), + description=html.escape(doc.blurb, quote=True), + nav=_nav(doc.slug, "../"), + body=body, + repo=REPO, + icon=ICON, + ) + (docs / f"{doc.slug}.html").write_text(page, encoding="utf-8") + + listing = "\n".join( + f'
  • {html.escape(doc.label)} ' + f'{html.escape(doc.source)}
    ' + f"{html.escape(doc.blurb)}
  • " + for doc in DOCS + ) + at = prov.built.strftime("%Y-%m-%d %H:%M UTC") + index = ( + '
    \n

    Documentation

    \n' + "

    The repository's own markdown, rendered from commit " + f'{prov.sha[:7]} ' + f"at {at}.

    \n" + f'
      \n{listing}\n
    \n
    ' + ) + (docs / "index.html").write_text( + PAGE.format( + title="Documentation", + description="plumbline's documentation, rendered from the repository.", + nav=_nav(None, "../"), + body=index, + repo=REPO, + icon=ICON, + ), + encoding="utf-8", + ) + + def main() -> int: parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) parser.add_argument("--out", type=Path, default=ROOT / "_site", help="output directory") @@ -183,14 +420,19 @@ def main() -> int: try: example = build_example() + prov = provenance() + rendered = render_docs(prov) except BuildError as problem: print(f"site build refused: {problem}", file=sys.stderr) return 1 if out.exists(): shutil.rmtree(out) - shutil.copytree(SITE, out) + # vendor/ holds the markdown renderer, which runs here at build time; the + # pages it produces need no script, so it is not shipped. + shutil.copytree(SITE, out, ignore=shutil.ignore_patterns("vendor")) (out / "example-run.json").write_text(json.dumps(example, indent=1) + "\n", encoding="utf-8") + write_docs(out, prov, rendered) print(f"site assembled in {out}") return 0 diff --git a/scripts/render_docs.mjs b/scripts/render_docs.mjs new file mode 100644 index 0000000..91c87a6 --- /dev/null +++ b/scripts/render_docs.mjs @@ -0,0 +1,252 @@ +// Render the repository's markdown docs to HTML fragments for the site. +// +// Called by scripts/build_site.py, which owns the page template. It runs on the +// runner's own Node with the standard library and one vendored file, +// site/vendor/markdown-it/markdown-it.min.js; nothing is installed. +// +// Input, on stdin, as JSON: +// { repo, sha, tracked: [paths], docs: [{ source, slug, markdown }] } +// Output, on stdout, as JSON: { slug: { html } }. +// +// Rendering happens here, at build time, not in the browser: the pages need no +// script at all, and every rule below fails the build instead of degrading on +// a reader's screen. The rules: +// +// - Raw HTML in markdown is refused unless it is one of a handful of literal +// tags (ALLOWED_TAGS). There is no sanitizer to get wrong, only an allowlist +// of exact strings, so markdown content cannot put a script on the site. +// - A relative link to another hosted doc becomes a link to that doc's page, +// and its #fragment must name a heading that exists there. +// - A relative link to any other tracked file becomes a GitHub link to that +// file at the commit being built, so it shows the code the page describes. +// - A relative link to anything else fails the build. +// - An image from another origin is rendered as its alt text, so the site +// makes no third-party request. +// +// node scripts/render_docs.mjs --self-test + +import { createHash } from "node:crypto"; +import { readFileSync } from "node:fs"; +import { createRequire } from "node:module"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const VENDORED = path.join(here, "..", "site", "vendor", "markdown-it", "markdown-it.min.js"); + +// markdown-it 15.0.2, dist/browser/markdown-it.umd.min.js from the npm tarball +// whose integrity the registry states. site/vendor/markdown-it/README.md says +// how to update it; change this hash in the same commit. +const VENDORED_SHA256 = "635972b985228e8af9f0143647c68616b7a3bb09f6946e7e4a52e43dcf5e7be5"; + +// Exact tag strings, not patterns: README's collapsible install sections. +const ALLOWED_TAGS = new Set([ + "
    ", + "
    ", + "
    ", + "", + "", + "", + "", +]); + +const SCHEME = /^[a-z][a-z0-9+.-]*:/i; + +class RenderError extends Error {} + +function loadMarkdownIt() { + const bytes = readFileSync(VENDORED); + const actual = createHash("sha256").update(bytes).digest("hex"); + if (actual !== VENDORED_SHA256) { + throw new RenderError( + `${path.relative(process.cwd(), VENDORED)} has sha256 ${actual}, expected ${VENDORED_SHA256}. ` + + "Update the pinned hash only together with a deliberate vendor update.", + ); + } + return createRequire(import.meta.url)(VENDORED); +} + +// GitHub's heading anchors (github-slugger), so a #fragment that works on +// github.com works here too. +function slugger() { + const seen = new Map(); + return (text) => { + const base = text.toLowerCase().replace(/[^\p{L}\p{M}\p{N}\p{Pc} -]/gu, "").replace(/ /g, "-"); + let slug = base; + let count = seen.get(base) ?? 0; + while (seen.has(slug)) slug = `${base}-${++count}`; + seen.set(base, count); + seen.set(slug, 0); + return slug; + }; +} + +function inlineText(token) { + return (token.children ?? []) + .filter((child) => child.type === "text" || child.type === "code_inline") + .map((child) => child.content) + .join(""); +} + +// Raw HTML is emitted verbatim, so this validates rather than sanitizes: every +// "<" in it must open one of the exact allowed tags, or the build fails. +function checkHtml(content, where, problems) { + for (let at = content.indexOf("<"); at !== -1; at = content.indexOf("<", at + 1)) { + const close = content.indexOf(">", at); + const tag = close === -1 ? content.slice(at) : content.slice(at, close + 1); + if (!ALLOWED_TAGS.has(tag.toLowerCase())) { + problems.push(`${where}: raw HTML ${JSON.stringify(tag)} is not on the allowlist`); + } + } +} + +// The line a token starts on, for error messages. +function lineOf(token, doc) { + return token.map ? `${doc.source}:${token.map[0] + 1}` : doc.source; +} + +export function render(job) { + const markdownit = loadMarkdownIt(); + const md = markdownit({ html: true, linkify: false, typographer: false }); + const tracked = new Set(job.tracked); + const trackedDirs = new Set(); + for (const file of job.tracked) { + for (let dir = path.posix.dirname(file); dir !== "."; dir = path.posix.dirname(dir)) { + trackedDirs.add(dir); + } + } + const bySource = new Map(job.docs.map((doc) => [doc.source, doc])); + const blob = (kind, target) => `https://github.com/${job.repo}/${kind}/${job.sha}/${target}`; + + // First pass: parse everything and collect heading anchors, so links can be + // checked against the headings of the doc they point into. + const parsed = new Map(); + for (const doc of job.docs) { + const tokens = md.parse(doc.markdown, {}); + const slug = slugger(); + const anchors = new Set(); + tokens.forEach((token, i) => { + if (token.type !== "heading_open") return; + const text = inlineText(tokens[i + 1]); + const id = slug(text); + token.attrSet("id", id); + anchors.add(id); + }); + parsed.set(doc.source, { tokens, anchors }); + } + + const problems = []; + + function rewrite(href, doc, where) { + if (href.startsWith("//") || SCHEME.test(href)) return href; + const [target, fragment] = href.split("#", 2); + if (target === "") { + if (!parsed.get(doc.source).anchors.has(fragment)) { + problems.push(`${where}: #${fragment} names no heading in ${doc.source}`); + } + return href; + } + const resolved = target.startsWith("/") + ? path.posix.normalize(target.slice(1)) + : path.posix.normalize(path.posix.join(path.posix.dirname(doc.source), target)); + const clean = resolved.replace(/\/$/, ""); + const hosted = bySource.get(clean); + if (hosted) { + if (fragment !== undefined && !parsed.get(clean).anchors.has(fragment)) { + problems.push(`${where}: #${fragment} names no heading in ${clean}`); + } + return `${hosted.slug}.html${fragment !== undefined ? `#${fragment}` : ""}`; + } + const suffix = fragment !== undefined ? `#${fragment}` : ""; + if (tracked.has(clean)) return blob("blob", clean) + suffix; + if (trackedDirs.has(clean)) return blob("tree", clean) + suffix; + problems.push(`${where}: ${href} resolves to ${clean}, which is neither a hosted doc nor a tracked file`); + return href; + } + + const out = {}; + for (const doc of job.docs) { + const { tokens } = parsed.get(doc.source); + for (const token of tokens) { + const where = lineOf(token, doc); + if (token.type === "html_block") checkHtml(token.content, where, problems); + for (const child of token.children ?? []) { + if (child.type === "html_inline") checkHtml(child.content, where, problems); + if (child.type === "link_open") { + child.attrSet("href", rewrite(child.attrGet("href"), doc, where)); + } + if (child.type === "image") { + const src = child.attrGet("src"); + if (src.startsWith("//") || SCHEME.test(src)) { + // Keep the words, drop the request. + child.type = "text"; + child.content = child.content || inlineText(child); + child.children = null; + } else { + problems.push(`${where}: image ${src} is not copied to the site; link it instead`); + } + } + } + } + out[doc.slug] = { html: md.renderer.render(tokens, md.options, {}) }; + } + + if (problems.length) throw new RenderError(problems.join("\n")); + return out; +} + +function selfTest() { + const job = (markdown, extra = []) => ({ + repo: "o/r", + sha: "abc", + tracked: ["a.md", "src/x.py", ...extra], + docs: [ + { source: "a.md", slug: "a", markdown }, + { source: "docs/b.md", slug: "b", markdown: "# B\n\n## Two words\n" }, + ], + }); + const refuses = (markdown, pattern) => { + try { + render(job(markdown)); + } catch (error) { + if (pattern.test(error.message)) return; + throw new Error(`refused for the wrong reason: ${error.message}`); + } + throw new Error(`accepted what it should refuse: ${JSON.stringify(markdown)}`); + }; + const html = (markdown) => render(job(markdown)).a.html; + const expect = (condition, what) => { + if (!condition) throw new Error(`self-test failed: ${what}`); + }; + + refuses("\n", /not on the allowlist/); + refuses("hi \n", /not on the allowlist/); + refuses('
    \n', /not on the allowlist/); + refuses("
    \nipt>alert(1)\n
    \n", /not on the allowlist/); + refuses("[x](missing.md)\n", /neither a hosted doc nor a tracked file/); + refuses("[x](docs/b.md#nope)\n", /names no heading/); + refuses("# A\n\n[x](#nope)\n", /names no heading/); + refuses("![x](pic.png)\n", /not copied to the site/); + expect(!html("[x](javascript:alert(1))\n").includes("href"), "javascript: is linked"); + expect(html("[x](docs/b.md#two-words)\n").includes('href="b.html#two-words"'), "doc link"); + expect(html("[x](src/x.py)\n").includes('href="https://github.com/o/r/blob/abc/src/x.py"'), "blob"); + expect(html("[x](src)\n").includes('href="https://github.com/o/r/tree/abc/src"'), "tree"); + expect(!html("[![CI](https://e.x/b.svg)](https://e.x)\n").includes("\nPS\n\nx\n\n
    \n").includes("
    "), "allowlist"); + console.log("render_docs self-test: 15 cases pass"); +} + +if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + try { + if (process.argv.includes("--self-test")) { + selfTest(); + } else { + const job = JSON.parse(readFileSync(0, "utf8")); + process.stdout.write(JSON.stringify(render(job))); + } + } catch (error) { + process.stderr.write(`${error instanceof RenderError ? "" : error.stack + "\n"}${error.message}\n`); + process.exit(1); + } +} diff --git a/site/base.css b/site/base.css new file mode 100644 index 0000000..c483fcf --- /dev/null +++ b/site/base.css @@ -0,0 +1,61 @@ +/* Shared by the explainer (index.html) and the doc pages (docs/*.html). */ +:root { + --bg: #fbfbf9; + --fg: #1b1b1a; + --muted: #5b5b56; + --line: #d6d5cf; + --panel: #f1f0ec; + --accent: #1f5f8b; + --bar: #9aa3ab; + --mark-measured: #1b1b1a; + --mark-p95: #b3261e; + --warn-bg: #fbf1dc; + --warn-fg: #6a4600; + --ok-bg: #e5f0e8; + --ok-fg: #1d5230; + --error: #b3261e; + --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace; + --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; +} +@media (prefers-color-scheme: dark) { + :root { + --bg: #141413; + --fg: #e7e6e1; + --muted: #a3a29b; + --line: #3a3a36; + --panel: #1e1e1c; + --accent: #7db4dc; + --bar: #5d666e; + --mark-measured: #e7e6e1; + --mark-p95: #f2b8b5; + --warn-bg: #3a2c0e; + --warn-fg: #f1d18f; + --ok-bg: #173022; + --ok-fg: #a9dcb8; + --error: #f2b8b5; + } +} +* { box-sizing: border-box; } +html { -webkit-text-size-adjust: 100%; } +body { margin: 0; background: var(--bg); color: var(--fg); font: 16px/1.55 var(--sans); } +main, header, footer { max-width: 46rem; margin: 0 auto; padding: 0 1rem; } +header { padding-top: 2rem; } +.kicker { font: 600 0.85rem var(--mono); color: var(--muted); margin: 0 0 0.5rem; letter-spacing: 0.02em; } +.kicker a { color: inherit; } +h1 { font-size: 1.65rem; line-height: 1.2; margin: 0 0 0.75rem; } +h2 { font-size: 1.25rem; line-height: 1.3; margin: 0 0 0.75rem; } +h3 { font-size: 1rem; margin: 1.5rem 0 0.5rem; } +p { margin: 0 0 1rem; } +a { color: var(--accent); } +:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +code, .num { font-family: var(--mono); font-size: 0.92em; } +.muted { color: var(--muted); } +.small { font-size: 0.9rem; } +nav ul { list-style: none; padding: 0; margin: 1.25rem 0 2rem; display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; } +nav a { font-size: 0.95rem; } +nav a[aria-current="page"] { color: var(--fg); font-weight: 600; text-decoration: none; } +blockquote { margin: 0 0 1rem; padding: 0.75rem 1rem; border-left: 3px solid var(--line); background: var(--panel); } +blockquote p:last-child { margin: 0; } +footer { padding-bottom: 3rem; border-top: 1px solid var(--line); padding-top: 1.5rem; font-size: 0.9rem; color: var(--muted); } +.skip { position: absolute; left: -999px; } +.skip:focus { left: 1rem; top: 1rem; background: var(--bg); padding: 0.5rem; z-index: 1; } diff --git a/site/docs.css b/site/docs.css new file mode 100644 index 0000000..1862ab9 --- /dev/null +++ b/site/docs.css @@ -0,0 +1,23 @@ +/* The doc pages: markdown rendered at build time by scripts/render_docs.mjs. */ +.provenance { font-size: 0.85rem; color: var(--muted); border: 1px solid var(--line); border-radius: 4px; padding: 0.5rem 0.75rem; margin: 0 0 2rem; overflow-wrap: anywhere; } +.prose { padding-bottom: 2rem; overflow-wrap: break-word; } +.prose h1 { margin-top: 0; } +.prose h2 { margin-top: 2.25rem; padding-top: 1rem; border-top: 1px solid var(--line); } +.prose h3, .prose h4 { margin-top: 1.75rem; } +.prose h2, .prose h3, .prose h4 { scroll-margin-top: 1rem; } +.prose ul, .prose ol { padding-left: 1.4rem; margin: 0 0 1rem; } +.prose li { margin-bottom: 0.3rem; } +.prose li > p { margin-bottom: 0.4rem; } +.prose hr { border: 0; border-top: 1px solid var(--line); margin: 2rem 0; } +.prose code { background: var(--panel); padding: 0.05rem 0.3rem; border-radius: 3px; overflow-wrap: anywhere; } +.prose pre { background: var(--panel); border: 1px solid var(--line); border-radius: 4px; padding: 0.75rem 1rem; overflow-x: auto; margin: 0 0 1rem; line-height: 1.45; } +.prose pre code { background: none; padding: 0; font-size: 0.85rem; overflow-wrap: normal; } +.prose table { display: block; overflow-x: auto; border-collapse: collapse; margin: 0 0 1rem; font-size: 0.9rem; max-width: 100%; } +.prose th, .prose td { padding: 0.35rem 0.6rem; border: 1px solid var(--line); text-align: left; vertical-align: top; } +.prose th { background: var(--panel); font-weight: 600; } +.prose details { border: 1px solid var(--line); border-radius: 4px; padding: 0.5rem 0.75rem; margin: 0 0 1rem; } +.prose summary { cursor: pointer; } +.prose details[open] > summary { margin-bottom: 0.5rem; } +.doc-list { padding-left: 0; list-style: none; } +.doc-list li { margin-bottom: 1rem; } +.doc-list a { font-weight: 600; } diff --git a/site/index.html b/site/index.html index ff184e6..6f4679e 100644 --- a/site/index.html +++ b/site/index.html @@ -7,64 +7,10 @@ + +

    plumbline

    A calibration claim has a floor

    @@ -135,6 +81,7 @@

    A calibration claim has a floor

  • Worked example
  • Sample-size planner
  • What computes this
  • +
  • Documentation
  • Repository
  • @@ -204,7 +151,7 @@

    Calibrated-model floor

    Worked example: the 105-row report

    -

    The repository's example report +

    The repository's example report prints this line:

    Loading the example...

    Below, this page derives that line from the 105 rows behind it, rather than quoting it.

    @@ -340,7 +287,7 @@

    What computes these numbers

    plumbline measures whether a decision model's probabilities are trustworthy on your own labeled - data. It is not a leaderboard. Source on GitHub, MIT licensed. + data. It is not a leaderboard. Documentation. Source on GitHub, Apache-2.0 licensed. No analytics, no trackers, no external requests.

    diff --git a/site/vendor/markdown-it/LICENSE b/site/vendor/markdown-it/LICENSE new file mode 100644 index 0000000..7ffa058 --- /dev/null +++ b/site/vendor/markdown-it/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/site/vendor/markdown-it/README.md b/site/vendor/markdown-it/README.md new file mode 100644 index 0000000..4907ca4 --- /dev/null +++ b/site/vendor/markdown-it/README.md @@ -0,0 +1,35 @@ +# Vendored: markdown-it + +`markdown-it.min.js` is markdown-it 15.0.2's browser build, +`dist/browser/markdown-it.umd.min.js`, taken unmodified from the npm tarball +`https://registry.npmjs.org/markdown-it/-/markdown-it-15.0.2.tgz`. The tarball +matched the registry's stated integrity, +`sha512-q4IGxMv56jCqT4OCRCADBoDP3LO4MhmTXjFbphHPXs4g3j9Xg5RDnxqN8IF/3vIWEU+VCnUq+7JUg/cfy2E6Qw==`. +The file's own sha256 is pinned in `scripts/render_docs.mjs`, which refuses to +run if it changes. + +- `LICENSE` is markdown-it's MIT license. +- `THIRD-PARTY-LICENSES` holds the licenses of the packages the browser build + inlines: mdurl, entities (BSD-2-Clause), uc.micro, linkify-it, and + punycode.js. + +## What it is used for + +`scripts/render_docs.mjs` runs it under the CI runner's own Node, at build time, +to turn the repository's markdown docs into the site's doc pages. It is not +shipped to the site: the pages it produces need no script. It was chosen because +it is maintained, has no install step once vendored, escapes raw HTML unless +told otherwise, and refuses `javascript:`, `vbscript:`, `file:`, and non-image +`data:` link targets. The build turns raw HTML on only to check it against an +allowlist of exact tags and fail on anything else. + +## Updating it + +1. Download the new version's tarball from the registry and check it against + the `dist.integrity` the registry states for that version. +2. Replace `markdown-it.min.js` with the tarball's + `dist/browser/markdown-it.umd.min.js`, and `LICENSE` with its `LICENSE`. + Refresh `THIRD-PARTY-LICENSES` if the bundled dependencies changed. +3. Update the version, the integrity above, and `VENDORED_SHA256` in + `scripts/render_docs.mjs`, in the same commit. +4. Run `node scripts/render_docs.mjs --self-test` and the site build. diff --git a/site/vendor/markdown-it/THIRD-PARTY-LICENSES b/site/vendor/markdown-it/THIRD-PARTY-LICENSES new file mode 100644 index 0000000..cd461f4 --- /dev/null +++ b/site/vendor/markdown-it/THIRD-PARTY-LICENSES @@ -0,0 +1,148 @@ +Third-party code bundled into markdown-it.min.js +================================================= + +markdown-it 15.0.2's browser build (dist/browser/markdown-it.umd.min.js) inlines +the packages below. Their license texts follow, as each package publishes it. + + +mdurl 2.1.0 (MIT) +----------------- + +Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +.parse() is based on Joyent's node.js `url` code: + +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + + +entities 8.1.0 (BSD-2-Clause) +----------------------------- + +Copyright (c) Felix Böhm +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +uc.micro 3.0.0 (MIT) +-------------------- + +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +linkify-it 6.1.0 (MIT) +---------------------- + +Copyright (c) 2015 Vitaly Puzrin. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + +punycode.js 2.3.1 (MIT) +----------------------- + +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/site/vendor/markdown-it/markdown-it.min.js b/site/vendor/markdown-it/markdown-it.min.js new file mode 100644 index 0000000..839f325 --- /dev/null +++ b/site/vendor/markdown-it/markdown-it.min.js @@ -0,0 +1,14 @@ +(function(e,t){typeof exports==`object`&&typeof module<`u`?module.exports=t():typeof define==`function`&&define.amd?define([],t):(e=typeof globalThis<`u`?globalThis:e||self,e.markdownit=t())})(this,function(){var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r},n={};function r(e){let t=n[e];if(t)return t;t=n[e]=[];for(let e=0;e<128;e++){let n=String.fromCharCode(e);t.push(n)}for(let n=0;n=55296&&e<=57343?`���`:String.fromCharCode(e),r+=6;continue}}if((a&248)==240&&r+91114111?t+=`����`:(e-=65536,t+=String.fromCharCode(55296+(e>>10),56320+(e&1023))),r+=9;continue}}t+=`�`}return t})}i.defaultChars=`;/?:@&=+$,#`,i.componentChars=``;var a={};function o(e){let t=a[e];if(t)return t;t=a[e]=[];for(let e=0;e<128;e++){let n=String.fromCharCode(e);/^[0-9a-z]$/i.test(n)?t.push(n):t.push(`%`+(`0`+e.toString(16).toUpperCase()).slice(-2))}for(let n=0;n=55296&&o<=57343){if(o>=55296&&o<=56319&&t+1=56320&&n<=57343){i+=encodeURIComponent(e[t]+e[t+1]),t++;continue}}i+=`%EF%BF%BD`;continue}i+=encodeURIComponent(e[t])}return i}s.defaultChars=`;/?:@&=+$,-_.!~*'()#`,s.componentChars=`-_.!~*'()`;function c(e){let t=``;return t+=e.protocol||``,t+=e.slashes?`//`:``,t+=e.auth?e.auth+`@`:``,e.hostname&&e.hostname.indexOf(`:`)!==-1?t+=`[`+e.hostname+`]`:t+=e.hostname||``,t+=e.port?`:`+e.port:``,t+=e.pathname||``,t+=e.search||``,t+=e.hash||``,t}function l(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}var u=/^([a-z0-9.+-]+:)/i,d=/:[0-9]*$/,f=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,p=[`%`,`/`,`?`,`;`,`#`,`'`,`{`,`}`,`|`,`\\`,`^`,"`",`<`,`>`,`"`,"`",` `,`\r`,` +`,` `],m=[`/`,`?`,`#`],h=255,g=/^[+a-z0-9A-Z_-]{0,63}$/,_=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,v={javascript:!0,"javascript:":!0},y={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};function b(e,t){if(e&&e instanceof l)return e;let n=new l;return n.parse(e,t),n}l.prototype.parse=function(e,t){let n,r,i,a=e;if(a=a.trim(),!t&&e.split(`#`).length===1){let e=f.exec(a);if(e)return this.pathname=e[1],e[2]&&(this.search=e[2]),this}let o=u.exec(a);if(o&&(o=o[0],n=o.toLowerCase(),this.protocol=o,a=a.substr(o.length)),(t||o||a.match(/^\/\/[^@\/]+@[^@\/]+/))&&(i=a.substr(0,2)===`//`,i&&!(o&&v[o])&&(a=a.substr(2),this.slashes=!0)),!v[o]&&(i||o&&!y[o])){let e=-1;for(let t=0;t127?r+=`x`:r+=n[e];if(!r.match(g)){let r=e.slice(0,t),i=e.slice(t+1),o=n.match(_);o&&(r.push(o[1]),i.unshift(o[2])),i.length&&(a=i.join(`.`)+a),this.hostname=r.join(`.`);break}}}}this.hostname.length>h&&(this.hostname=``),o&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}let s=a.indexOf(`#`);s!==-1&&(this.hash=a.substr(s),a=a.slice(0,s));let c=a.indexOf(`?`);return c!==-1&&(this.search=a.substr(c),a=a.slice(0,c)),a&&(this.pathname=a),y[n]&&this.hostname&&!this.pathname&&(this.pathname=``),this},l.prototype.parseHost=function(e){let t=d.exec(e);t&&(t=t[0],t!==`:`&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)};var ee=t({decode:()=>i,encode:()=>s,format:()=>c,parse:()=>b}),te=t({Any:()=>x,Cc:()=>ne,Cf:()=>re,P:()=>S,S:()=>ie,Z:()=>ae}),x=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,ne=/[\0-\x1F\x7F-\x9F]/,re=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/,S=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F]/,ie=/[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C1\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2429\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E5\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD803[\uDD8E\uDD8F\uDED1-\uDED8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDC00-\uDCEF\uDCFA-\uDCFC\uDD00-\uDEB3\uDEBA-\uDED0\uDEE0-\uDEF0\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED8\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0-\uDCBB\uDCC0\uDCC1\uDCD0-\uDCD8\uDD00-\uDE57\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF-\uDEF8\uDF00-\uDF92\uDF94-\uDFEF\uDFFA]/,ae=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/,oe=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function se(e){var t;return e>=55296&&e<=57343||e>1114111?65533:(t=oe.get(e))==null?e:t}function ce(e){let t=atob(e),n=t.length&-2,r=new Uint16Array(n/2);for(let e=0,i=0;e=E.ZERO&&e<=E.NINE}function me(e){return e>=E.UPPER_A&&e<=E.UPPER_F||e>=E.LOWER_A&&e<=E.LOWER_F}function he(e){return e>=E.UPPER_A&&e<=E.UPPER_Z||e>=E.LOWER_A&&e<=E.LOWER_Z||pe(e)}function ge(e){return e===E.EQUALS||he(e)}var D;(function(e){e[e.EntityStart=0]=`EntityStart`,e[e.NumericStart=1]=`NumericStart`,e[e.NumericDecimal=2]=`NumericDecimal`,e[e.NumericHex=3]=`NumericHex`,e[e.NamedEntity=4]=`NamedEntity`})(D||(D={}));var O;(function(e){e[e.Legacy=0]=`Legacy`,e[e.Strict=1]=`Strict`,e[e.Attribute=2]=`Attribute`})(O||(O={}));var _e=class{constructor(e,t,n){T(this,`decodeTree`,void 0),T(this,`emitCodePoint`,void 0),T(this,`errors`,void 0),T(this,`state`,D.EntityStart),T(this,`consumed`,1),T(this,`result`,0),T(this,`treeIndex`,0),T(this,`excess`,1),T(this,`decodeMode`,O.Strict),T(this,`runConsumed`,0),this.decodeTree=e,this.emitCodePoint=t,this.errors=n}startEntity(e){this.decodeMode=e,this.state=D.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1,this.runConsumed=0}write(e,t){switch(this.state){case D.EntityStart:return e.charCodeAt(t)===E.NUM?(this.state=D.NumericStart,this.consumed+=1,this.stateNumericStart(e,t+1)):(this.state=D.NamedEntity,this.stateNamedEntity(e,t));case D.NumericStart:return this.stateNumericStart(e,t);case D.NumericDecimal:return this.stateNumericDecimal(e,t);case D.NumericHex:return this.stateNumericHex(e,t);case D.NamedEntity:return this.stateNamedEntity(e,t)}}stateNumericStart(e,t){return t>=e.length?-1:(e.charCodeAt(t)|fe)===E.LOWER_X?(this.state=D.NumericHex,this.consumed+=1,this.stateNumericHex(e,t+1)):(this.state=D.NumericDecimal,this.stateNumericDecimal(e,t))}stateNumericHex(e,t){for(;t>14;for(;t>7;if(this.runConsumed===0){let n=r&C.JUMP_TABLE;if(e.charCodeAt(t)!==n)return this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}for(;this.runConsumed=e.length)return-1;let r=this.runConsumed-1,i=n[this.treeIndex+1+(r>>1)],a=r%2==0?i&255:i>>8&255;if(e.charCodeAt(t)!==a)return this.runConsumed=0,this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}this.runConsumed=0,this.treeIndex+=1+(a>>1),r=n[this.treeIndex],i=(r&C.VALUE_LENGTH)>>14}if(t>=e.length)break;let a=e.charCodeAt(t);if(a===E.SEMI&&i!==0&&(r&C.FLAG13)!==0)return this.emitNamedEntityData(this.treeIndex,i,this.consumed+this.excess);if(this.treeIndex=ye(n,r,this.treeIndex+Math.max(1,i),a),this.treeIndex<0)return this.result===0||this.decodeMode===O.Attribute&&(i===0||ge(a))?0:this.emitNotTerminatedNamedEntity();if(r=n[this.treeIndex],i=(r&C.VALUE_LENGTH)>>14,i!==0){if(a===E.SEMI)return this.emitNamedEntityData(this.treeIndex,i,this.consumed+this.excess);this.decodeMode!==O.Strict&&(r&C.FLAG13)===0&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}t++,this.excess++}return-1}emitNotTerminatedNamedEntity(){var e;let{result:t,decodeTree:n}=this,r=(n[t]&C.VALUE_LENGTH)>>14;return this.emitNamedEntityData(t,r,this.consumed),(e=this.errors)==null||e.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(e,t,n){let{decodeTree:r}=this;return this.emitCodePoint(t===1?r[e]&~(C.VALUE_LENGTH|C.FLAG13):r[e+1],n),t===3&&this.emitCodePoint(r[e+2],n),n}end(){switch(this.state){case D.NamedEntity:return this.result!==0&&(this.decodeMode!==O.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case D.NumericDecimal:return this.emitNumericEntity(0,2);case D.NumericHex:return this.emitNumericEntity(0,3);case D.NumericStart:var e;return(e=this.errors)==null||e.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case D.EntityStart:return 0}}};function ve(e){let t=``,n=new _e(e,e=>t+=String.fromCodePoint(e));return function(e,r){let i=0,a=0;for(;(a=e.indexOf(`&`,a))>=0;){t+=e.slice(i,a),n.startEntity(r);let o=n.write(e,a+1);if(o<0){i=a+n.end();break}i=a+o,a=o===0?i+1:i}let o=t+e.slice(i);return t=``,o}}function ye(e,t,n,r){let i=(t&C.BRANCH_LENGTH)>>7,a=t&C.JUMP_TABLE;if(i===0)return a!==0&&r===a?n:-1;if(a){let t=r-a;return t<0||t>=i?-1:e[n+t]-1}let o=i+1>>1,s=0,c=i-1;for(;s<=c;){let t=s+c>>>1,i=e[n+(t>>1)]>>(t&1)*8&255;if(ir)c=t-1;else return e[n+o+t]}return-1}var be=ve(le);function xe(e){return be(e,O.Strict)}var Se=t({arrayReplaceAt:()=>we,asciiTrim:()=>L,callable:()=>Ce,escapeHtml:()=>j,escapeRE:()=>Ie,fromCodePoint:()=>k,isMdAsciiPunct:()=>F,isPunctChar:()=>Le,isPunctCharCode:()=>P,isSpace:()=>M,isValidEntityCode:()=>Te,isWhiteSpace:()=>N,lib:()=>ze,normalizeReference:()=>I,unescapeAll:()=>A,unescapeMd:()=>Ae});function Ce(e){let t=function(...n){return Reflect.construct(e,n,new.target&&new.target!==t?new.target:e)};return Object.defineProperty(t,"name",{value:e.name}),Object.setPrototypeOf(t,e),t.prototype=e.prototype,t}function we(e,t,n){return[].concat(e.slice(0,t),n,e.slice(t+1))}function Te(e){return!(e>=55296&&e<=57343||e>=64976&&e<=65007||(e&65535)==65535||(e&65535)==65534||e>=0&&e<=8||e===11||e>=14&&e<=31||e>=127&&e<=159||e>1114111)}function k(e){if(e>65535){e-=65536;let t=55296+(e>>10),n=56320+(e&1023);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var Ee=/\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g,De=RegExp(`${Ee.source}|&([a-z#][a-z0-9]{1,31});`,`gi`),Oe=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i;function ke(e,t){if(t.charCodeAt(0)===35&&Oe.test(t)){let n=t[1].toLowerCase()===`x`?parseInt(t.slice(2),16):parseInt(t.slice(1),10);return Te(n)?k(n):e}let n=xe(e);return n===e?e:n}function Ae(e){return e.indexOf(`\\`)<0?e:e.replace(Ee,`$1`)}function A(e){return e.indexOf(`\\`)<0&&e.indexOf(`&`)<0?e:e.replace(De,function(e,t,n){return t||ke(e,n)})}var je=/[&<>"]/,Me=/[&<>"]/g,Ne={"&":`&`,"<":`<`,">":`>`,'"':`"`};function Pe(e){return Ne[e]}function j(e){return je.test(e)?e.replace(Me,Pe):e}var Fe=/[.?*+^$[\]\\(){}|-]/g;function Ie(e){return e.replace(Fe,`\\$&`)}function M(e){switch(e){case 9:case 32:return!0}return!1}function N(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function Le(e){return S.test(e)||ie.test(e)}function P(e){return Le(k(e))}function F(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function I(e){return e=e.trim().replace(/\s+/g,` `),e.toLowerCase().toUpperCase()}function Re(e){return e===32||e===9||e===10||e===13}function L(e){let t=0;for(;t=t&&Re(e.charCodeAt(n));n--);return e.slice(t,n+1)}var ze={mdurl:ee,ucmicro:te};function Be(e,t,n){let r,i,a,o,s=e.posMax,c=e.pos;for(e.pos=t+1,r=1;e.pos32))return a;if(r===41){if(o===0)break;o--}i++}return t===i||o!==0?a:(a.str=A(e.slice(t,i)),a.pos=i,a.ok=!0,a)}function He(e,t,n,r){let i,a=t,o={ok:!1,can_continue:!1,pos:0,str:``,marker:0};if(r)o.str=r.str,o.marker=r.marker;else{if(a>=n)return o;let r=e.charCodeAt(a);if(r!==34&&r!==39&&r!==40)return o;t++,a++,r===40&&(r=41),o.marker=r}for(;aVe,parseLinkLabel:()=>Be,parseLinkTitle:()=>He}),R=class{constructor(e,t,n){T(this,`map`,null),T(this,`level`,0),T(this,`children`,null),T(this,`content`,``),T(this,`markup`,``),T(this,`info`,``),T(this,`block`,!1),T(this,`hidden`,!1),this.type=e,this.tag=t,this.attrs=null,this.nesting=n,this.meta=null}attrIndex(e){if(!this.attrs)return-1;let t=this.attrs;for(let n=0,r=t.length;n=0&&(n=this.attrs[t][1]),n}attrJoin(e,t){let n=this.attrIndex(e);n<0?this.attrPush([e,t]):this.attrs[n][1]=`${this.attrs[n][1]} ${t}`}},z=class{constructor(){T(this,`__rules__`,[]),T(this,`__cache__`,null)}__find__(e){for(let t=0;t{t.enabled&&t.alt.forEach(t=>{t&&e.add(t)})}),this.__cache__=Object.create(null),this.__cache__[``]=[],this.__rules__.forEach(e=>{e.enabled&&this.__cache__[``].push(e.fn)}),e.forEach(e=>{this.__cache__[e]=[],this.__rules__.forEach(t=>{t.enabled&&t.alt.indexOf(e)>=0&&this.__cache__[e].push(t.fn)})})}at(e,t,n={}){let r=this.__find__(e);if(r===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__[r].fn=t,this.__rules__[r].alt=n.alt||[],this.__cache__=null}before(e,t,n,r={}){let i=this.__find__(e);if(i===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__.splice(i,0,{name:t,enabled:!0,fn:n,alt:r.alt||[]}),this.__cache__=null}after(e,t,n,r={}){let i=this.__find__(e);if(i===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__.splice(i+1,0,{name:t,enabled:!0,fn:n,alt:r.alt||[]}),this.__cache__=null}push(e,t,n={}){this.__rules__.push({name:e,enabled:!0,fn:t,alt:n.alt||[]}),this.__cache__=null}enable(e,t=!1){Array.isArray(e)||(e=[e]);let n=[];return e.forEach(e=>{let r=this.__find__(e);if(r<0){if(t)return;throw Error(`Rules manager: invalid rule name ${e}`)}this.__rules__[r].enabled=!0,n.push(e)}),this.__cache__=null,n}enableOnly(e,t=!1){Array.isArray(e)||(e=[e]),this.__rules__.forEach(e=>{e.enabled=!1}),this.enable(e,t)}disable(e,t=!1){Array.isArray(e)||(e=[e]);let n=[];return e.forEach(e=>{let r=this.__find__(e);if(r<0){if(t)return;throw Error(`Rules manager: invalid rule name ${e}`)}this.__rules__[r].enabled=!1,n.push(e)}),this.__cache__=null,n}getRules(e){return this.__cache__||this.__compile__(),this.__cache__[e]||[]}},B={};B.code_inline=function(e,t,n,r,i){let a=e[t];return`${j(a.content)}`},B.code_block=function(e,t,n,r,i){let a=e[t];return`${j(e[t].content)}\n`},B.fence=function(e,t,n,r,i){let a=e[t],o=a.info?A(a.info).trim():``,s=``,c=``;if(o){let e=o.split(/(\s+)/g);s=e[0],c=e.slice(2).join(``)}let l;if(l=n.highlight&&n.highlight(a.content,s,c)||j(a.content),l.indexOf(`${l}\n`}return`
    ${l}
    \n`},B.image=function(e,t,n,r,i){let a=e[t];return a.attrs[a.attrIndex(`alt`)][1]=i.renderInlineAsText(a.children,n,r),i.renderToken(e,t,n)},B.hardbreak=function(e,t,n){return n.xhtmlOut?`
    +`:`
    +`},B.softbreak=function(e,t,n){return n.breaks?n.xhtmlOut?`
    +`:`
    +`:` +`},B.text=function(e,t){return j(e[t].content)},B.html_block=function(e,t){return e[t].content},B.html_inline=function(e,t){return e[t].content};var We=class{constructor(){T(this,`rules`,Object.assign({},B))}renderAttrs(e){let t,n,r;if(!e.attrs)return``;for(r=``,t=0,n=e.attrs.length;t=0&&e[a].hidden&&e[a].nesting===0;)a--;r.block&&r.nesting!==-1&&a>=0&&e[a].hidden&&e[a].nesting===-1&&(i+=` +`),i+=(r.nesting===-1?` +`:`>`,i}renderInline(e,t,n){let r=``,i=this.rules;for(let a=0,o=e.length;a\s]/i.test(e)}function $e(e){return/^<\/a\s*>/i.test(e)}function et(e){let t=e.tokens;if(e.md.options.linkify)for(let n=0,r=t.length;n=0;t--){let n=r[t];if(n.type===`link_close`){for(t--;r[t].level!==n.level&&r[t].type!==`link_open`;)t--;continue}if(n.type===`html_inline`&&(Qe(n.content)&&a>0&&a--,$e(n.content)&&a++),!(a>0)&&n.type===`text`&&e.md.linkify.test(n.content)){let a=n.content,o=e.md.linkify.match(a),s=[],c=n.level,l=0;o.length>0&&o[0].index===0&&t>0&&r[t-1].type===`text_special`&&(o=o.slice(1));for(let t=0;tl){let t=new e.Token(`text`,``,0);t.content=a.slice(l,u),t.level=c,s.push(t)}let d=new e.Token(`link_open`,`a`,1);d.attrs=[[`href`,r]],d.level=c++,d.markup=`linkify`,d.info=`auto`,s.push(d);let f=new e.Token(`text`,``,0);f.content=i,f.level=c,s.push(f);let p=new e.Token(`link_close`,`a`,-1);p.level=--c,p.markup=`linkify`,p.info=`auto`,s.push(p),l=o[t].lastIndex}if(l0){let e=r.length;for(let t of i)e+=t.nodes.length-1;let a=Array(e),o=0,s=0;i.reverse();for(let e=0;e=0;n--){let r=e[n];r.type===`text`&&!t&&(r.content=r.content.replace(rt,at)),r.type===`link_open`&&r.info===`auto`&&t--,r.type===`link_close`&&r.info===`auto`&&t++}}function st(e){let t=0;for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`text`&&!t&&tt.test(r.content)&&(r.content=r.content.replace(/\+-/g,`±`).replace(/\.{2,}/g,`…`).replace(/([?!])…/g,`$1..`).replace(/([?!]){4,}/g,`$1$1$1`).replace(/,{2,}/g,`,`).replace(/(^|[^-])---(?=[^-]|$)/gm,`$1—`).replace(/(^|\s)--(?=\s|$)/gm,`$1–`).replace(/(^|[^-\s])--(?=[^-\s]|$)/gm,`$1–`)),r.type===`link_open`&&r.info===`auto`&&t--,r.type===`link_close`&&r.info===`auto`&&t++}}function ct(e){let t;if(e.md.options.typographer)for(t=e.tokens.length-1;t>=0;t--)e.tokens[t].type===`inline`&&(nt.test(e.tokens[t].content)&&ot(e.tokens[t].children),tt.test(e.tokens[t].content)&&st(e.tokens[t].children))}var lt=/['"]/,ut=/['"]/g,dt=`’`,ft=1e3;function pt(e,t,n){for(;e.length>n;){let n=e.pop();n.isSingleQuote?t.single=n.prevSameQuoteIdx:t.double=n.prevSameQuoteIdx}}function V(e,t,n,r){e[t]||(e[t]=[]),e[t].push({pos:n,ch:r})}function mt(e,t){let n=``,r=0;t.sort((e,t)=>e.pos-t.pos);for(let i=0;i=0&&!(r[n].level<=c);n--);if(pt(r,i,n+1),s.type!==`text`)continue;let l=s.content,u=0,d=l.length;OUTER:for(;u=0)h=l.charCodeAt(s.index-1);else for(n=o-1;n>=0&&e[n].type!==`softbreak`&&e[n].type!==`hardbreak`;n--)if(e[n].content){h=e[n].content.charCodeAt(e[n].content.length-1);break}let g=32;if(u=48&&h<=57&&(p=f=!1),f&&p&&(f=_,p=v),!f&&!p){m&&V(a,o,s.index,dt);continue}if(p&&(n=m?i.single:i.double,n>=0&&r[n].level===c)){let e=r[n],c,l;m?(c=t.md.options.quotes[2],l=t.md.options.quotes[3]):(c=t.md.options.quotes[0],l=t.md.options.quotes[1]),V(a,o,s.index,l),V(a,e.tokenIdx,e.contentPos,c),pt(r,i,n);continue OUTER}if(f){if(r.length>=ft)return;r.push({tokenIdx:o,contentPos:s.index,isSingleQuote:m,level:c,prevSameQuoteIdx:m?i.single:i.double}),m?i.single=r.length-1:i.double=r.length-1}else p&&m&&V(a,o,s.index,dt)}}Object.keys(a).forEach(function(t){let n=Number(t);e[n].content=mt(e[n].content,a[t])})}function gt(e){if(e.md.options.typographer)for(let t=e.tokens.length-1;t>=0;t--)e.tokens[t].type!==`inline`||!lt.test(e.tokens[t].content)||ht(e.tokens[t].children,e)}function _t(e){let t,n,r=e.length;for(t=0;t0&&this.level++,this.tokens.push(r),r}isEmpty(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]}skipEmptyLines(e){for(let t=this.lineMax;et;)if(!M(this.src.charCodeAt(--e)))return e+1;return e}skipChars(e,t){for(let n=this.src.length;en;)if(t!==this.src.charCodeAt(--e))return e+1;return e}getLines(e,t,n,r){if(e>=t)return``;let i=Array(t-e);for(let a=0,o=e;on?i[a]=Array(e-n+1).join(` `)+this.src.slice(c,l):i[a]=this.src.slice(c,l)}return i.join(``)}},xt=65536;function U(e,t){let n=e.bMarks[t]+e.tShift[t],r=e.eMarks[t];return e.src.slice(n,r)}function St(e){let t=[],n=e.length,r=0,i=e.charCodeAt(r),a=!1,o=0,s=``;for(;rn)return!1;let i=t+1;if(e.sCount[i]=4)return!1;let a=e.bMarks[i]+e.tShift[i];if(a>=e.eMarks[i])return!1;let o=e.src.charCodeAt(a++);if(o!==124&&o!==45&&o!==58||a>=e.eMarks[i])return!1;let s=e.src.charCodeAt(a++);if(s!==124&&s!==45&&s!==58&&!M(s)||o===45&&M(s))return!1;for(;a=4)return!1;l=St(c),l.length&&l[0]===``&&l.shift(),l.length&&l[l.length-1]===``&&l.pop();let d=l.length;if(d===0||d!==u.length)return!1;if(r)return!0;let f=e.parentType;e.parentType=`table`;let p=e.md.block.ruler.getRules(`blockquote`),m=e.push(`table_open`,`table`,1),h=[t,0];m.map=h;let g=e.push(`thead_open`,`thead`,1);g.map=[t,t+1];let _=e.push(`tr_open`,`tr`,1);_.map=[t,t+1];for(let t=0;t=4||(l=St(c),l.length&&l[0]===``&&l.shift(),l.length&&l[l.length-1]===``&&l.pop(),y+=d-l.length,y>xt))break;if(i===t+2){let n=e.push(`tbody_open`,`tbody`,1);n.map=v=[t+2,0]}let a=e.push(`tr_open`,`tr`,1);a.map=[i,i+1];for(let t=0;t=4){r++,i=r;continue}break}e.line=i;let a=e.push(`code_block`,`code`,0);return a.content=e.getLines(t,i,4+e.blkIndent,!1)+` +`,a.map=[t,e.line],!0}function Tt(e,t,n,r){let i=e.bMarks[t]+e.tShift[t],a=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||i+3>a)return!1;let o=e.src.charCodeAt(i);if(o!==126&&o!==96)return!1;let s=i;i=e.skipChars(i,o);let c=i-s;if(c<3)return!1;let l=e.src.slice(s,i),u=e.src.slice(i,a);if(o===96&&u.indexOf(String.fromCharCode(o))>=0)return!1;if(r)return!0;let d=t,f=!1;for(;d++,!(d>=n||(i=s=e.bMarks[d]+e.tShift[d],a=e.eMarks[d],i=4)&&(i=e.skipChars(i,o),!(i-s=4||e.src.charCodeAt(i)!==62)return!1;if(r)return!0;let s=[],c=[],l=[],u=[],d=e.md.block.ruler.getRules(`blockquote`),f=e.parentType;e.parentType=`blockquote`;let p=!1,m;for(m=t;m=a)break;if(e.src.charCodeAt(i++)===62&&!t){let t=e.sCount[m]+1,n,r;e.src.charCodeAt(i)===32?(i++,t++,r=!1,n=!0):e.src.charCodeAt(i)===9?(n=!0,(e.bsCount[m]+t)%4==3?(i++,t++,r=!1):r=!0):n=!1;let o=t;for(s.push(e.bMarks[m]),e.bMarks[m]=i;i=a,c.push(e.bsCount[m]),e.bsCount[m]=e.sCount[m]+1+ +!!n,l.push(e.sCount[m]),e.sCount[m]=o-t,u.push(e.tShift[m]),e.tShift[m]=i-e.bMarks[m];continue}if(p)break;let r=!1;for(let t=0,i=d.length;t`;let _=[t,0];g.map=_,e.md.block.tokenize(e,t,m);let v=e.push(`blockquote_close`,`blockquote`,-1);v.markup=`>`,e.lineMax=o,e.parentType=f,_[1]=e.line;for(let n=0;n=4)return!1;let a=e.bMarks[t]+e.tShift[t],o=e.src.charCodeAt(a++);if(o!==42&&o!==45&&o!==95)return!1;let s=1;for(;a=r)return-1;let a=e.src.charCodeAt(i++);if(a<48||a>57)return-1;for(;;){if(i>=r)return-1;if(a=e.src.charCodeAt(i++),a>=48&&a<=57){if(i-n>=10)return-1;continue}if(a===41||a===46)break;return-1}return i=4||e.listIndent>=0&&e.sCount[c]-e.listIndent>=4&&e.sCount[c]=e.blkIndent&&(u=!0);let d,f,p;if((p=kt(e,c))>=0){if(d=!0,o=e.bMarks[c]+e.tShift[c],f=Number(e.src.slice(o,p-1)),u&&f!==1)return!1}else if((p=Ot(e,c))>=0)d=!1;else return!1;if(u&&e.skipSpaces(p)>=e.eMarks[c])return!1;if(r)return!0;let m=e.src.charCodeAt(p-1),h=e.tokens.length;d?(s=e.push(`ordered_list_open`,`ol`,1),f!==1&&(s.attrs=[[`start`,f]])):s=e.push(`bullet_list_open`,`ul`,1);let g=[c,0];s.map=g,s.markup=String.fromCharCode(m);let _=!1,v=e.md.block.ruler.getRules(`list`),y=e.parentType;for(e.parentType=`list`;c=i?1:r-t,f>4&&(f=1);let h=t+f;s=e.push(`list_item_open`,`li`,1),s.markup=String.fromCharCode(m);let g=[c,0];s.map=g,d&&(s.info=e.src.slice(o,p-1));let y=e.tight,b=e.tShift[c],ee=e.sCount[c],te=e.listIndent;if(e.listIndent=e.blkIndent,e.blkIndent=h,e.tight=!0,e.tShift[c]=u-e.bMarks[c],e.sCount[c]=r,u>=i&&e.isEmpty(c+1)?e.line=Math.min(e.line+2,n):e.md.block.tokenize(e,c,n),(!e.tight||_)&&(l=!1),_=e.line-c>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=te,e.tShift[c]=b,e.sCount[c]=ee,e.tight=y,s=e.push(`list_item_close`,`li`,-1),s.markup=String.fromCharCode(m),c=e.line,g[1]=c,c>=n||e.sCount[c]=4)break;let x=!1;for(let t=0,r=v.length;t=4||e.src.charCodeAt(i)!==91)return!1;function s(t){let n=e.lineMax;if(t>=n||e.isEmpty(t))return null;let r=!1;if(e.sCount[t]-e.blkIndent>3&&(r=!0),e.sCount[t]<0&&(r=!0),!r){let r=e.md.block.ruler.getRules(`reference`),i=e.parentType;e.parentType=`reference`;let a=!1;for(let i=0,o=r.length;i\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*\\/?>`,Ft=`<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>`,It=RegExp(`^(?:${Pt}|${Ft}||<[?][\\s\\S]*?[?]>|]*>|)`),Lt=RegExp(`^(?:${Pt}|${Ft})`),W=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[RegExp(`^|$))`,`i`),/^$/,!0],[RegExp(`${Lt.source}\\s*$`),/^$/,!1]];function Rt(e,t,n,r){let i=e.bMarks[t]+e.tShift[t],a=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||!e.md.options.html||e.src.charCodeAt(i)!==60)return!1;let o=e.src.slice(i,a),s=0;for(;s=4)return!1;let o=e.src.charCodeAt(i);if(o!==35||i>=a)return!1;let s=1;for(o=e.src.charCodeAt(++i);o===35&&i6||ii&&M(e.src.charCodeAt(c-1))&&(a=c),e.line=t+1;let l=e.push(`heading_open`,`h${s}`,1);l.markup=`########`.slice(0,s),l.map=[t,e.line];let u=e.push(`inline`,``,0);u.content=L(e.src.slice(i,a)),u.map=[t,e.line],u.children=[];let d=e.push(`heading_close`,`h${s}`,-1);return d.markup=`########`.slice(0,s),!0}function Bt(e,t,n){let r=e.md.block.ruler.getRules(`paragraph`);if(e.sCount[t]-e.blkIndent>=4)return!1;let i=e.parentType;e.parentType=`paragraph`;let a=0,o,s=t+1;for(;s3)continue;if(e.sCount[s]>=e.blkIndent){let t=e.bMarks[s]+e.tShift[s],n=e.eMarks[s];if(t=n))){a=o===61?1:2;break}}if(e.sCount[s]<0)continue;let t=!1;for(let i=0,a=r.length;i3||e.sCount[a]<0)continue;let t=!1;for(let i=0,o=r.length;i=n||e.sCount[o]=a){e.line=n;break}let t=e.line,c=!1;for(let a=0;a=e.line)throw Error(`block rule didn't increment state.line`);break}if(!c)throw Error(`none of the block rules matched`);e.tight=!s,e.isEmpty(e.line-1)&&(s=!0),o=e.line,o0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],i={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(r),this.tokens_meta.push(i),r}scanDelims(e,t){let n=this.posMax,r=this.src.charCodeAt(e),i;if(e===0)i=32;else if(e===1)i=this.src.charCodeAt(0),(i&63488)==55296&&(i=65533);else if(i=this.src.charCodeAt(e-1),(i&64512)==56320){let t=this.src.charCodeAt(e-2);i=(t&64512)==55296?65536+(t-55296<<10)+(i-56320):65533}else(i&64512)==55296&&(i=65533);let a=e;for(;a=65&&e<=90||e>=97&&e<=122}function qt(e){return e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||e===43||e===45||e===46}function Jt(e,t){if(!e.md.options.linkify||e.linkLevel>0)return!1;let n=e.pos,r=e.posMax;if(n+3>r||e.src.charCodeAt(n)!==58||e.src.charCodeAt(n+1)!==47||e.src.charCodeAt(n+2)!==47)return!1;let i=n-Math.min(10,e.pending.length,n),a=n;for(;a>i&&qt(e.src.charCodeAt(a-1));)a--;if(a===n||!Kt(e.src.charCodeAt(a)))return!1;let o=n-a,s=e.md.linkify.matchAtStart(e.src.slice(a));if(!s)return!1;let c=s.url;if(c.length<=o)return!1;let l=c.length;for(;l>0&&c.charCodeAt(l-1)===42;)l--;l!==c.length&&(c=c.slice(0,l));let u=e.md.normalizeLink(c);if(!e.md.validateLink(u))return!1;if(!t){e.pending=e.pending.slice(0,-o);let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,u]],t.markup=`linkify`,t.info=`auto`;let n=e.push(`text`,``,0);n.content=e.md.normalizeLinkText(c);let r=e.push(`link_close`,`a`,-1);r.markup=`linkify`,r.info=`auto`}return e.pos+=c.length-o,!0}function Yt(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==10)return!1;let r=e.pending.length-1,i=e.posMax;if(!t)if(r>=0&&e.pending.charCodeAt(r)===32)if(r>=1&&e.pending.charCodeAt(r-1)===32){let t=r-1;for(;t>=1&&e.pending.charCodeAt(t-1)===32;)t--;e.pending=e.pending.slice(0,t),e.push(`hardbreak`,`br`,0)}else e.pending=e.pending.slice(0,-1),e.push(`softbreak`,`br`,0);else e.push(`softbreak`,`br`,0);for(n++;n?@[]^_\`{|}~-`.split(``).forEach(function(e){K[e.charCodeAt(0)]=1});function Xt(e,t){let n=e.pos,r=e.posMax;if(e.src.charCodeAt(n)!==92||(n++,n>=r))return!1;let i=e.src.charCodeAt(n);if(i===10){for(t||e.push(`hardbreak`,`br`,0),n++;n=55296&&i<=56319&&n+1=56320&&t<=57343&&(a+=e.src[n+1],n++)}let o=`\\`+a;if(!t){let t=e.push(`text_special`,``,0);t.content=i<256&&K[i]!==0?a:o,t.markup=o,t.info=`escape`}return e.pos=n+1,!0}function Zt(e){let t={},n=0;for(;(n=e.indexOf("`",n))!==-1;){let r=n;for(;e.charCodeAt(++n)===96;);t[n-r]=r}return t}function Qt(e,t){var n;let r=e.pos;if(e.src.charCodeAt(r)!==96)return!1;let i=e.posMax,a=r+1;for(;a=a){let n=a,r;for(;(r=e.src.indexOf("`",n))!==-1&&ri)break;if(n-r===s){if(!t){let t=e.push(`code_inline`,`code`,0);t.markup=o;let n=e.src.slice(a,r).replace(/\n/g,` `);n.startsWith(` `)&&n.endsWith(` `)&&/[^ ]/.test(n)&&(n=n.slice(1,-1)),t.content=n}return e.pos=n,!0}}}return t||(e.pending+=o),e.pos=a,!0}function $t(e,t){let n=e.pos,r=e.src.charCodeAt(n);if(t||r!==126)return!1;let i=e.scanDelims(e.pos,!0),a=i.length,o=String.fromCharCode(r);if(a<2)return!1;let s;a%2&&(s=e.push(`text`,``,0),s.content=o,a--);for(let t=0;t=0;r--){let n=t[r];if(n.marker!==95&&n.marker!==42||n.end===-1)continue;let i=t[n.end],a=r>0&&t[r-1].end===n.end+1&&t[r-1].marker===n.marker&&t[r-1].token===n.token-1&&t[n.end+1].token===i.token+1,o=String.fromCharCode(n.marker),s=e.tokens[n.token];s.type=a?`strong_open`:`em_open`,s.tag=a?`strong`:`em`,s.nesting=1,s.markup=a?o+o:o,s.content=``;let c=e.tokens[i.token];c.type=a?`strong_close`:`em_close`,c.tag=a?`strong`:`em`,c.nesting=-1,c.markup=a?o+o:o,c.content=``,a&&(e.tokens[t[r-1].token].content=``,e.tokens[t[n.end+1].token].content=``,r--)}}function on(e){let t=e.tokens_meta,n=e.tokens_meta.length;an(e,e.delimiters);for(let i=0;i=d)return!1;if(c=m,i=e.md.helpers.parseLinkDestination(e.src,m,e.posMax),i.ok){for(o=e.md.normalizeLink(i.str),e.md.validateLink(o)?m=i.pos:o=``,c=m;m=d||e.src.charCodeAt(m)!==41)&&(l=!0),m++}if(l){if(e.env.references===void 0)return!1;if(m=0?r=e.src.slice(c,m++):m=p+1):m=p+1,r||(r=e.src.slice(f,p)),r=I(r),a=e.env.references[r],!a)return e.pos=u,!1;o=a.href,s=a.title}if(!t){e.pos=f,e.posMax=p;let t=e.push(`link_open`,`a`,1),n=[[`href`,o]];if(t.attrs=n,s&&n.push([`title`,s]),r){let e=Object.create(null);e.label=r,t.meta=e}e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push(`link_close`,`a`,-1)}return e.pos=m,e.posMax=d,!0}function ln(e,t){let n,r,i,a,o,s,c,l,u=``,d=e.pos,f=e.posMax;if(e.src.charCodeAt(e.pos)!==33||e.src.charCodeAt(e.pos+1)!==91)return!1;let p=e.pos+2,m=e.md.helpers.parseLinkLabel(e,e.pos+1,!1);if(m<0)return!1;if(a=m+1,a=f)return!1;for(l=a,s=e.md.helpers.parseLinkDestination(e.src,a,e.posMax),s.ok&&(u=e.md.normalizeLink(s.str),e.md.validateLink(u)?a=s.pos:u=``),l=a;a=f||e.src.charCodeAt(a)!==41)return e.pos=d,!1;a++}else{if(e.env.references===void 0)return!1;if(a=0?i=e.src.slice(l,a++):a=m+1):a=m+1,i||(i=e.src.slice(p,m)),i=I(i),o=e.env.references[i],!o)return e.pos=d,!1;u=o.href,c=o.title}if(!t){r=e.src.slice(p,m);let t=[];e.md.inline.parse(r,e.md,e.env,t);let n=e.push(`image`,`img`,0),a=[[`src`,u],[`alt`,``]];if(n.attrs=a,n.children=t,n.content=r,c&&a.push([`title`,c]),i){let e=Object.create(null);e.label=i,n.meta=e}}return e.pos=a,e.posMax=f,!0}var un=/^([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])?)*)$/,dn=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function fn(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==60)return!1;let r=e.pos,i=e.posMax;for(;;){if(++n>=i)return!1;let t=e.src.charCodeAt(n);if(t===60)return!1;if(t===62)break}let a=e.src.slice(r+1,n);if(dn.test(a)){let n=e.md.normalizeLink(a);if(!e.md.validateLink(n))return!1;if(!t){let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,n]],t.markup=`autolink`,t.info=`auto`;let r=e.push(`text`,``,0);r.content=e.md.normalizeLinkText(a);let i=e.push(`link_close`,`a`,-1);i.markup=`autolink`,i.info=`auto`}return e.pos+=a.length+2,!0}if(un.test(a)){let n=e.md.normalizeLink(`mailto:${a}`);if(!e.md.validateLink(n))return!1;if(!t){let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,n]],t.markup=`autolink`,t.info=`auto`;let r=e.push(`text`,``,0);r.content=e.md.normalizeLinkText(a);let i=e.push(`link_close`,`a`,-1);i.markup=`autolink`,i.info=`auto`}return e.pos+=a.length+2,!0}return!1}function pn(e){return/^\s]/i.test(e)}function mn(e){return/^<\/a\s*>/i.test(e)}function hn(e){let t=e|32;return t>=97&&t<=122}function gn(e,t){if(!e.md.options.html)return!1;let n=e.posMax,r=e.pos;if(e.src.charCodeAt(r)!==60||r+2>=n)return!1;let i=e.src.charCodeAt(r+1);if(i!==33&&i!==63&&i!==47&&!hn(i))return!1;let a=e.src.slice(r).match(It);if(!a)return!1;if(!t){let t=e.push(`html_inline`,``,0);t.content=a[0],pn(t.content)&&e.linkLevel++,mn(t.content)&&e.linkLevel--}return e.pos+=a[0].length,!0}var _n=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,vn=/^&([a-z][a-z0-9]{1,31});/i;function yn(e,t){let n=e.pos,r=e.posMax;if(e.src.charCodeAt(n)!==38||n+1>=r)return!1;if(e.src.charCodeAt(n+1)===35){let r=e.src.slice(n).match(_n);if(r){if(!t){let t=r[1][0].toLowerCase()===`x`?parseInt(r[1].slice(1),16):parseInt(r[1],10),n=e.push(`text_special`,``,0);n.content=Te(t)?k(t):k(65533),n.markup=r[0],n.info=`entity`}return e.pos+=r[0].length,!0}}else{let r=e.src.slice(n).match(vn);if(r){let n=xe(r[0]);if(n!==r[0]){if(!t){let t=e.push(`text_special`,``,0);t.content=n,t.markup=r[0],t.info=`entity`}return e.pos+=r[0].length,!0}}}return!1}function bn(e){let t={},n=e.length;if(!n)return;let r=0,i=-2,a=[];for(let o=0;os;c-=a[c]+1){let t=e[c];if(t.marker===n.marker&&t.open&&t.end<0){let r=!1;if((t.close||n.open)&&(t.length+n.length)%3==0&&(t.length%3!=0||n.length%3!=0)&&(r=!0),!r){let r=c>0&&!e[c-1].open?a[c-1]+1:0;a[o]=o-c+r,a[c]=r,n.open=!1,t.end=o,t.close=!1,l=-1,i=-2;break}}}l!==-1&&(t[n.marker][(n.open?3:0)+(n.length||0)%3]=l)}}function xn(e){let t=e.tokens_meta,n=e.tokens_meta.length;bn(e.delimiters);for(let e=0;e0&&r++,i[t].type===`text`&&t+1=e.pos)throw Error(`inline rule didn't increment state.pos`);break}}else e.pos=e.posMax;o||e.pos++,a[t]=e.pos}tokenize(e){let t=this.ruler.getRules(``),n=t.length,r=e.posMax,i=e.md.options.maxNesting;for(;e.pos=e.pos)throw Error(`inline rule didn't increment state.pos`);break}}if(o){if(e.pos>=r)break;continue}e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()}parse(e,t,n,r){let i=new this.State(e,t,n,r);this.tokenize(i);let a=this.ruler2.getRules(``),o=a.length;for(let e=0;e<\uff5c]/:t}get_pseudo_letter(){var e,t;return(t=(e=this.cache).src_pseudo_letter)==null?e.src_pseudo_letter=RegExp(`(?:(?!${this.get_text_separators().source}|${this.src_ZPCc})${this.src_Any})`):t}get_ipv4_addr(){var e,t;return(t=(e=this.cache).src_ip4)==null?e.src_ip4=RegExp(`(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])[.]){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])`):t}get_ipv6_addr(){var e,t;let n=`[0-9A-Fa-f]{1,4}`,r=`(?:(?:${n}:${n})|${this.get_ipv4_addr().source})`;return(t=(e=this.cache).src_ip6_addr)==null?e.src_ip6_addr=RegExp(`(?:(?:${n}:){6}${r}|::(?:${n}:){5}${r}|(?:${n})?::(?:${n}:){4}${r}|(?:(?:${n}:){0,1}${n})?::(?:${n}:){3}${r}|(?:(?:${n}:){0,2}${n})?::(?:${n}:){2}${r}|(?:(?:${n}:){0,3}${n})?::${n}:${r}|(?:(?:${n}:){0,4}${n})?::${r}|(?:(?:${n}:){0,5}${n})?::${n}|(?:(?:${n}:){0,6}${n})?::)`):t}get_ipv6_url_host(){var e,t;return(t=(e=this.cache).src_ip6_host)==null?e.src_ip6_host=RegExp(`\\[${this.get_ipv6_addr().source}\\]`):t}get_ipv6_mail_host(){var e,t;return(t=(e=this.cache).src_ipv6_mail_host)==null?e.src_ipv6_mail_host=RegExp(`\\[IPv6:${this.get_ipv6_addr().source}\\]`):t}get_auth(){var e,t;return(t=(e=this.cache).src_auth)==null?e.src_auth=RegExp(`(?:(?:(?!${this.src_ZCc}|[@/\\[\\]()]).){1,50}@)?`):t}get_port(){var e,t;return(t=(e=this.cache).src_port)==null?e.src_port=RegExp(`(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?`):t}get_host_terminator(){var e,t;return(t=(e=this.cache).src_host_terminator)==null?e.src_host_terminator=RegExp(`(?=$|${this.get_text_separators().source}|${this.src_ZPCc})(?!${this.opts[`---`]?`-(?!--)|`:`-|`}_|:\\d|\\.-|\\.(?!$|${this.src_ZPCc}))`):t}get_path_terminator(){var e,t;return(t=(e=this.cache).src_path_terminator)==null?e.src_path_terminator=RegExp(`${this.src_ZPCc}|${this.get_text_separators().source}`):t}get_path(){var e,t;return(t=(e=this.cache).src_path)==null?e.src_path=RegExp(`(?:[/?#](?:${this.nestedPairRE(`[`,`]`)}|${this.nestedPairRE(`(`,`)`)}|${this.nestedPairRE(`{`,`}`)}|\\"(?:(?!${this.src_ZCc}|["]).){1,100}\\"|\\'(?:(?!${this.src_ZCc}|[']).){1,100}\\'|\\'(?=${this.get_pseudo_letter().source}|[-])|\\.{2,20}[:]?[a-zA-Z0-9%/&]|\\.(?!${this.src_ZCc}|[.]|$)|`+(this.opts[`---`]?`\\-(?!--(?:[^-]|$))(?:-{0,19})|`:`\\-{1,20}|`)+`,(?!${this.src_ZCc}|$)|;(?!${this.src_ZCc}|$)|\\!{1,20}(?!${this.src_ZCc}|[!]|$)|\\?(?!${this.src_ZCc}|[?]|$)|`+this.get_path_extra().source+`[\\\\/:%@#&=_~*]|(?!${this.get_path_terminator().source}).){1,${this.opts.maxLength}}|\\/)?`):t}get_mail_name(){var e,t;return(t=(e=this.cache).src_mail_name)==null?e.src_mail_name=RegExp("[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9](?:[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9]|[.](?=[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9])){0,63}"):t}get_xn(){var e,t;return(t=(e=this.cache).src_xn)==null?e.src_xn=RegExp(`xn--[a-z0-9\\-]{1,59}`):t}get_tld(){if(this.cache.tld)return this.cache.tld;let e=[...new Set(this.opts.tlds||[])].sort().reverse().join(`|`);return this.cache.tld=RegExp(`${e||`$#none#$`}|${this.get_xn().source}`),this.cache.tld}get_domain_root(){var e,t;return(t=(e=this.cache).src_domain_root)==null?e.src_domain_root=RegExp(`(?:`+this.get_xn().source+`|${this.get_pseudo_letter().source}{1,63})`):t}get_domain(){var e,t;return(t=(e=this.cache).src_domain)==null?e.src_domain=RegExp(`(?:`+this.get_xn().source+`|(?:${this.get_pseudo_letter().source})|(?:${this.get_pseudo_letter().source}(?:-|${this.get_pseudo_letter().source}){0,61}${this.get_pseudo_letter().source}))`):t}get_url_host_port(){var e,t;return(t=(e=this.cache).url_host_port)==null?e.url_host_port=RegExp(`(?:`+this.get_ipv6_url_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,10}${this.get_domain().source}))`+this.get_port().source+this.get_host_terminator().source):t}get_fuzzy_url_host_port(){var e,t;return(t=(e=this.cache).fuzzy_url_host_port)==null?e.fuzzy_url_host_port=RegExp(`(?:`+(this.opts.fuzzyIP?this.get_ipv4_addr().source+`|`:``)+`(?:(?:(?:${this.get_domain().source})\\.){1,10}(?:${this.get_tld().source})))`+this.get_host_terminator().source):t}get_mail_host(){var e,t;return(t=(e=this.cache).src_mail_host)==null?e.src_mail_host=RegExp(`(?:`+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,4}${this.get_domain().source}))`+this.get_host_terminator().source):t}get_fuzzy_mail_host(){var e,t;return(t=(e=this.cache).src_fuzzy_mail_host)==null?e.src_fuzzy_mail_host=RegExp(`(?:`+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})[.]){1,4}${this.get_domain_root().source}))`+this.get_host_terminator().source):t}get_path_extra(){var e,t;return(t=(e=this.cache).src_path_extra)==null?e.src_path_extra=RegExp(``):t}get_fuzzy_mail_host_search(){var e,t;return(t=(e=this.cache).mail_fuzzy_host_search)==null?e.mail_fuzzy_host_search=RegExp(`@${this.get_fuzzy_mail_host().source}`,`ig`):t}get_fuzzy_link_search(){var e,t;return(t=(e=this.cache).link_fuzzy_search)==null?e.link_fuzzy_search=RegExp(`(^|(?![.:/\\-_@])(?:[$+<=>^\`|\uff5c]|${this.src_ZPCc}))(?:(?![$+<=>^\`|\uff5c])${this.get_fuzzy_url_host_port().source}${this.get_path().source})`,`ig`):t}get_http_validator(){var e,t;return(t=(e=this.cache).http_validator)==null?e.http_validator=RegExp(`\\/\\/`+(this.opts.urlAuth?this.get_auth().source:``)+this.get_url_host_port().source+this.get_path().source,`iy`):t}get_relative_proto_validator(){var e,t;return(t=(e=this.cache).relative_proto_validator)==null?e.relative_proto_validator=RegExp((this.opts.urlAuth?this.get_auth().source:``)+`(?:localhost|${this.get_ipv6_url_host().source}|(?:(?:${this.get_domain().source})[.]){1,10}${this.get_domain_root().source})`+this.get_port().source+this.get_host_terminator().source+this.get_path().source,`iy`):t}get_mail_name_validator(){var e,t;return(t=(e=this.cache).mail_name_validator)==null?e.mail_name_validator=RegExp(`(?:^|${this.get_text_separators().source}|"|\\(|${this.src_ZCc})(${this.get_mail_name().source})$`):t}get_mailto_validator(){var e,t;return(t=(e=this.cache).mailto_validator)==null?e.mailto_validator=RegExp(`${this.get_mail_name().source}@${this.get_mail_host().source}`,`iy`):t}get_schema_names(){var e,t;return(t=(e=this.cache).schema_names)==null?e.schema_names=new RegExp((this.opts.schema_names||[]).map(e=>this.escapeRE(e)).join(`|`)):t}get_schema_search(){var e,t;return(t=(e=this.cache).schema_search)==null?e.schema_search=RegExp(`(^|(?!_)(?:[><\uff5c]|${this.src_ZPCc}))(${this.get_schema_names().source})`,`ig`):t}get_schema_at_start(){var e,t;return(t=(e=this.cache).schema_at_start)==null?e.schema_at_start=RegExp(`^${this.get_schema_search().source}`,`i`):t}},jn={validate:(e,t,n)=>{let r=n.re.get_http_validator();r.lastIndex=t;let i=r.exec(e);return i?i[0].length:0},normalize:(e,t)=>t.normalize(e)},Mn={"http:":jn,"https:":jn,"ftp:":jn,"//":{validate:function(e,t,n){let r=n.re.get_relative_proto_validator();r.lastIndex=t;let i=r.exec(e);return i?t>=3&&e[t-3]===`:`||t>=3&&e[t-3]===`/`?0:i[0].length:0},normalize:(e,t)=>t.normalize(e)},"mailto:":{validate:function(e,t,n){let r=n.re.get_mailto_validator();r.lastIndex=t;let i=r.exec(e);return i?i[0].length:0},normalize:(e,t)=>t.normalize(e)}},Nn=`a:cdefgilmnoqrstuwxz|b:abdefghijmnorstvwyz|c:acdfghiklmnoruvwxyz|d:ejkmoz|e:cegrstu|f:ijkmor|g:abdefghilmnpqrstuwy|h:kmnrtu|i:delmnoqrst|j:emop|k:eghimnprwyz|l:abcikrstuvy|m:acdeghklmnopqrstuvwxyz|n:acefgilopruz|o:m|p:aefghklmnrstwy|q:a|r:eosuw|s:abcdeghijklmnortuvxyz|t:cdfghjklmnortvwz|u:agksyz|v:aceginu|w:fs|y:et|z:amw`,Pn=`biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф`;function Fn(){let e=Pn.split(`|`);return Nn.split(`|`).forEach(t=>{let n=t.indexOf(`:`),r=t.slice(0,n);for(let i of t.slice(n+1))e.push(r+i)}),e}var In={fuzzyLink:!1,fuzzyEmail:!0,fuzzyIP:!1,"---":!1,tlds:Fn(),urlAuth:!1,maxLength:1e4},Ln=class{constructor(e,t,n,r){T(this,`schema`,void 0),T(this,`index`,void 0),T(this,`lastIndex`,void 0),T(this,`raw`,void 0),T(this,`text`,void 0),T(this,`url`,void 0);let i=e.slice(n,r);this.schema=t.toLowerCase(),this.index=n,this.lastIndex=r,this.raw=i,this.text=i,this.url=i}},Rn=class{constructor(e={}){T(this,`__opts__`,void 0),T(this,`__schemas__`,void 0),T(this,`re`,void 0);let{rebuilder:t}=e,n=On(e,kn);this.__opts__=q(q({},In),n),this.__schemas__=q({},Mn),this.re=t||new An,this.re.set(q(q({},this.__opts__),{},{schema_names:Object.keys(this.__schemas__)}))}add(e,t=null){if(!t)delete this.__schemas__[e];else{let n=q({normalize:(e,t)=>t.normalize(e)},t);this.__schemas__[e]=n}return this.re.set(q(q({},this.__opts__),{},{schema_names:Object.keys(this.__schemas__)})),this}set(e={}){return this.__opts__=q(q({},this.__opts__),e),this.re.set(q(q({},this.__opts__),{},{schema_names:Object.keys(this.__schemas__)})),this}test(e){if(!e.length)return!1;let t,n;for(n=this.re.get_schema_search(),n.lastIndex=0;(t=n.exec(e))!==null;)if(this.testSchemaAt(e,t[2],n.lastIndex))return!0;if(this.__opts__.fuzzyLink&&this.__schemas__[`http:`]&&(n=this.re.get_fuzzy_link_search(),n.lastIndex=0,n.exec(e)!==null))return!0;if(this.__opts__.fuzzyEmail&&this.__schemas__[`mailto:`]&&e.indexOf(`@`)>=0){let n=this.re.get_fuzzy_mail_host_search(),r=this.re.get_mail_name_validator();for(n.lastIndex=0;(t=n.exec(e))!==null;){let n=e.slice(Math.max(0,t.index-65),t.index);if(r.test(n))return!0}}return!1}testSchemaAt(e,t,n){return this.__schemas__[t.toLowerCase()]?this.__schemas__[t.toLowerCase()].validate(e.slice(0,n+this.__opts__.maxLength),n,this):0}match(e){let t=[],n=this.re.get_schema_search(),r,i,a,o,s,c,l=!1,u=!1,d=!1,f=0;if(!e.length)return null;for(n.lastIndex=0,this.__opts__.fuzzyLink&&this.__schemas__[`http:`]&&(r=this.re.get_fuzzy_link_search(),r.lastIndex=0),this.__opts__.fuzzyEmail&&this.__schemas__[`mailto:`]&&(i=this.re.get_fuzzy_mail_host_search(),i.lastIndex=0,a=this.re.get_mail_name_validator());;){let p=Math.max(f-1,0);if(i&&a&&!d&&(!s||s.index=f)break;i.lastIndex=f)break;r.lastIndexm.lastIndex))&&(m=o);let h;if(!l)for(;;){if(!c){n.lastIndexm.index)break;let t=c;c=void 0;let r=this.testSchemaAt(e,t.schema,t.lastIndex);if(r){h={schema:t.schema,index:t.index,lastIndex:t.lastIndex+r};break}}let g=h;if((!g||s&&(s.indexg.lastIndex))&&(g=s),(!g||o&&(o.indexg.lastIndex))&&(g=o),!g)break;g===s?s=void 0:g===o&&(o=void 0);let _=new Ln(e,g.schema,g.index,g.lastIndex);_.schema?this.__schemas__[_.schema].normalize(_,this):this.normalize(_),t.push(_),f=g.lastIndex}return t.length?t:null}matchAtStart(e){if(!e.length)return null;let t=this.re.get_schema_at_start().exec(e);if(!t)return null;let n=this.testSchemaAt(e,t[2],t[0].length);if(!n)return null;let r=new Ln(e,t[2],t.index+t[1].length,t.index+t[0].length+n);return this.__schemas__[r.schema].normalize(r,this),r}tlds(e,t=!1){return e=Array.isArray(e)?e:[e],t?this.__opts__.tlds=this.__opts__.tlds.concat(e):this.__opts__.tlds=e,this.re.set(q(q({},this.__opts__),{},{schema_names:Object.keys(this.__schemas__)})),this}normalize(e){e.schema||(e.url=`http://${e.url}`),e.schema===`mailto:`&&!/^mailto:/i.test(e.url)&&(e.url=`mailto:${e.url}`)}},J=2147483647,Y=36,zn=1,X=26,Bn=38,Vn=700,Hn=72,Un=128,Wn=`-`,Gn=/^xn--/,Kn=/[^\0-\x7F]/,qn=/[\x2E\u3002\uFF0E\uFF61]/g,Jn={overflow:`Overflow: input needs wider integers to process`,"not-basic":`Illegal input >= 0x80 (not a basic code point)`,"invalid-input":`Invalid input`},Yn=35,Z=Math.floor,Xn=String.fromCharCode;function Q(e){throw RangeError(Jn[e])}function Zn(e,t){let n=[],r=e.length;for(;r--;)n[r]=t(e[r]);return n}function Qn(e,t){let n=e.split(`@`),r=``;n.length>1&&(r=n[0]+`@`,e=n[1]),e=e.replace(qn,`.`);let i=Zn(e.split(`.`),t).join(`.`);return r+i}function $n(e){let t=[],n=0,r=e.length;for(;n=55296&&i<=56319&&nString.fromCodePoint(...e),tr=function(e){return e>=48&&e<58?26+(e-48):e>=65&&e<91?e-65:e>=97&&e<123?e-97:Y},nr=function(e,t){return e+22+75*(e<26)-((t!=0)<<5)},rr=function(e,t,n){let r=0;for(e=n?Z(e/Vn):e>>1,e+=Z(e/t);e>455;r+=Y)e=Z(e/Yn);return Z(r+36*e/(e+Bn))},ir=function(e){let t=[],n=e.length,r=0,i=Un,a=Hn,o=e.lastIndexOf(Wn);o<0&&(o=0);for(let n=0;n=128&&Q(`not-basic`),t.push(e.charCodeAt(n));for(let s=o>0?o+1:0;s=n&&Q(`invalid-input`);let o=tr(e.charCodeAt(s++));o>=Y&&Q(`invalid-input`),o>Z((J-r)/t)&&Q(`overflow`),r+=o*t;let c=i<=a?zn:i>=a+X?X:i-a;if(oZ(J/l)&&Q(`overflow`),t*=l}let c=t.length+1;a=rr(r-o,c,o==0),Z(r/c)>J-i&&Q(`overflow`),i+=Z(r/c),r%=c,t.splice(r++,0,i)}return String.fromCodePoint(...t)},ar=function(e){let t=[];e=$n(e);let n=e.length,r=Un,i=0,a=Hn;for(let n of e)n<128&&t.push(Xn(n));let o=t.length,s=o;for(o&&t.push(Wn);s=r&&tZ((J-i)/c)&&Q(`overflow`),i+=(n-r)*c,r=n;for(let n of e)if(nJ&&Q(`overflow`),n===r){let e=i;for(let n=Y;;n+=Y){let r=n<=a?zn:n>=a+X?X:n-a;if(e=0))try{t.hostname=or.toASCII(t.hostname)}catch(e){}return t.auth&&(t.auth=s(t.auth)),t.hostname&&(t.hostname=s(t.hostname)),t.pathname&&(t.pathname=s(t.pathname)),t.search&&(t.search=s(t.search)),t.hash&&(t.hash=s(t.hash)),c(t)}normalizeLinkText(e){let t=b(e,!0);if(t.hostname&&(!t.protocol||ur.indexOf(t.protocol)>=0))try{t.hostname=or.toUnicode(t.hostname)}catch(e){}return i(c(t),i.defaultChars+`%`)}constructor(...e){T(this,`inline`,new Tn),T(this,`block`,new Ht),T(this,`core`,new yt),T(this,`renderer`,new We),T(this,`linkify`,new Rn),T(this,`utils`,Se),T(this,`helpers`,Object.assign({},Ue));let[t,n]=e;typeof t==`string`?(this.configure(t),n&&this.set(n)):(this.configure(`default`),this.set(t||{}))}set(e){return Object.assign(this.options,e),this}configure(e){let t;if(typeof e==`string`){let n=e;if(t=sr[n],!t)throw Error(`Wrong 'markdown-it' preset "${n}", check name`)}else t=e;if(!t)throw Error("Wrong `markdown-it` preset, can't be empty");t.options&&(this.options=q({},t.options));let n=t.components;if(n){var r;[`core`,`block`,`inline`].forEach(e=>{var t;let r=(t=n[e])==null?void 0:t.rules;r&&this[e].ruler.enableOnly(r)});let e=(r=n.inline)==null?void 0:r.rules2;e&&this.inline.ruler2.enableOnly(e)}return this}enable(e,t=!1){let n=[];Array.isArray(e)||(e=[e]),[`core`,`block`,`inline`].forEach(t=>{n=n.concat(this[t].ruler.enable(e,!0))}),n=n.concat(this.inline.ruler2.enable(e,!0));let r=e.filter(e=>n.indexOf(e)<0);if(r.length&&!t)throw Error(`MarkdownIt. Failed to enable unknown rule(s): ${r}`);return this}disable(e,t=!1){let n=[];Array.isArray(e)||(e=[e]),[`core`,`block`,`inline`].forEach(t=>{n=n.concat(this[t].ruler.disable(e,!0))}),n=n.concat(this.inline.ruler2.disable(e,!0));let r=e.filter(e=>n.indexOf(e)<0);if(r.length&&!t)throw Error(`MarkdownIt. Failed to disable unknown rule(s): ${r}`);return this}use(e,...t){return e.apply(e,[this,...t]),this}parse(e,t){if(typeof e!=`string`)throw Error(`Input data should be a String`);let n=new this.core.State(e,this,t);return this.core.process(n),n.tokens}render(e,t={}){return this.renderer.render(this.parse(e,t),this.options,t)}parseInline(e,t){let n=new this.core.State(e,this,t);return n.inlineMode=!0,this.core.process(n),n.tokens}renderInline(e,t={}){return this.renderer.render(this.parseInline(e,t),this.options,t)}};return T($,`Token`,R),T($,`Ruler`,z),T($,`Renderer`,We),T($,`ParserCore`,yt),T($,`StateCore`,Ge),T($,`ParserBlock`,Ht),T($,`StateBlock`,bt),T($,`ParserInline`,Tn),T($,`StateInline`,Ut),Ce($)}); +//# sourceMappingURL=markdown-it.umd.min.js.map \ No newline at end of file