From 6a8201a5321efc2c84f004eb168b8e9e3e58c626 Mon Sep 17 00:00:00 2001 From: Dave Star Date: Thu, 30 Jun 2022 17:13:33 +0100 Subject: [PATCH] build release 1.1.54 --- package.json | 2 +- release/cli.js | 6 +++--- release/cli.js.map | 2 +- release/package.json | 2 +- release/template.css | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 3c5f44cb..3d9ce35b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "compiler", "template" ], - "version": "1.1.53", + "version": "1.1.54", "repository": "https://github.com/UofGAnalytics/build-coursework.git", "author": "David McArthur ", "license": "MIT", diff --git a/release/cli.js b/release/cli.js index 596feda9..b42ff328 100755 --- a/release/cli.js +++ b/release/cli.js @@ -3163,7 +3163,7 @@ function environment(ctx, targetPdf) { if (platforms.includes(node.name)) { node.data = { hProperties: { - className: ['platform', node.name] + className: ['platform', node.name, platformFlag === node.name ? 'show' : ''] } }; @@ -3179,7 +3179,7 @@ function environment(ctx, targetPdf) { if (programs.includes(node.name)) { node.data = { hProperties: { - className: ['program', node.name] + className: ['program', node.name, programFlag === node.name ? 'show' : ''] } }; @@ -4222,7 +4222,7 @@ const repo = 'UofGAnalytics/build-coursework'; async function checkForLatestVersion() { if (false) {} - const currentVersion = "1.1.53"; + const currentVersion = "1.1.54"; try { const tags = await listRemoteGitTags(); diff --git a/release/cli.js.map b/release/cli.js.map index 65420cc9..5c1dd9e6 100644 --- a/release/cli.js.map +++ b/release/cli.js.map @@ -1 +1 @@ -{"version":3,"file":"cli.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAmBA;AACA;AAEA;;AAGA;AAEA;AACA;AACA;AACA;AAHA;;AAMA;AACA;AAMA;;AAEA;AACA;AAOA;AAEA;AAFA;AAIA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AAIA;;AAEA;AAOA;AACA;AAMA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;AClHA;AACA;AACA;AAGA;AAEA;AAAA;AAAA;AAEA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AACA;AAHA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAnBA;;AAsBA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;;;ACnIA;AAEA;AAuCA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AASA;;;;;;;;;;;;;;;;;;;;;;;;ACtDA;AAEA;AACA;AAEA;AACA;AACA;AAUA;AACA;AACA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;;AAEA;AAKA;AAAA;AAAA;AAAA;AACA;AACA;AAEA;;AACA;AACA;AACA;;AACA;AACA;AAEA;AACA;AACA;AACA;AAHA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;;;;;;;;;;;;;;;;;;;;;AC9DA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AADA;AAIA;AACA;AACA;AATA;AAYA;AACA;;AACA;AACA;AAGA;;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AC9CA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AADA;AAJA;AAUA;AACA;;AACA;AACA;AAGA;;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AC3BA;AACA;AACA;AAIA;AACA;AAEA;AAMA;AACA;AAAA;;AAIA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1BA;AAEA;AAEA;AACA;AACA;AACA;;AAGA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;;AAGA;AACA;;AACA;AACA;AAhBA;AAkBA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAHA;AAUA;AAEA;AAAA;AAAA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AALA;AAOA;;;;;;;;;;;;;;;;;;AC9KA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AADA;AAGA;AALA;AAOA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AC/BA;AAGA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAQA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAFA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AAEA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AClEA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAHA;AAcA;AACA;;;;;;;;;;;;;;;;;;;AC3BA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAHA;AAcA;AACA;;;;;;;;;;;;;;;;;;;;AC5BA;AAEA;AACA;AAGA;AAEA;AAKA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAJA;AAcA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAGA;AACA;AACA;AACA;AADA;AAGA;AANA;AARA;AAqBA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAKA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AARA;AAuBA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;AC5GA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AADA;AAGA;AANA;AASA;AACA;AACA;AACA;AADA;AAGA;AANA;AAdA;AAwBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAPA;AAkBA;;;;;;;;;;;;;;;;;;AC1DA;AAEA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AACA;AACA;AACA;AALA;AASA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AANA;AAQA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAjCA;AAvBA;AAyEA;;AC1HA;AAEA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAMA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AANA;AAQA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;ACpDA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;AAEA;AACA;AAIA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAUA;;;;;;;;;;;;;;;;;;;;;;AC5CA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;;AAGA;;AAEA;AACA;AACA;AAGA;AACA;;AACA;AACA;AAEA;AAGA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AAGA;AACA;;AACA;AACA;AAGA;;AACA;AAIA;AACA;AACA;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AAKA;AACA;AACA;AACA;AACA;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AAIA;;AAGA;AACA;;AAGA;;AAMA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAUA;;AAGA;AACA;;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAUA;AACA;;;AAGA;AACA;;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAUA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AAGA;AACA;AACA;AACA;;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACrVA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAJA;AAMA;AACA;AACA;AACA;AAHA;AAKA;AAjBA;AAmBA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACpCA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAVA;AAeA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;AAGA;AACA;;AAGA;AACA;AACA;AAFA;AAMA;AACA;AAFA;AAMA;AACA;AAKA;AACA;AARA;AAYA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AA1CA;AAlBA;;AAkEA;AAEA;;AAGA;AACA;AAEA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;AAIA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AAIA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxKA;AAGA;AACA;AAEA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC3BA;AAGA;AAEA;AACA;AACA;AAIA;AACA;AACA;;AACA;AACA;AAKA;AACA;;AACA;AACA;;AACA;AACA;AAKA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;ACpCA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;ACjBA;AAEA;AACA;AACA;AACA;;AACA;AACA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAWA;AACA;AACA;;;;;;;;;;;;ACvBA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAWA;AACA;AACA;;;;;;;;;;;;;;;;ACzBA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC9BA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AAKA;;AAEA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnCA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrBA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AAEA;AAEA;AAFA;AAFA;AAOA;;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;;AAWA;AACA;AAEA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACrEA;AAIA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AAIA;AACA;AACA;AAEA;;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAHA;AAKA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACjFA;AACA;AAKA;AAmBA;AACA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;;AAEA;AACA;AACA;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AALA;AAOA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;AAJA;AAMA;;;;;;;;;;;;;;;;;;;;;AClHA;AAGA;AAEA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAjBA;AAmBA;AACA;AACA;;AAEA;AAKA;AACA;AAEA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AAAA;AAAA;AAAA;AACA;;AAEA;AAIA;AACA;AAEA;;AACA;AACA;AACA;AACA;;AAEA;AAEA;AAGA;AAAA;;AAGA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAEA;AACA;AAFA;AARA;AAeA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AArBA;AAgCA;;AAEA;AAIA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AAEA;AACA;AACA;AACA;AACA;AAHA;AAKA;;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAAA;AAAA;;AACA;AACA;AACA;;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AARA;AAWA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAKA;;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;AC7MA;AAGA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAJA;AAJA;AAPA;AAFA;AAwBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;ACxHA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AADA;AAKA;AACA;AACA;AACA;AADA;AADA;;AAMA;AACA;AAEA;AACA;AACA;AACA;AAHA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AAEA;;AACA;AACA;AACA;;AAEA;;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACzDA;AAIA;AACA;AACA;AAEA;AAMA;;AAIA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACxBA;AAGA;AAIA;AACA;AACA;AAGA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAKA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AAIA;AACA;AACA;AACA;;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACzEA;AAEA;AAEA;AAIA;AACA;AAEA;AACA;;AACA;AACA;AAGA;;AAEA;;AACA;AACA;AAGA;;AAEA;AACA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AADA;AADA;;AAKA;AACA;AACA;AACA;AACA;AAIA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AADA;AADA;;AAKA;AACA;AACA;AACA;AACA;AAGA;AACA;;AAEA;AACA;AACA;AACA;;AAIA;AAKA;AAEA;AACA;AACA;AAFA;AAKA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAWA;AACA;AAnBA;AAsBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAWA;AACA;AAnBA;AAsBA;;AAEA;AACA;AACA;AACA;AAHA;AAKA;;AAEA;AAKA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AATA;AAYA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAlBA;AA8BA;;;;;;;;;;;;;;;;;;ACxNA;AAGA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAPA;;AAmBA;AACA;AAEA;AAFA;AAIA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAJA;AAeA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AANA;AAFA;AAWA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AAFA;AAKA;;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAKA;AAAA;AALA;AAUA;AACA;AAAA;AAAA;AAFA;AATA;AAAA;AAwBA;AACA;AACA;;;;;;;;;;;;;;;;;AClDA;AAEA;AACA;AACA;AAIA;AACA;;AAGA;AACA;AAEA;AAGA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAGA;AACA;AAEA;AAEA;AAFA;AAKA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;AC5CA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAFA;AAMA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACfA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACbA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAWA;AACA;AAFA;AAjBA;AAjCA;AA2DA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAPA;AAnEA;AAuFA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;AClIA;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AAJA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AALA;AAYA;AACA;AACA;;;;;;;;;;;;;ACvCA;AACA;AAGA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;ACXA;AAEA;AACA;AAIA;AAEA;AACA;AAGA;AAIA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;;;;ACRA;AACA;AAGA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAQA;AACA;;AACA;AACA;AACA;;AACA;AACA;AAGA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AAPA;AASA;;AAEA;AAIA;AAEA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;AClEA;AACA;AAIA;AACA;AACA;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxCA;AAEA;AAEA;AACA;AAGA;;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AAKA;;AAEA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACzIA;AAEA;AAGA;AAUA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AAEA;AACA;AAAA;AAAA;AACA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACzDA;AAEA;AACA;AAEA;AAEA;AACA;;AAIA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AALA;AAOA;;;;;;;;;;;;;;;;ACdA;AAEA;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AChBA;AAEA;AAEA;;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC1CA;AACA;AACA;AAQA;AAKA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AARA;AAkBA;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAHA;AAPA;AAcA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAJA;AAMA;;;;;;;;;;;;;;;;ACpEA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AAKA;AACA;AACA;AAEA;AAKA;AACA;AACA;AAEA;AAKA;AACA;AACA;;AAEA;AAMA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;;AAJA;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AAGA;AAIA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AAEA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;;;;;;;;;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACpHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjGA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC5HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC1OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtlBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACzJA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5YA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;;;;;AEAA;AACA;AACA;AACA","sources":["webpack://compiler/./src/build-unit.ts","webpack://compiler/./src/cli/cli.ts","webpack://compiler/./src/context.ts","webpack://compiler/./src/course/index.ts","webpack://compiler/./src/course/load-course.ts","webpack://compiler/./src/course/load-unit.ts","webpack://compiler/./src/hast/index.ts","webpack://compiler/./src/hast/inline-files.ts","webpack://compiler/./src/hast/responsive-tables.ts","webpack://compiler/./src/html/index.ts","webpack://compiler/./src/html/pdf.ts","webpack://compiler/./src/html/wrapper/index.ts","webpack://compiler/./src/html/wrapper/main.ts","webpack://compiler/./src/html/wrapper/sidebar.ts","webpack://compiler/./src/html/wrapper/view-options/readability.ts","webpack://compiler/./src/html/wrapper/view-options/theme.ts","webpack://compiler/./src/html/wrapper/view-options/index.ts","webpack://compiler/./src/index.ts","webpack://compiler/./src/knitr/knitr.ts","webpack://compiler/./src/latex/directive-to-svg.ts","webpack://compiler/./src/latex/mathjax-tex.ts","webpack://compiler/./src/latex/tex-to-directive.ts","webpack://compiler/./src/linter/assert-asset-exists.ts","webpack://compiler/./src/linter/assert-columns.ts","webpack://compiler/./src/linter/assert-no-h1.ts","webpack://compiler/./src/linter/assert-no-image-attributes.ts","webpack://compiler/./src/linter/assert-no-tex-tabular.ts","webpack://compiler/./src/linter/assert-task-answer.ts","webpack://compiler/./src/linter/assert-video-attributes.ts","webpack://compiler/./src/linter/assert-weblink-target.ts","webpack://compiler/./src/linter/index.ts","webpack://compiler/./src/linter/lint-latex.ts","webpack://compiler/./src/linter/report.ts","webpack://compiler/./src/mdast/boxouts.ts","webpack://compiler/./src/mdast/code-blocks.ts","webpack://compiler/./src/mdast/columns.ts","webpack://compiler/./src/mdast/combined.ts","webpack://compiler/./src/mdast/embed-asset-url.ts","webpack://compiler/./src/mdast/environment.ts","webpack://compiler/./src/mdast/images.ts","webpack://compiler/./src/mdast/index.ts","webpack://compiler/./src/mdast/move-answers-to-end.ts","webpack://compiler/./src/mdast/pagebreaks.ts","webpack://compiler/./src/mdast/remove-empty-paragraphs.ts","webpack://compiler/./src/mdast/youtube-videos.ts","webpack://compiler/./src/pdf/index.ts","webpack://compiler/./src/pre-parse/allow-no-whitespace-before-heading.ts","webpack://compiler/./src/pre-parse/convert-block-tex.ts","webpack://compiler/./src/pre-parse/convert-inline-tex.ts","webpack://compiler/./src/pre-parse/convert-macro-to-directive.ts","webpack://compiler/./src/pre-parse/index.ts","webpack://compiler/./src/pre-parse/reformat-pandoc-simple-tables.ts","webpack://compiler/./src/utils/cache-to-file.ts","webpack://compiler/./src/utils/check-for-latest-version.ts","webpack://compiler/./src/utils/counter.ts","webpack://compiler/./src/utils/get-asset-hast.ts","webpack://compiler/./src/utils/get-svg-hast.ts","webpack://compiler/./src/utils/icons.ts","webpack://compiler/./src/utils/message.ts","webpack://compiler/./src/utils/timer.ts","webpack://compiler/./src/utils/utils.ts","webpack://compiler/../node_modules/extend/index.js","webpack://compiler/../node_modules/is-buffer/index.js","webpack://compiler/../node_modules/mdurl/encode.js","webpack://compiler/./assets/crest.svg","webpack://compiler/./assets/dag-logo.svg","webpack://compiler/./assets/hamburger-icon.svg","webpack://compiler/./assets/hexagons.svg","webpack://compiler/./assets/link-icon.svg","webpack://compiler/./assets/uofg.svg","webpack://compiler/external module \"@double-great/remark-lint-alt-text\"","webpack://compiler/external module \"@mapbox/remark-lint-link-text\"","webpack://compiler/external module \"base64-arraybuffer\"","webpack://compiler/external module \"chalk\"","webpack://compiler/external module \"dictionary-en-gb\"","webpack://compiler/external module \"figures\"","webpack://compiler/external module \"hash-sum\"","webpack://compiler/external module \"image-size\"","webpack://compiler/external module \"js-yaml\"","webpack://compiler/external module \"lodash/cloneDeep.js\"","webpack://compiler/external module \"lodash/kebabCase.js\"","webpack://compiler/external module \"lodash/startCase.js\"","webpack://compiler/external module \"markdown-table\"","webpack://compiler/external module \"mathjax-full/js/adaptors/liteAdaptor.js\"","webpack://compiler/external module \"mathjax-full/js/core/MathItem.js\"","webpack://compiler/external module \"mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js\"","webpack://compiler/external module \"mathjax-full/js/handlers/html.js\"","webpack://compiler/external module \"mathjax-full/js/handlers/html/HTMLDocument.js\"","webpack://compiler/external module \"mathjax-full/js/input/mathml.js\"","webpack://compiler/external module \"mathjax-full/js/input/tex.js\"","webpack://compiler/external module \"mathjax-full/js/input/tex/AllPackages.js\"","webpack://compiler/external module \"mathjax-full/js/mathjax.js\"","webpack://compiler/external module \"mathjax-full/js/output/svg.js\"","webpack://compiler/external module \"mdast-util-toc\"","webpack://compiler/external module \"mime/lite.js\"","webpack://compiler/external module \"node-fetch\"","webpack://compiler/external module \"puppeteer\"","webpack://compiler/external module \"refractor\"","webpack://compiler/external module \"rehype-document\"","webpack://compiler/external module \"rehype-format\"","webpack://compiler/external module \"rehype-parse\"","webpack://compiler/external module \"rehype-raw\"","webpack://compiler/external module \"rehype-stringify\"","webpack://compiler/external module \"remark-autolink-headings\"","webpack://compiler/external module \"remark-directive\"","webpack://compiler/external module \"remark-footnotes\"","webpack://compiler/external module \"remark-frontmatter\"","webpack://compiler/external module \"remark-gfm\"","webpack://compiler/external module \"remark-parse\"","webpack://compiler/external module \"remark-rehype\"","webpack://compiler/external module \"remark-retext\"","webpack://compiler/external module \"remark-slug\"","webpack://compiler/external module \"retext-english\"","webpack://compiler/external module \"retext-spell\"","webpack://compiler/external module \"speech-rule-engine\"","webpack://compiler/external module \"to-vfile\"","webpack://compiler/external module \"unist-util-visit\"","webpack://compiler/external module \"yargs\"","webpack://compiler/external module \"yup\"","webpack://compiler/external node-commonjs \"child_process\"","webpack://compiler/external node-commonjs \"fs\"","webpack://compiler/external node-commonjs \"os\"","webpack://compiler/external node-commonjs \"path\"","webpack://compiler/external node-commonjs \"url\"","webpack://compiler/../node_modules/mdast-util-definitions/index.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/footer.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/blockquote.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/break.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/code.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/delete.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/emphasis.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/footnote-reference.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/footnote.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/heading.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/html.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/revert.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/image-reference.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/image.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/inline-code.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/link-reference.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/link.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/list-item.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/list.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/paragraph.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/root.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/strong.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/table.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/text.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/thematic-break.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/index.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/index.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/traverse.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/wrap.js","webpack://compiler/../node_modules/micromark-util-character/lib/unicode-punctuation-regex.js","webpack://compiler/../node_modules/micromark-util-character/index.js","webpack://compiler/../node_modules/micromark-util-encode/index.js","webpack://compiler/../node_modules/micromark-util-sanitize-uri/index.js","webpack://compiler/../node_modules/bail/index.js","webpack://compiler/../node_modules/unified/node_modules/is-plain-obj/index.js","webpack://compiler/../node_modules/trough/index.js","webpack://compiler/../node_modules/unified/lib/index.js","webpack://compiler/../node_modules/unist-builder/index.js","webpack://compiler/../node_modules/unist-util-generated/index.js","webpack://compiler/../node_modules/unist-util-position/index.js","webpack://compiler/../node_modules/unist-util-stringify-position/index.js","webpack://compiler/../node_modules/vfile-message/index.js","webpack://compiler/external node-commonjs \"process\"","webpack://compiler/../node_modules/vfile/lib/minurl.shared.js","webpack://compiler/../node_modules/vfile/lib/index.js","webpack://compiler/webpack/bootstrap","webpack://compiler/webpack/runtime/async module","webpack://compiler/webpack/runtime/compat get default export","webpack://compiler/webpack/runtime/define property getters","webpack://compiler/webpack/runtime/hasOwnProperty shorthand","webpack://compiler/webpack/before-startup","webpack://compiler/webpack/startup","webpack://compiler/webpack/after-startup"],"sourcesContent":["import { EOL } from 'os';\n\nimport { Parent as HastParent } from 'hast';\nimport { Parent as MdastParent, Root } from 'mdast';\nimport { VFile } from 'vfile';\n\nimport { Context } from './context';\nimport { Unit } from './course/types';\nimport { hastPhase } from './hast';\nimport { htmlPhase } from './html';\nimport { knitr } from './knitr/knitr';\nimport { texToAliasDirective } from './latex/tex-to-directive';\nimport { createReport, reportErrors } from './linter';\nimport { assertNoImageAttributes } from './linter/assert-no-image-attributes';\nimport { mdastPhase } from './mdast';\nimport { combinedMdastPhase } from './mdast/combined';\nimport { convertToPdf } from './pdf';\nimport { preParsePhase } from './pre-parse';\n\nexport type BuiltUnit = {\n unit: Unit;\n md: string;\n files: VFile[];\n html?: {\n mdast: MdastParent;\n hast: HastParent;\n html: string;\n };\n pdf?: {\n mdast: MdastParent;\n hast: HastParent;\n html: string;\n pdf: Buffer;\n };\n};\n\nexport async function buildUnit(unit: Unit, ctx: Context) {\n const unifiedFile = await knitr(unit, ctx);\n\n const mdast = (await inSituTransforms(unifiedFile, ctx)) as Root;\n // console.log(mdast);\n\n await createReport(unifiedFile, mdast, ctx);\n\n const result: BuiltUnit = {\n unit,\n md: combineMdFiles(unifiedFile),\n files: [unifiedFile],\n };\n\n if (!ctx.options.noHtml) {\n result.html = await syntaxTreeTransforms(\n mdast,\n unifiedFile,\n unit,\n ctx\n );\n }\n\n if (!ctx.options.noPdf) {\n const transformed = await syntaxTreeTransforms(\n mdast,\n unifiedFile,\n unit,\n ctx,\n true\n );\n result.pdf = {\n ...transformed,\n pdf: await convertToPdf(transformed.html),\n };\n }\n\n if (!ctx.options.noReport) {\n reportErrors(result.files, ctx);\n }\n\n return result;\n}\n\nasync function inSituTransforms(file: VFile, ctx: Context) {\n assertNoImageAttributes(file);\n preParsePhase(file);\n texToAliasDirective(file, ctx);\n return mdastPhase(file, ctx);\n}\n\nfunction combineMdFiles(file: VFile) {\n return removeDirectoryLines(file.value as string);\n}\n\nfunction removeDirectoryLines(md: string) {\n return md\n .split(EOL)\n .filter((line) => !/^:directory\\[.+\\]$/.test(line))\n .join(EOL);\n}\n\nasync function syntaxTreeTransforms(\n _mdast: Root,\n file: VFile,\n unit: Unit,\n ctx: Context,\n targetPdf?: boolean\n) {\n const mdast = await combinedMdastPhase(_mdast, ctx, file, targetPdf);\n const hast = (await hastPhase(\n mdast,\n ctx,\n file,\n targetPdf\n )) as HastParent;\n const html = await htmlPhase(hast, mdast, file, unit, ctx, targetPdf);\n return { mdast, hast, html };\n}\n","import chalk from 'chalk';\nimport figures from 'figures';\nimport yargs from 'yargs';\n\nimport { Options } from '../context';\nimport { rMarkdown } from '..';\n\nconst { argv } = yargs(process.argv.slice(2))\n .option('week', {\n type: 'number',\n description: 'Build specific week (1-based index)',\n })\n .option('watch', {\n type: 'boolean',\n description: 'Watch coursework for changes',\n })\n .option('noDoc', {\n type: 'boolean',\n description: 'Only compile content HTML',\n })\n .option('noHtml', {\n type: 'boolean',\n description: \"Don't create HTML file\",\n })\n .option('noPdf', {\n type: 'boolean',\n description: \"Don't create PDF file\",\n })\n .option('noSyntaxHighlight', {\n type: 'boolean',\n description: 'No syntax highlighting',\n })\n .option('noReport', {\n type: 'boolean',\n description: 'Bypass linter',\n })\n .option('noEmbedAssets', {\n type: 'boolean',\n description: \"Don't embed assets\",\n })\n .option('noEmbedAssetUrl', {\n type: 'boolean',\n description: \"Don't complete asset Url\",\n })\n .option('noCache', {\n type: 'boolean',\n description: 'No cache',\n })\n .option('noTexSvg', {\n type: 'boolean',\n description: 'No Tex Svg',\n })\n .option('noHexagons', {\n type: 'boolean',\n description: 'No cover hexagons',\n })\n .option('spelling', {\n type: 'boolean',\n description: 'Check spelling',\n })\n .option('pythonBin', {\n type: 'string',\n description: 'Custom path to python binary',\n })\n .option('force', {\n type: 'boolean',\n description: 'Compile even with fatal errors',\n })\n .option('verbose', {\n type: 'boolean',\n description: 'Show error stack',\n })\n .option('envPlatform', {\n type: 'string',\n description: 'Specify which environment platform to display',\n })\n .option('envProgram', {\n type: 'string',\n description: 'Specify which environment program to display',\n })\n .option('output', {\n type: 'string',\n description: 'output to stdout',\n choices: ['md', 'html'],\n });\n\nconst dirPath = String(argv._[0] || '.');\n\nconst options: Options = {\n week: argv.week,\n watch: argv.watch,\n noDoc: argv.noDoc,\n noHtml: argv.noHtml,\n noPdf: argv.noPdf,\n noSyntaxHighlight: argv.noSyntaxHighlight,\n noReport: argv.noReport,\n noEmbedAssets: argv.noEmbedAssets,\n noEmbedAssetUrl: argv.noEmbedAssetUrl,\n noCache: argv.noCache,\n noTexSvg: argv.noTexSvg,\n noHexagons: argv.noHexagons,\n spelling: argv.spelling,\n pythonBin: argv.pythonBin,\n force: argv.force,\n verbose: argv.verbose,\n envPlatform: argv.envPlatform,\n envProgram: argv.envProgram,\n output: argv.output as 'md' | 'html',\n};\n\nasync function run() {\n try {\n const weeks = await rMarkdown(dirPath, options);\n if (weeks.length === 1) {\n const result = weeks[0];\n if (options.output === 'html') {\n console.log(result.html?.html || '');\n }\n if (options.output === 'md') {\n console.log(result.md);\n }\n }\n } catch (err: any) {\n console.log(chalk.red(figures.cross + ' ' + err.message));\n if (options.verbose) {\n console.error(err);\n }\n process.exit(1);\n }\n}\n\nrun();\n","import { collectCoursework } from './course';\nimport { Course } from './course/types';\nimport { getBuildDir, getCacheDir } from './utils/utils';\n\nexport type Options = {\n noDoc?: boolean;\n noHtml?: boolean;\n noPdf?: boolean;\n noSyntaxHighlight?: boolean;\n noReport?: boolean;\n reportOnlyErrors?: boolean;\n noEmbedAssets?: boolean;\n noEmbedAssetUrl?: boolean;\n noCache?: boolean;\n noTexSvg?: boolean;\n noHexagons?: boolean;\n week?: number;\n watch?: boolean;\n shouldFail?: boolean;\n spelling?: boolean;\n force?: boolean;\n noWrite?: boolean;\n format?: boolean;\n pythonBin?: string;\n verbose?: boolean;\n envPlatform?: string;\n envProgram?: string;\n output?: 'md' | 'html';\n};\n\nexport type Context = {\n dirPath: string;\n buildDir: string;\n cacheDir: string;\n course: Course;\n options: Options;\n mmlStore?: string[];\n refStore: Record;\n figureCounter: number;\n};\n\nexport async function createContext(\n dirPath: string,\n options: Options = {}\n): Promise {\n return {\n course: await collectCoursework(dirPath),\n dirPath,\n buildDir: getBuildDir(dirPath),\n cacheDir: getCacheDir(dirPath),\n options,\n refStore: {},\n figureCounter: 0,\n };\n}\n","import path from 'path';\n\nimport kebabCase from 'lodash/kebabCase.js';\nimport { toVFile } from 'to-vfile';\n\nimport { checkLocalFileExists } from '../utils/utils';\nimport { loadCourseYaml } from './load-course';\nimport { loadUnitYaml } from './load-unit';\nimport {\n Course,\n CourseYaml,\n Unit,\n UnitTitles,\n UnitTitlesInput,\n} from './types';\nimport { FileRef } from './types';\n\nexport async function collectCoursework(dirPath: string): Promise {\n const course = await loadCourseYaml(dirPath);\n const coursePath = path.join(process.cwd(), dirPath);\n const units = await Promise.all(\n course.units.map((unit) => collectUnit(unit, course, dirPath))\n );\n return { ...course, coursePath, units };\n}\n\nasync function collectUnit(\n unit: FileRef,\n course: CourseYaml,\n dirPath: string\n): Promise {\n const { content, ...yaml } = await loadUnitYaml(dirPath, unit.src);\n const unitPath = path.join(process.cwd(), dirPath, unit.src);\n const files = await Promise.all(\n content.map(async (c) => {\n const filePath = path.resolve(dirPath, unit.src, '..', c.src);\n if (!(await checkLocalFileExists(filePath))) {\n throw new Error(`No Rmd file exists at ${filePath}`);\n }\n return toVFile.read(filePath, 'utf-8');\n })\n );\n const titles = getUnitTitles({\n courseTitle: course.title,\n unitName: yaml.name,\n unitTitle: yaml.title,\n });\n return { ...yaml, unitPath, parts: content, files, titles };\n}\n\nexport function getUnitTitles({\n courseTitle,\n unitName,\n unitTitle,\n}: UnitTitlesInput): UnitTitles {\n return {\n courseTitle,\n unitTitle: `${unitName}: ${unitTitle}`,\n unitName,\n docTitle: `${unitTitle} | ${courseTitle}`,\n fileName: kebabCase(unitName),\n };\n}\n","import path from 'path';\n\nimport yaml from 'js-yaml';\nimport * as yup from 'yup';\n\nimport { checkLocalFileExists, readFile } from '../utils/utils';\nimport { CourseYaml } from './types';\n\n// export const validCatalogValues = [\n// 'STATS5077',\n// 'STATS5078',\n// 'STATS5075',\n// 'STATS5084',\n// 'STATS5074',\n// 'STATS5081',\n// 'STATS5080',\n// 'STATS5073',\n// 'STATS5076',\n// 'STATS5079',\n// 'STATS5082',\n// 'STATS5094',\n// 'STATS5083',\n// ];\n\nconst courseSchema = yup.object().shape({\n title: yup.string().required(),\n units: yup.array().of(\n yup.object().shape({\n src: yup.string().required(),\n })\n ),\n catalog: yup.string(),\n authors: yup.string().required(),\n academic_year: yup.string().required(),\n});\n\nexport async function loadCourseYaml(dirPath: string) {\n const courseYamlPath = path.join(dirPath, 'course.yaml');\n if (!(await checkLocalFileExists(courseYamlPath))) {\n throw Error(\n `No course.yaml file exists in ${path.join(process.cwd(), dirPath)}`\n );\n }\n const fileContents = await readFile(courseYamlPath);\n const course = yaml.load(fileContents);\n return courseSchema.validateSync(course) as CourseYaml;\n}\n","import path from 'path';\n\nimport yaml from 'js-yaml';\nimport * as yup from 'yup';\n\nimport { checkLocalFileExists, readFile } from '../utils/utils';\nimport { UnitYaml } from './types';\n\nconst unitSchema = yup.object().shape({\n name: yup.string().required(),\n title: yup.string().required(),\n content: yup.array().of(\n yup.object().shape({\n src: yup.string().required(),\n })\n ),\n});\n\nexport async function loadUnitYaml(dirPath: string, src: string) {\n const contentsPath = path.join(dirPath, src);\n if (!(await checkLocalFileExists(contentsPath))) {\n throw Error(\n `No yaml file exists at ${path.join(process.cwd(), contentsPath)}`\n );\n }\n const fileContents = await readFile(contentsPath);\n const unit = yaml.load(fileContents);\n return unitSchema.validateSync(unit) as UnitYaml;\n}\n","import { Root } from 'mdast';\nimport rehypeRaw from 'rehype-raw';\nimport remark2rehype from 'remark-rehype';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { inlineRelativeAssets } from './inline-files';\nimport { responsiveTables } from './responsive-tables';\n\nexport async function hastPhase(\n mdast: Root,\n ctx: Context,\n file: VFile,\n targetPdf?: boolean\n) {\n const processor = unified()\n .use(remark2rehype, { allowDangerousHtml: true })\n .use(rehypeRaw)\n .use(responsiveTables);\n\n if (!ctx.options.noEmbedAssets) {\n processor.use(inlineRelativeAssets, ctx);\n }\n\n return processor.run(mdast, file);\n}\n","import path from 'path';\n\nimport { encode as base46Encode } from 'base64-arraybuffer';\nimport { Element, Properties } from 'hast';\nimport sizeOf from 'image-size';\nimport mimes from 'mime/lite.js';\nimport fetch from 'node-fetch';\nimport { toVFile } from 'to-vfile';\n// import { optimize } from 'svgo';\nimport { Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\n// import { pdfToSvg } from '../pdf/pdf-to-svg';\nimport { cacheToFile } from '../utils/cache-to-file';\nimport { getSvgHast } from '../utils/get-svg-hast';\nimport { failMessage } from '../utils/message';\nimport { readFile, rehypeParser } from '../utils/utils';\n\nexport function inlineRelativeAssets(ctx: Context) {\n return async (tree: Element, file: VFile) => {\n const transformations: Promise[] = [];\n visit(tree, 'element', (node) => {\n if (node.tagName === 'img') {\n transformations.push(embed(node, file, ctx));\n }\n });\n await Promise.all(transformations);\n };\n}\n\nasync function embed(node: Element, file: VFile, ctx: Context) {\n const src = getImageSrc(node);\n const parsed = path.parse(src);\n try {\n switch (parsed.ext) {\n case '.png':\n case '.jpg':\n case '.jpeg':\n case '.gif':\n return await embedImage(node, ctx, file);\n case '.svg':\n return await embedSvg(node, ctx);\n case '.pdf':\n // return await embedPdfSvg(node);\n throw new Error(\n `Unhandled file extension: .pdf (convert to .svg)`\n );\n case '.html':\n return await embedHtml(node);\n default:\n throw new Error(`Unhandled file extension: ${parsed.ext}`);\n }\n } catch (_err) {\n console.log(_err);\n const err = _err as Error;\n failMessage(file, err?.message || '', node.position);\n }\n}\n\nasync function embedImage(node: Element, ctx: Context, file: VFile) {\n const src = getImageSrc(node);\n const mime = mimes.getType(path.extname(src));\n try {\n const image = await getImage(src, ctx);\n const { width } = sizeOf(Buffer.from(image, 'base64'));\n node.properties = {\n ...node.properties,\n src: `data:${mime};base64,${image}`,\n style: [`max-width: ${width}px`],\n };\n } catch (err) {\n console.log(err);\n failMessage(file, `Image not found: ${src}`);\n }\n}\n\nasync function embedSvg(imgNode: Element, ctx: Context) {\n const src = getImageSrc(imgNode);\n const contents = await readFile(src);\n const idx = contents.indexOf(' String(x)).filter((s) => s !== removeClass);\n }\n return [];\n}\n\nfunction getImageSrc(node: Element) {\n const properties = (node.properties || {}) as { src: string };\n if (!properties.src) {\n throw new Error('Image has no src');\n }\n return properties.src;\n}\n\nasync function getImage(src: string, ctx: Context) {\n if (src.startsWith('http')) {\n return cacheToFile({\n ctx,\n prefix: 'youtube',\n key: src,\n execFn: getImageDataFromWeb,\n });\n }\n return readFile(src, 'base64');\n}\n\nasync function getImageDataFromWeb(src: string) {\n const response = await fetch(src);\n const buffer = await response.arrayBuffer();\n return base46Encode(buffer);\n}\n\n// async function embedPdfSvg(imgNode: Element) {\n// const src = getImageSrc(imgNode);\n// const svgNode = (await pdfToSvg(src)) as Element;\n// console.log('hey!');\n// console.log(svgNode);\n\n// const properties = {\n// ...imgNode.properties,\n// ...svgNode.properties,\n// } as Properties;\n\n// delete properties.src;\n\n// Object.assign(imgNode, svgNode, { properties });\n// }\n\nasync function embedHtml(imgNode: Element) {\n const src = getImageSrc(imgNode);\n const value = await readFile(src);\n const vfile = toVFile({ value });\n const parsed = rehypeParser().parse(vfile) as Parent;\n\n Object.assign(imgNode, {\n tagName: 'div',\n properties: {\n className: 'interactive-element',\n },\n children: parsed.children,\n });\n}\n","import { Element } from 'hast';\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\ntype ParentProps = {\n className: string[];\n};\n\nexport function responsiveTables() {\n return async (tree: Element, file: VFile) => {\n visit(tree, 'element', (node, idx, _parent) => {\n if (node.tagName !== 'table') {\n return;\n }\n\n const parent = _parent as Element;\n const properties = (parent?.properties || {}) as ParentProps;\n const className = properties.className || [];\n\n if (!className.includes('table-wrapper')) {\n Object.assign(node, {\n tagName: 'div',\n properties: {\n className: 'table-wrapper',\n },\n children: [cloneDeep(node)],\n });\n }\n });\n };\n}\n","import path from 'path';\n\nimport { Parent as HastParent, Root } from 'hast';\nimport startCase from 'lodash/startCase.js';\nimport { Parent as MdastParent } from 'mdast';\nimport doc, { Options } from 'rehype-document';\nimport format from 'rehype-format';\nimport stringify from 'rehype-stringify';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { Unit } from '../course/types';\nimport { getTemplateDir, readFile } from '../utils/utils';\nimport { pdfWrapper } from './pdf';\nimport { htmlWrapper } from './wrapper';\n\nexport async function htmlPhase(\n hast: HastParent,\n mdast: MdastParent,\n file: VFile,\n unit: Unit,\n ctx: Context,\n targetPdf?: boolean\n) {\n const processor = unified().use(stringify, { allowDangerousHtml: true });\n\n if (ctx.options.format) {\n // hangs in some scenarios so off by default, useful in tests\n processor.use(format);\n }\n\n if (!ctx.options.noDoc) {\n const cssPath = path.join(getTemplateDir(), 'template.css');\n const docOptions: Options = {\n title: unit.titles.docTitle,\n style: `\\n${await readFile(cssPath)}\\n`,\n };\n\n if (!targetPdf) {\n const jsPath = path.join(getTemplateDir(), 'template.js2');\n docOptions.script = `\\n${await readFile(jsPath)}\\n`;\n processor.use(htmlWrapper, unit, mdast, ctx);\n } else {\n processor.use(pdfWrapper, unit, ctx);\n }\n\n processor.use(doc, docOptions);\n }\n\n const transformed = await processor.run(hast as Root, file);\n\n const result = processor.stringify(transformed, file);\n\n return postTransforms(result, ctx);\n}\n\nfunction postTransforms(html: string, ctx: Context) {\n let result = '';\n result = referenceTransform(html, ctx.refStore);\n return result;\n}\n\nfunction referenceTransform(html: string, refStore: Context['refStore']) {\n return html.replace(/ref:\\/\\/(\\w+)/gms, (...match) => {\n const key = match[1];\n const link = refStore[key];\n const name = startCase(link);\n return `${name}`;\n });\n}\n","import { Node, Parent } from 'unist';\n\nimport { Context } from '../context';\nimport { Unit } from '../course/types';\n// import { UnitTitles } from '../course/types';\nimport { createDefs } from '../utils/icons';\nimport { createMain } from './wrapper/main';\n\nexport function pdfWrapper(unit: Unit, ctx: Context) {\n return async (tree: Node) => {\n const main = await createMain(\n unit.titles,\n ctx,\n (tree as Parent).children\n );\n const iconDefs = createDefs();\n return {\n type: 'root',\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'root',\n className: ['hide-sidebar', 'font-default', 'pdf'],\n },\n children: [iconDefs, main],\n },\n ],\n };\n };\n}\n","import { Parent } from 'mdast';\n\nimport { Context } from '../../context';\nimport { Unit } from '../../course/types';\nimport { createDefs, createSvg } from '../../utils/icons';\nimport { createMain } from './main';\nimport { createSidebar } from './sidebar';\n\nexport function htmlWrapper(unit: Unit, mdast: Parent, ctx: Context) {\n return async (tree: Parent) => {\n const hamburgerIcon = createSvg('hamburger-icon');\n const sidebar = await createSidebar(mdast);\n const main = await createMain(unit.titles, ctx, tree.children);\n const iconDefs = createDefs();\n return {\n type: 'root',\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'root',\n className: ['hide-sidebar'],\n },\n children: [iconDefs, main, hamburgerIcon, sidebar],\n },\n ],\n };\n };\n}\n","import { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport dagLogoSvg from '../../../assets/dag-logo.svg';\nimport coverSvg from '../../../assets/hexagons.svg';\nimport { Context } from '../../context';\nimport { Course, UnitTitles } from '../../course/types';\nimport { getAssetHast } from '../../utils/get-asset-hast';\n\nexport async function createMain(\n titles: UnitTitles,\n ctx: Context,\n content: Node[]\n) {\n const children = [];\n\n if (ctx.options.noHexagons) {\n children.push(createH1(titles));\n } else {\n children.push(createCover(titles, ctx.course));\n }\n\n children.push(...content);\n\n return {\n type: 'element',\n tagName: 'main',\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'wrapper',\n },\n children,\n },\n ],\n };\n}\n\nfunction createCover(titles: UnitTitles, course: Course) {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'cover',\n },\n children: [\n createH1(titles),\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'logos',\n },\n children: [\n createCoverHexagons(course.catalog || ''),\n getAssetHast(dagLogoSvg),\n ],\n },\n ],\n };\n}\n\nfunction createH1(titles: UnitTitles) {\n return {\n type: 'element',\n tagName: 'h1',\n children: [\n {\n type: 'text',\n value: titles.courseTitle,\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'unit',\n },\n children: [\n {\n type: 'text',\n value: titles.unitTitle,\n },\n ],\n },\n ],\n };\n}\n\nfunction createCoverHexagons(catalog: string) {\n const hexagons = getAssetHast(coverSvg);\n\n if (catalog !== '') {\n visit(hexagons, 'element', (node) => {\n if (node.tagName === 'g') {\n const properties = node.properties || {};\n const [className] = (properties.className || []) as string[];\n if (catalog === className) {\n properties.className = ['active'];\n } else {\n properties.className = [];\n }\n node.properties = properties;\n }\n });\n }\n\n return hexagons;\n}\n","import { Parent, Root } from 'mdast';\nimport { toHast } from 'mdast-util-to-hast';\nimport { toc as getToc } from 'mdast-util-toc';\n\nimport crestSvg from '../../../assets/crest.svg';\nimport uOfGSvg from '../../../assets/uofg.svg';\nimport { getAssetHast } from '../../utils/get-asset-hast';\nimport { createSvg } from '../../utils/icons';\nimport {\n createViewOptions,\n createViewOptionsButton,\n} from './view-options';\n\nexport async function createSidebar(mdast: Parent) {\n const logo = await createLogo();\n const toc = getToc(mdast as Root, { maxDepth: 3 }).map;\n const tocChildren = toc === null ? [] : [toHast(toc)];\n\n return {\n type: 'element',\n tagName: 'aside',\n children: [\n logo,\n createViewOptionsButton(),\n {\n type: 'element',\n tagName: 'nav',\n properties: {\n id: 'toc',\n },\n children: tocChildren,\n },\n {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'view-options',\n },\n children: createViewOptions(),\n },\n ],\n };\n}\n\nasync function createLogo() {\n const crest = getAssetHast(crestSvg);\n const uofg = getAssetHast(uOfGSvg);\n const hamburgerIcon = createSvg('hamburger-icon');\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'logo',\n },\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'logo-wrapper',\n },\n children: [crest, uofg],\n },\n hamburgerIcon,\n ],\n };\n}\n","import { Item } from './shared';\n\ntype ReadabilityItem = Item & {\n min: number;\n max: number;\n increment: number;\n};\n\nconst options: ReadabilityItem[] = [\n {\n value: 'fontSize',\n label: 'Font-size',\n min: 0.6,\n max: 2,\n increment: 0.1,\n },\n {\n value: 'lineSpacing',\n label: 'Line spacing',\n min: 0.6,\n max: 2,\n increment: 0.1,\n },\n {\n value: 'letterSpacing',\n label: 'Letter spacing',\n min: -0.1,\n max: 0.2,\n increment: 0.05,\n },\n {\n value: 'lineWidth',\n label: 'Line width',\n min: 0.6,\n max: 1.2,\n increment: 0.05,\n },\n];\n\nexport function createReadabilityList() {\n return {\n type: 'element',\n tagName: 'ul',\n properties: {\n id: 'readability',\n },\n children: options.map(createOption),\n };\n}\n\nfunction createOption(item: ReadabilityItem) {\n return {\n type: 'element',\n tagName: 'li',\n properties: {\n className: [item.value],\n 'data-min': item.min,\n 'data-max': item.max,\n 'data-increment': item.increment,\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['label'],\n },\n children: [\n {\n type: 'text',\n value: item.label,\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['actions'],\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['btn', 'minus'],\n },\n children: [\n {\n type: 'text',\n value: '−',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['btn', 'plus'],\n },\n children: [\n {\n type: 'text',\n value: '+',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['btn', 'reset'],\n },\n children: [\n {\n type: 'text',\n value: 'Reset',\n },\n ],\n },\n ],\n },\n ],\n };\n}\n","import { Item } from './shared';\n\nconst themes: Item[] = [\n {\n value: 'light',\n label: 'Light',\n },\n {\n value: 'dark',\n label: 'Dark',\n },\n {\n value: 'yellow-on-black',\n label: 'Yellow on Black',\n },\n {\n value: 'black-on-yellow',\n label: 'Black on Yellow',\n },\n {\n value: 'black-on-red',\n label: 'Black on Red',\n },\n {\n value: 'black-on-blue',\n label: 'Black on Blue',\n },\n];\n\nexport function createThemeList() {\n return {\n type: 'element',\n tagName: 'ul',\n properties: {\n id: 'themes',\n },\n children: themes.map(createThemeButton),\n };\n}\n\nfunction createThemeButton(theme: Item) {\n return {\n type: 'element',\n tagName: 'li',\n properties: {\n className: [theme.value],\n },\n children: [\n {\n type: 'text',\n value: theme.label,\n },\n ],\n };\n}\n","import { Node } from 'unist';\n\n// import { createFontList } from './font';\nimport { createReadabilityList } from './readability';\nimport { createThemeList } from './theme';\n\nexport function createViewOptionsButton() {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'view-options-toggle',\n },\n children: [\n {\n type: 'text',\n value: 'View options',\n },\n ],\n };\n}\n\nexport function createViewOptions(): Node[] {\n return [\n createTitle('Theme'),\n createThemeList(),\n // createTitle('Font'),\n // createFontList(),\n createTitle('Readability'),\n createReadabilityList(),\n ];\n}\n\nfunction createTitle(value: string) {\n return {\n type: 'element',\n tagName: 'h3',\n children: [\n {\n type: 'text',\n value,\n },\n ],\n };\n}\n","import path from 'path';\n\nimport chalk from 'chalk';\n\nimport { BuiltUnit, buildUnit } from './build-unit';\nimport { Context, Options, createContext } from './context';\nimport { checkForLatestVersion } from './utils/check-for-latest-version';\nimport { Timer, createTimer } from './utils/timer';\nimport { mkdir, writeFile } from './utils/utils';\n\nexport async function rMarkdown(dirPath: string, options: Options = {}) {\n if (!options.output) {\n await checkForLatestVersion();\n }\n\n const timer = createTimer();\n const ctx = await createContext(dirPath, options);\n\n const result = [];\n\n if (ctx.options.week) {\n // write single week\n const idx = ctx.options.week - 1;\n const input = ctx.course.units[idx];\n\n if (input === undefined) {\n const courseYaml = path.join(ctx.dirPath, 'course.yaml');\n throw new Error(\n `Week ${ctx.options.week} not found in ${courseYaml}`\n );\n }\n\n const built = await buildUnit(input, ctx);\n await writeUnit(built, ctx, timer);\n result.push(built);\n } else {\n // write full course\n for (const input of ctx.course.units) {\n const built = await buildUnit(input, ctx);\n await writeUnit(built, ctx, timer);\n result.push(built);\n }\n }\n\n return result;\n}\n\nasync function writeUnit(built: BuiltUnit, ctx: Context, timer: Timer) {\n if (ctx.options.noWrite) {\n return;\n }\n\n await mkdir(ctx.buildDir);\n const filePath = path.join(ctx.buildDir, built.unit.titles.fileName);\n\n if (built.html) {\n await writeFile(filePath + '.html', built.html.html);\n\n if (!ctx.options.output) {\n const status = chalk.green.bold(`Complete in ${timer.seconds()}s`);\n console.log(`✨ ${status} ${filePath}.html`);\n }\n }\n\n if (built.pdf) {\n await writeFile(filePath + '.pdf', built.pdf.pdf);\n\n // debug\n // await writeFile(filePath + '.pdf.html', built.pdf.html);\n\n if (!ctx.options.output) {\n const status = chalk.green.bold(`Complete in ${timer.seconds()}s`);\n console.log(`✨ ${status} ${filePath}.pdf`);\n }\n }\n}\n","import { exec } from 'child_process';\nimport { EOL } from 'os';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nimport chalk from 'chalk';\nimport hashSum from 'hash-sum';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { Unit } from '../course/types';\nimport { infoMessage, warnMessage } from '../utils/message';\nimport { mkdir, rmFile, writeFile } from '../utils/utils';\n\n// bypass knitr for debugging\n// export async function knitr(unit: Unit, ctx: Context) {\n// const file = new VFile();\n\n// file.value = unit.files.reduce((acc, o) => {\n// return acc + EOL + EOL + o.value;\n// }, '');\n\n// return file;\n// }\n\nexport async function knitr(unit: Unit, ctx: Context) {\n const parentFile = await createParentFile(unit, ctx);\n // console.log(parentFile.value);\n\n const result = await execKnitr(parentFile, ctx, unit.unitPath);\n // console.log(result);\n parentFile.value = result;\n return parentFile;\n}\n\n// creating a temporary file which includes all child files allows\n// R/Python state to be shared across multiple .Rmd files\n// https://yihui.org/knitr/options/#child-documents\nasync function createParentFile(unit: Unit, ctx: Context) {\n const file = new VFile();\n\n let value = '';\n\n // pass path to custom python binary to reticulate\n // https://rstudio.github.io/reticulate/articles/r_markdown.html\n if (ctx.options.pythonBin) {\n const reticulate = `reticulate::use_python(\"${ctx.options.pythonBin}\")`;\n value += `\\`\\`\\`{r, echo=FALSE}${EOL}${reticulate}${EOL}\\`\\`\\`${EOL}${EOL}`;\n }\n\n value += unit.files.reduce((acc, o) => {\n const [filePath] = o.history;\n\n // directory directive is used to ensure external assets\n // can have relative paths to the .Rmd document.\n // used in embed-asset-url mdast transform\n const fileDir = path.parse(filePath).dir;\n const directive = `:directory[${fileDir}]`;\n\n // child document\n // convert all file paths to forward slash (windows anaconda/knitr bug)\n const formattedPath = path\n .relative(ctx.cacheDir, filePath)\n .replace(/\\\\/g, '/');\n\n const childCodeBlock = `\\`\\`\\`{r, child='${formattedPath}'}${EOL}\\`\\`\\``;\n return acc + directive + EOL + EOL + childCodeBlock + EOL + EOL;\n }, '');\n\n // console.log(value);\n\n file.value = value;\n return file;\n}\n\nasync function execKnitr(file: VFile, ctx: Context, unitPath: string) {\n const md = file.value as string;\n const uniqueId = getUniqueId(md);\n const cachedFile = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n const cacheDir = path.join(ctx.cacheDir, uniqueId);\n await mkdir(cacheDir);\n await writeFile(cachedFile, md);\n\n return new Promise((resolve, reject) => {\n const cmd = createKnitrCommand(ctx, uniqueId, unitPath);\n\n exec(cmd, async (err, response, stdErr) => {\n if (stdErr) {\n console.log(chalk.grey(`[knitr] ${stdErr.trim()}`));\n }\n if (err) {\n console.error('ERROR', err);\n reject(err);\n } else {\n reportErrors(response, file, ctx);\n resolve(formatResponse(response));\n }\n await rmFile(cachedFile);\n });\n });\n}\n\nfunction getUniqueId(md: string) {\n const hash = hashSum(md);\n const ts = new Date().getTime().toString();\n return `knitr-${hash}-${ts}`;\n}\n\nfunction createKnitrCommand(\n ctx: Context,\n uniqueId: string,\n unitPath: string\n) {\n const rFileDir = getKnitrFileDir();\n const rFile = path.join(rFileDir, 'knitr.R');\n const baseDir = path.parse(unitPath).dir;\n const cachedFile = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n const cacheDir = path.join(ctx.cacheDir, uniqueId);\n\n // spawn args\n // return [rFile, cachedFile, baseDir, cacheDir];\n\n return `Rscript \"${rFile}\" \"${cachedFile}\" \"${baseDir}\" \"${cacheDir}\"`;\n}\n\nfunction getKnitrFileDir() {\n // temporary hack until this PR is merged\n // https://github.com/webpack/webpack/pull/15246\n if (process.env.NODE_ENV === 'production') {\n return __dirname;\n }\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\nfunction reportErrors(response: string, file: VFile, ctx: Context) {\n const lines = response\n .split(EOL)\n .filter((s) => !s.startsWith(':directory'));\n\n const trimmed = lines.join(EOL).trim();\n\n // Warning at the start of a document\n if (trimmed.startsWith('WARNING -')) {\n const match = trimmed.match(/^WARNING - (.+?)[\\r\\n]{2,}/ms);\n\n // Check the original file doesn't start with WARNING\n const original = String(ctx.course.units[0].files[0].value)\n .split(EOL)\n .filter((s) => !s.startsWith(':directory'))\n .join(EOL)\n .trim();\n\n if (match !== null && !original.startsWith('WARNING -')) {\n warnMessage(file, match[1], {\n start: {\n line: 1,\n column: 0,\n },\n end: {\n line: 1,\n column: lines[0].length,\n },\n });\n }\n\n // Python binary path\n } else if (trimmed.startsWith('$python [1]')) {\n const match = trimmed.match(/^\\$python\\s\\[1\\]\\s(\"\\S+\")/);\n if (match !== null) {\n infoMessage(file, match[1], {\n start: {\n line: 1,\n column: 0,\n },\n end: {\n line: 1,\n column: lines[0].length,\n },\n });\n }\n }\n\n // Errors throughout document\n lines.forEach((line, idx) => {\n const trimmedLine = line.trim();\n if (trimmedLine.startsWith('## Error')) {\n warnMessage(file, trimmedLine.replace('## ', ''), {\n start: {\n line: idx + 1,\n column: 0,\n },\n end: {\n line: idx + 1,\n column: line.length,\n },\n });\n }\n });\n}\n\nasync function formatResponse(response: string) {\n let md = response;\n md = removeCustomPythonBinNotice(md);\n md = removePythonWarningMessage(md);\n md = addCodeBlockClasses(md);\n md = addErrorCodeBlock(md);\n md = removeHashSigns(md);\n md = removeEmptyLog(md);\n md = addNewLineAfterKable(md);\n return md;\n}\n\nfunction removeCustomPythonBinNotice(md: string) {\n return md.replace(/^\\$python\\s\\[1\\]\\s\"\\S+\"/, '');\n}\n\nfunction removePythonWarningMessage(md: string) {\n return md.replace(/^WARNING - .+?[\\r\\n]+/m, '');\n}\n\nfunction addCodeBlockClasses(md: string) {\n return md\n .split('\\n')\n .reduce((acc: string[], line) => {\n if (line.startsWith('```{.knitr-output}')) {\n const lang = findLanguageForOutput(acc);\n acc.push(`\\`\\`\\`{.${lang}-output}`);\n } else {\n acc.push(line);\n }\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction removeHashSigns(md: string) {\n let insideCodeResponse = false;\n let openingLine = '';\n return md\n .split('\\n')\n .reduce((acc: string[], line) => {\n if (line.startsWith('```')) {\n insideCodeResponse = !insideCodeResponse;\n openingLine = insideCodeResponse ? line : '';\n }\n if (insideCodeResponse && openingLine.endsWith('-output}')) {\n acc.push(line.replace(/^##\\s+/, ''));\n } else {\n acc.push(line);\n }\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction removeEmptyLog(md: string) {\n return md.replace(/\\[1\\]\\s\"\"$/gm, '').trim();\n}\n\nfunction addErrorCodeBlock(md: string) {\n return md\n .split('\\n')\n .reduce((acc: string[], line, idx) => {\n if (line.startsWith('## Error') && acc[idx - 1].startsWith('```')) {\n const lang = findLanguageForOutput(acc.slice(0, -1));\n acc[acc.length - 1] = `\\`\\`\\`{.${lang}-error-output}`;\n }\n acc.push(line);\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction addNewLineAfterKable(md: string) {\n return md\n .split('\\n')\n .reduce((acc: string[], line, idx) => {\n if (acc[idx - 1]?.startsWith('|') && !line.startsWith('|')) {\n acc.push('', line);\n } else {\n acc.push(line);\n }\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction findLanguageForOutput(prev: string[]) {\n const pattern = /```(\\w*)/;\n const reversed = prev.slice().reverse();\n const prevClosingIdx = reversed.findIndex((s) => s.startsWith('```'));\n const prevOpening = reversed\n .slice(prevClosingIdx + 1)\n .find((s) => pattern.test(s)) as string;\n\n if (!prevOpening) {\n return 'r';\n }\n\n const match = prevOpening.match(pattern) as RegExpMatchArray;\n return match[1];\n}\n\n// experimental streaming output\n// async function spawnKnitr(file: VFile, ctx: Context, unitPath: string) {\n// const md = file.value as string;\n// const uniqueId = getUniqueId(md);\n// const cachedFile = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n// const cacheDir = path.join(ctx.cacheDir, uniqueId);\n// await mkdir(cacheDir);\n// await writeFile(cachedFile, md);\n\n// return new Promise((resolve, reject) => {\n// const args = createKnitrCommand(ctx, uniqueId, unitPath);\n// const knitr = spawn('Rscript', args);\n// const result: string[] = [];\n\n// knitr.stdout.on('data', (data) => {\n// const str = data.toString();\n// console.log(str);\n// result.push(str);\n// });\n\n// knitr.stdout.on('end', () => {\n// console.log('STDOUT END');\n// const end = result.join('');\n// console.log('END', end);\n// reportErrors(end, file);\n// resolve(formatResponse(end));\n// });\n\n// knitr.stdout.on('error', (err) => {\n// console.log('STDOUT ERROR', err, err.toString());\n// reject();\n// });\n\n// knitr.stderr.on('data', (data) => {\n// const str = data.toString();\n// console.log('STDERR ERROR', str);\n// });\n// }).then(async (result) => {\n// await rmFile(cachedFile);\n// return result;\n// });\n// }\n","import { Element, Literal } from 'hast';\nimport { Parent, Root } from 'mdast';\nimport { TextDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\nimport { rehypeParser } from '../utils/utils';\nimport { mmlToSpeech, mmlToSvg } from './mathjax-tex';\n\nexport function aliasDirectiveToSvg(ctx: Context) {\n return (tree: Root) => {\n visit(tree, 'textDirective', (node) => {\n if (!ctx.mmlStore || ctx.options.noTexSvg) {\n return;\n }\n switch (node.name) {\n case 'inlineMath':\n case 'blockMath': {\n const idx = getTexIdx(node as TextDirective);\n const mml = ctx.mmlStore[idx];\n const svg = renderSvg(mml);\n const properties = {\n ...svg.properties,\n className:\n node.name === 'inlineMath' ? 'inline-math' : 'block-math',\n id: getRefId(mml),\n };\n node.data = {\n hName: svg.tagName,\n hProperties: properties,\n hChildren: svg.children,\n };\n }\n }\n });\n };\n}\n\nfunction getTexIdx(node: Parent) {\n const firstChild = node.children[0] as Literal;\n return Number(firstChild.value || 0);\n}\n\nfunction getRefId(mml: string) {\n const match = mml.match(/;\n\n const newProperties: Record = {\n width: properties.width,\n height: properties.height,\n viewBox: properties.viewBox,\n role: 'img',\n };\n\n if (label !== '') {\n const uniqueId = `math-${Math.random().toString(16).slice(2)}`;\n newProperties['aria-labelledby'] = uniqueId;\n svg.children.unshift({\n type: 'element',\n tagName: 'title',\n properties: {\n id: uniqueId,\n },\n children: [\n {\n type: 'text',\n value: label,\n },\n ],\n });\n }\n\n svg.properties = newProperties;\n return svg;\n}\n","import { liteAdaptor } from 'mathjax-full/js/adaptors/liteAdaptor.js';\nimport { STATE } from 'mathjax-full/js/core/MathItem.js';\nimport { SerializedMmlVisitor } from 'mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js';\nimport { RegisterHTMLHandler } from 'mathjax-full/js/handlers/html.js';\nimport { HTMLDocument } from 'mathjax-full/js/handlers/html/HTMLDocument.js';\nimport { MathML } from 'mathjax-full/js/input/mathml.js';\nimport { TeX } from 'mathjax-full/js/input/tex.js';\nimport { AllPackages } from 'mathjax-full/js/input/tex/AllPackages.js';\nimport { mathjax } from 'mathjax-full/js/mathjax.js';\nimport { SVG } from 'mathjax-full/js/output/svg.js';\n// @ts-expect-error\nimport SRE from 'speech-rule-engine';\n\nexport function texToMml(tex: string = '') {\n const adaptor = liteAdaptor();\n // Busproofs requires an output jax, which we aren't using\n const packages = AllPackages.filter((name) => name !== 'bussproofs');\n const input = new TeX({ packages });\n const doc = new HTMLDocument('', adaptor, { InputJax: input });\n const node = doc.convert(tex, { end: STATE.CONVERT });\n const visitor = new SerializedMmlVisitor();\n return visitor.visitTree(node);\n}\n\nexport function mmlToSvg(mml: string) {\n const adaptor = liteAdaptor();\n RegisterHTMLHandler(adaptor);\n const input = new MathML();\n const output = new SVG({ fontCache: 'local' });\n const doc = mathjax.document('', { InputJax: input, OutputJax: output });\n const node = doc.convert(mml, { em: 25 });\n return adaptor.outerHTML(node);\n}\n\nexport function mmlToSpeech(mml: string) {\n return SRE.toSpeech(mml);\n}\n","import { liteAdaptor } from 'mathjax-full/js/adaptors/liteAdaptor.js';\nimport { MathDocument } from 'mathjax-full/js/core/MathDocument.js';\nimport * as MathItem from 'mathjax-full/js/core/MathItem.js';\nimport { SerializedMmlVisitor } from 'mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js';\nimport { RegisterHTMLHandler } from 'mathjax-full/js/handlers/html.js';\nimport { TeX } from 'mathjax-full/js/input/tex.js';\nimport { AllPackages } from 'mathjax-full/js/input/tex/AllPackages.js';\nimport { mathjax } from 'mathjax-full/js/mathjax.js';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { assertNoTexTabular } from '../linter/assert-no-tex-tabular';\nimport { failMessage } from '../utils/message';\n\n// This custom MathJax implementation has had to diverge from the provided demos found\n// here: https://github.com/mathjax/MathJax-demos-node, because they are all focused on\n// either converting LaTeX on its own or (referencing \"page\" demos) LaTeX embedded in\n// HTML, whereas at this stage in the processor we're dealing with LaTeX embedded in\n// Markdown. Due to TeX/LaTeX making heavy use of the backslash (\\) character, we need\n// to deal with it early as it conflicts with other libraries used later.\n\n// I use the MathJax \"page\" process as it will pick up LaTeX even without delimiters\n// and stores context required for numbered references (based on direct/tex2mml-page).\n// However this has a naive HTML handler which will munge HTML (and Python) in some\n// cases so I am careful to only mutate TeX and leave the rest of the Markdown alone.\n\n// I replace the TeX with a placeholder formatted as a Markdown directive, for example\n// :inlineMath[21] or :blockMath[42].\n\n// I convert the TeX to MathML and store it memory for use later (in directive-to-svg.ts).\n\nexport function texToAliasDirective(file: VFile, ctx: Context) {\n // simple regex tests\n assertNoTexTabular(file);\n\n const md = file.value as string;\n const store: string[] = [];\n const adaptor = liteAdaptor();\n const visitor = new SerializedMmlVisitor();\n RegisterHTMLHandler(adaptor);\n\n const doc = mathjax.document(md, {\n InputJax: new TeX({\n // Bussproofs requires an output jax\n packages: AllPackages.filter((name) => name !== 'bussproofs'),\n // Allow numbered references\n tags: 'ams',\n // Allow single $ delimiters\n inlineMath: [\n ['$', '$'],\n ['\\\\(', '\\\\)'],\n ],\n displayMath: [\n ['$$', '$$'],\n [`\\\\[`, `\\\\]`],\n ],\n }),\n // wrap verbatim latex with
\n ignoreHtmlClass: 'mathjax-ignore',\n renderActions: {\n typeset: [\n MathItem.STATE.TYPESET,\n ({ math }: MathDocument) => {\n for (const item of Array.from(math)) {\n let newMarkdown = '';\n\n // convert to MathML\n const mml = visitor.visitTree(item.root);\n assertNoMmlError(mml, file);\n\n // escaped dollar sign...\n if (item.math === '$') {\n newMarkdown = '$';\n }\n\n // double backslash...\n else if (item.math === '\\\\') {\n newMarkdown = '\\\\\\\\';\n }\n\n // reference link...\n else if (isReferenceLink(item.math)) {\n const refNum = extractRefNumFromMml(mml, item.math, file);\n const anchor = extractAnchorLinkFromMml(\n mml,\n item.math,\n file\n );\n newMarkdown = `[${refNum}](${anchor})`;\n }\n\n // normal use case (equation)...\n else {\n store.push(mml);\n const type = item.display ? 'blockMath' : 'inlineMath';\n newMarkdown = `:${type}[${store.length - 1}]`;\n }\n\n const tree = adaptor.parse(newMarkdown, 'text/html');\n item.typesetRoot = adaptor.firstChild(adaptor.body(tree));\n }\n },\n ],\n },\n });\n\n // add store to ctx\n ctx.mmlStore = store;\n\n doc.render();\n\n // replace md in VFile\n const result = adaptor.innerHTML(adaptor.body(doc.document));\n file.value = postParse(result);\n\n return file;\n}\n\nfunction assertNoMmlError(mml: string, file: VFile) {\n const match = mml.match(/(.+)<\\/mtext>/);\n if (match === null) {\n failMessage(file, `Invalid reference: ${tex}`);\n return;\n }\n if (match[1] === '???') {\n failMessage(\n file,\n `Invalid reference: ${tex}. You may only reference numbered sections.`\n );\n }\n return match[1] as string;\n}\n\nfunction extractAnchorLinkFromMml(mml: string, tex: string, file: VFile) {\n const match = mml.match(//);\n if (match === null) {\n failMessage(file, `Reference has no anchor link: ${tex}`);\n return;\n }\n return decodeURIComponent(match[1] || '') as string;\n}\n\nfunction postParse(html: string) {\n let result = html;\n result = unprotectHtml(result);\n result = removeUnresolvedLabels(result);\n return result;\n}\n\n// https://github.com/mathjax/MathJax-src/blob/41565a97529c8de57cb170e6a67baf311e61de13/ts/adaptors/lite/Parser.ts#L399-L403\nfunction unprotectHtml(html: string) {\n return html\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nfunction removeUnresolvedLabels(html: string) {\n return html.replace(/\\\\label{def:.*?}/gm, '');\n}\n","import { Image } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\nimport { checkLocalFileExists } from '../utils/utils';\n\nexport function assertAssetExists() {\n async function getAssetUrl(node: Image, file: VFile) {\n const url = (node.url || '') as string;\n if (!file.dirname) {\n throw new Error('VFile dirname undefined');\n }\n if (!url.startsWith('http')) {\n const exists = await checkLocalFileExists(url);\n if (!exists) {\n failMessage(file, `No asset found at ${url}`, node.position);\n }\n }\n }\n\n return async (tree: Node, file: VFile) => {\n const transformations: Promise[] = [];\n visit(tree, 'image', (node) => {\n transformations.push(getAssetUrl(node, file));\n });\n await Promise.all(transformations);\n };\n}\n","import { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertColumnStructure() {\n return (tree: Root, file: VFile) => {\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, index, _parent) => {\n if (node.name === 'columns') {\n const children = node.children as ContainerDirective[];\n const columns = children.filter((o) => o.name === 'column');\n if (columns.length < 2) {\n failMessage(\n file,\n 'Columns must contain at least 2 columns',\n node.position\n );\n }\n }\n if (node.name === 'column') {\n const parent = _parent as ContainerDirective;\n if (!parent || parent.name !== 'columns') {\n failMessage(\n file,\n 'Column must be nested inside columns',\n node.position\n );\n }\n }\n }\n );\n };\n}\n","import { Root } from 'mdast';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertNoH1() {\n return (tree: Root, file: VFile) => {\n visit(tree, 'heading', (node) => {\n if (node.depth === 1) {\n failMessage(\n file,\n 'Level 1 heading found. Only one Level 1 heading can be used in the document and it is automatically generated from .yaml file and should not be found in .Rmd file. Please use Level 2 (## Example) and below.',\n node.position\n );\n return;\n }\n });\n };\n}\n","import { VFile } from 'vfile';\n\nimport { warnMessage } from '../utils/message';\n\nexport function assertNoImageAttributes(file: VFile) {\n const md = file.value as string;\n md.split('\\n').forEach((line, idx) => {\n const match = line.match(/!\\[.*\\]\\(.*\\)({.+})/);\n if (match !== null) {\n warnMessage(\n file,\n `image attributes are not supported: ${match[1]}`,\n {\n start: {\n line: idx + 1,\n column: 0,\n },\n end: {\n line: idx + 1,\n column: line.length,\n },\n }\n );\n }\n });\n}\n","import { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\n// TODO: could possibly try converting to array here\n// https://stackoverflow.com/questions/51803244\n\nexport function assertNoTexTabular(file: VFile) {\n const md = file.value as string;\n md.split('\\n').forEach((line, idx) => {\n if (line.includes('\\\\begin{tabular}')) {\n failMessage(\n file,\n 'LaTeX tables are not allowed, please use Markdown syntax',\n {\n start: {\n line: idx + 1,\n column: 0,\n },\n end: {\n line: idx + 1,\n column: line.length,\n },\n }\n );\n }\n });\n}\n","import { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertTaskAnswerStructure() {\n return (tree: Root, file: VFile) => {\n let count = 0;\n visit(tree, 'containerDirective', (node, index, _parent) => {\n if (node.name === 'task') {\n count++;\n const children = node.children as ContainerDirective[];\n const answers = children.filter((o) => o.name === 'answer');\n if (answers.length < 1) {\n failMessage(file, `Task ${count} has no answer`, node.position);\n }\n if (answers.length > 1) {\n failMessage(file, 'Task has multiple answers', node.position);\n }\n }\n if (node.name === 'answer') {\n const parent = _parent as ContainerDirective;\n if (!parent || parent.name !== 'task') {\n failMessage(\n file,\n 'Answer must be nested inside task',\n node.position\n );\n }\n }\n });\n };\n}\n","import { Literal, Parent } from 'mdast';\nimport { Root } from 'mdast';\nimport { LeafDirective } from 'mdast-util-directive';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertVideoAttributes() {\n return async (tree: Root, file: VFile) => {\n visit(tree, 'leafDirective', (node: LeafDirective) => {\n if (node.name === 'video') {\n if (!node.attributes?.id) {\n failMessage(file, 'id attribute is required', node.position);\n }\n if (!node.attributes?.duration) {\n failMessage(\n file,\n 'duration attribute is required',\n node.position\n );\n }\n\n const title = getTitle(node);\n if (!title) {\n failMessage(file, 'title is required', node.position);\n }\n }\n });\n };\n}\n\nfunction getTitle(node: Parent) {\n const children = node.children as Node[];\n const firstChild = children[0] as Literal;\n return (firstChild?.value || '') as string;\n}\n","import { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertWeblinkTarget() {\n return (tree: Root, file: VFile) => {\n visit(tree, 'containerDirective', (node: ContainerDirective) => {\n if (node.name === 'weblink') {\n if (node.attributes?.target === undefined) {\n failMessage(\n file,\n 'Weblink has no target attribute',\n node.position\n );\n }\n }\n });\n };\n}\n","// @ts-expect-error\nimport lintAltText from '@double-great/remark-lint-alt-text';\n// @ts-expect-error\nimport lintLinkText from '@mapbox/remark-lint-link-text';\nimport dictionary from 'dictionary-en-gb';\nimport remark2retext from 'remark-retext';\nimport english from 'retext-english';\nimport spell from 'retext-spell';\nimport { unified } from 'unified';\nimport { Node } from 'unist';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { assertAssetExists } from './assert-asset-exists';\nimport { assertColumnStructure } from './assert-columns';\nimport { assertNoH1 } from './assert-no-h1';\nimport { assertTaskAnswerStructure } from './assert-task-answer';\nimport { assertVideoAttributes } from './assert-video-attributes';\nimport { assertWeblinkTarget } from './assert-weblink-target';\nimport { lintLatex } from './lint-latex';\nimport { printReport, reportHasFatalErrors } from './report';\n\nexport function reportErrors(files: VFile[], ctx: Context) {\n if (!ctx.options.noReport) {\n printReport(files, ctx);\n }\n if (reportHasFatalErrors(files, ctx)) {\n if (ctx.options.noReport) {\n printReport(files, {\n ...ctx,\n options: {\n ...ctx.options,\n reportOnlyErrors: true,\n },\n });\n }\n console.log('Report has fatal errors');\n if (ctx.options.force) {\n console.log('Compiling using force option...');\n } else {\n process.exit();\n }\n }\n}\n\nexport async function createReport(\n file: VFile,\n mdast: Node,\n ctx: Context\n) {\n const processor = unified()\n .use(assertAssetExists)\n .use(assertVideoAttributes)\n .use(assertTaskAnswerStructure)\n .use(assertColumnStructure)\n .use(assertWeblinkTarget)\n .use(assertNoH1)\n .use(lintLatex)\n .use(lintAltText)\n .use(lintLinkText);\n\n if (ctx.options.spelling) {\n const retextProcessor = unified()\n .use(english)\n .use(spell, { dictionary, max: 1 });\n processor.use(remark2retext, retextProcessor);\n }\n\n await processor.run(mdast, file);\n}\n","import { exec } from 'child_process';\n\nimport { Literal, Root } from 'mdast';\nimport { Position } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nexport function lintLatex() {\n return async (tree: Root, file: VFile) => {\n const transformations: Promise[] = [];\n\n visit(tree, 'math', (node: Literal) => {\n transformations.push(chktex(node, file));\n });\n\n await Promise.all(transformations);\n return tree;\n };\n}\n\nasync function chktex(node: Literal, file: VFile) {\n return new Promise((resolve, reject) => {\n exec(`chktex -q <<< \"${node.value}\"`, (err, response) => {\n if (err) {\n reject(err);\n } else {\n const messages = formatResponse(response);\n const position = node.position as Position;\n messages.forEach(({ line, column, message }) => {\n file.message(message, {\n line: position.start.line + line,\n column: position.start.column + column,\n });\n });\n resolve();\n }\n });\n });\n}\n\ntype Message = {\n line: number;\n column: number;\n message: string;\n};\n\nfunction formatResponse(response: string) {\n if (response.trim() === '') {\n return [];\n }\n\n function formatMessage(message: string) {\n return message.replace(/'/g, '').replace(/`/g, '');\n }\n\n return response\n .split(/Warning \\d+ in stdin line /)\n .filter(Boolean)\n .reduce((acc: Message[], s) => {\n const [key, value] = s.split(':');\n const line = Number(key);\n const trimmed = value.trim();\n\n const match = trimmed.match(/(.*)\\n(.*)\\n(\\s*)\\^/m);\n if (Array.isArray(match)) {\n const message = formatMessage(match[1]);\n acc.push({\n line,\n column: match[3].length,\n message: `${message}\\n\\n${match[2]}\\n${match[3]}^`,\n });\n } else {\n acc.push({\n line,\n column: 0,\n message: formatMessage(trimmed),\n });\n }\n\n return acc;\n }, []);\n}\n","import chalk from 'chalk';\nimport figures from 'figures';\nimport { VFile } from 'vfile';\nimport { VFileMessage } from 'vfile-message';\n\nimport { Context } from '../context';\nimport { MessageStatus } from '../utils/message';\n\nexport type Report = {\n failed: boolean;\n files: ReportFile[];\n};\n\nexport type ReportFile = Omit & {\n messages: ReportMessage[];\n};\n\nexport type ReportMessage = {\n status: MessageStatus;\n position: string;\n reason: string;\n line: number;\n column: number;\n};\n\nexport function printReport(files: VFile[], ctx: Context) {\n const { reportOnlyErrors, shouldFail } = ctx.options;\n\n if (reportOnlyErrors && shouldFail) {\n return;\n }\n\n for (const file of files) {\n // console.log(file.messages);\n const messages = reportOnlyErrors\n ? failingMessages(file.messages)\n : file.messages;\n\n if (messages.length !== 0) {\n // if (file.path !== undefined) {\n // console.log(`\\n${getFilePath(file.path)}`);\n // }\n messages.forEach((message) => {\n printMessage(message);\n });\n }\n }\n}\n\nexport function reportHasFatalErrors(files: VFile[], ctx: Context) {\n return files.some((file) => {\n const messages = file.messages as unknown as ReportMessage[];\n return messages.some(\n (message) => message.status === MessageStatus.fail\n );\n });\n}\n\nexport function reportHasWarnings(files: VFile[], ctx: Context) {\n return files.some((file) => {\n const messages = file.messages as unknown as ReportMessage[];\n return messages.some(\n (message) => message.status === MessageStatus.warning\n );\n });\n}\n\nfunction failingMessages(_messages: VFileMessage[]) {\n const messages = _messages as unknown as ReportMessage[];\n return messages.filter(\n (o) => o.status === MessageStatus.fail\n ) as unknown as VFileMessage[];\n}\n\nfunction printMessage(_message: VFileMessage) {\n const message = _message as unknown as ReportMessage;\n // console.log(message);\n const status = message.status;\n const position = chalk.grey(`${message.line}:${message.column}`);\n const reason = formatReason(message.reason, status);\n console.log(`${formatStatus(status)} ${position} ${reason}`);\n}\n\n// function getFilePath(filePath: string) {\n// return path.isAbsolute(filePath)\n// ? filePath\n// : path.join(process.cwd(), filePath);\n// }\n\nfunction formatStatus(status: MessageStatus) {\n const statusColour = getStatusColour(status);\n switch (status) {\n case MessageStatus.fail:\n return statusColour(figures.cross);\n default:\n return statusColour(figures.warning);\n // TODO: fail on unsupported status?\n }\n}\n\nfunction formatReason(reason: string, status: MessageStatus) {\n const statusColour = getStatusColour(status);\n const [first, ...rest] = reason.split('\\n');\n const formattedFirst = statusColour(first);\n const formattedRest = rest.map((line) => chalk.grey(line));\n return [formattedFirst, ...formattedRest].join('\\n');\n}\n\nfunction getStatusColour(status: MessageStatus) {\n switch (status) {\n case MessageStatus.fail:\n return chalk.red;\n default:\n return chalk.yellow;\n }\n}\n","import { Element, Parent as HastParent, Text } from 'hast';\nimport startCase from 'lodash/startCase.js';\nimport { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { toHast } from 'mdast-util-to-hast';\nimport { Node, Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\nimport { createCounter } from '../utils/counter';\n\nexport function boxouts(refStore: Context['refStore']) {\n const counter = createCounter();\n return async (tree: Node) => {\n visit(tree, 'containerDirective', (node: ContainerDirective) => {\n switch (node.name) {\n case 'example':\n case 'error':\n case 'supplement':\n case 'background':\n case 'definition':\n case 'weblink':\n case 'theorem':\n case 'task':\n case 'proposition':\n case 'answer': {\n const name = node.name as string;\n const count = counter.increment(name);\n node.data = {\n hProperties: createAttributes(node, count, refStore),\n hChildren: createBoxout(node, count),\n };\n }\n }\n });\n };\n}\n\nfunction createAttributes(\n node: ContainerDirective,\n count: number,\n refStore: Context['refStore']\n) {\n const name = node.name as string;\n const id = `${name}-${count}`;\n\n const attributes = node.attributes as Record;\n const className = ['boxout', name];\n if (attributes.icon) {\n className.push(`${attributes.icon}-icon`);\n }\n\n if (node.attributes?.label !== undefined) {\n refStore[node.attributes.label] = id;\n }\n\n return { className, id };\n}\n\nexport function createBoxout(\n node: ContainerDirective,\n count: number\n): Node[] {\n const typeTitle = createBoxoutType(node, count);\n const titles = [typeTitle];\n\n const titleValue = getTitleValue(node);\n if (titleValue.length > 0) {\n const title = createTitle(node);\n titles.push(title);\n }\n\n const children = node.children as ContainerDirective[];\n\n const content = children\n .filter((o) => !o.data?.directiveLabel)\n .filter((o) => o.type !== 'containerDirective' && o.name !== 'answer')\n .map((o) => toHast(o, { allowDangerousHtml: true }))\n .filter(Boolean) as HastParent[];\n\n if (node.name === 'task') {\n const answer = children.find(\n (o) => o.type === 'containerDirective' && o.name === 'answer'\n );\n if (answer) {\n const answerHast = createAnswer(answer, count);\n content.push(answerHast as HastParent);\n }\n }\n\n return [...titles, ...content];\n}\n\nfunction createAnswer(node: ContainerDirective, count: number) {\n const { children } = toHast(node) as HastParent;\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n className: ['answer'],\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['answer-trigger'],\n 'data-answer-id': count,\n },\n children: [\n {\n type: 'text',\n value: 'Show answer',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: ['answer-reveal'],\n id: `answer-${count}`,\n },\n children,\n },\n ],\n };\n}\n\nfunction createBoxoutType(\n node: ContainerDirective,\n count: number\n): Element {\n const name = node.name as string;\n const label = startCase(name);\n let value = `${label} ${count}`;\n\n if (node.attributes?.optional !== undefined) {\n value += ` (Optional)`;\n }\n\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['type'],\n },\n children: [\n {\n type: 'text',\n value,\n },\n ],\n };\n}\n\nfunction createTitle(node: ContainerDirective): Element {\n return {\n type: 'element',\n tagName: 'h3',\n children: createTitleValue(node) as Element['children'],\n };\n}\n\nfunction createTitleValue(node: ContainerDirective) {\n const name = node.name as string;\n const newRoot = {\n type: 'root',\n children: getTitleValue(node),\n };\n const { children = [] } = toHast(newRoot as Root) as Parent;\n if (name !== 'weblink') {\n return children;\n }\n const { target } = node.attributes as Record;\n return [\n {\n type: 'element',\n tagName: 'a',\n properties: {\n href: target,\n target: '_blank',\n className: ['target'],\n },\n children,\n },\n ];\n}\n\nfunction getTitleValue(node: ContainerDirective): Node[] {\n const children = (node.children || []) as Node[];\n const parent = (children[0] || {}) as Parent;\n\n if (!parent.data?.directiveLabel) {\n if (node.name === 'weblink') {\n const attributes = node.attributes as Record;\n return [\n {\n type: 'text',\n value: attributes.target,\n } as Text,\n ];\n }\n return [];\n }\n\n return parent.children || [];\n}\n","import { Properties, Text } from 'hast';\nimport { Code } from 'mdast';\nimport { refractor } from 'refractor';\nimport { RefractorElement } from 'refractor/lib/core';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\n\nexport function codeBlocks(ctx: Context) {\n return async (tree: Node, file: VFile) => {\n // replace \\\\n with \\n in code samples\n // visit(tree, 'inlineCode', (node) => {\n // const old = node.value;\n // const transformed = old.replace(/\\\\\\\\n/g, '\\\\n');\n // // console.log({ old, transformed, same: old === transformed });\n // node.value = transformed;\n // });\n\n visit(tree, 'code', (node: Code) => {\n customCode(node, ctx, file);\n });\n };\n}\n\nfunction customCode(node: Code, ctx: Context, file: VFile) {\n // const { language, options, value } = parseCodeParams(node);\n const language = parseLanguage(node);\n const klass = parseClass(node);\n const meta = (node.meta || '') as string;\n\n const codeProps: Properties = {};\n if (meta !== '') {\n codeProps.className = meta;\n }\n\n const children: (RefractorElement | Text)[] = [];\n const trimmed = node.value.trim();\n if (ctx.options.noSyntaxHighlight || language === '') {\n children.push({\n type: 'text',\n value: trimmed,\n });\n } else {\n const highlighted = refractor.highlight(trimmed, language);\n children.push(...highlighted.children);\n }\n\n Object.assign(node, {\n type: 'custom-code',\n data: {\n hName: 'div',\n hProperties: {\n className: ['code-wrapper', klass],\n },\n hChildren: [\n addConsoleHeading(klass),\n {\n type: 'element',\n tagName: 'pre',\n children: [\n {\n type: 'element',\n tagName: 'code',\n properties: codeProps,\n children,\n },\n ],\n },\n ],\n },\n });\n}\n\nfunction addConsoleHeading(klass: string) {\n if (klass === 'r-output' || klass === 'r-error-output') {\n return {\n type: 'element',\n tagName: 'h6',\n properties: {\n className: 'console-heading',\n },\n children: [\n {\n type: 'text',\n value: 'R Console',\n },\n ],\n };\n }\n if (klass === 'python-output' || klass === 'python-error-output') {\n return {\n type: 'element',\n tagName: 'h6',\n properties: {\n className: 'console-heading',\n },\n children: [\n {\n type: 'text',\n value: 'Python Console',\n },\n ],\n };\n }\n return null;\n}\n\nfunction parseLanguage(node: Code) {\n const lang = (node.lang || '') as string;\n if (lang === 'plaintext' || lang.startsWith('{')) {\n return '';\n }\n return lang.toLowerCase();\n}\n\nfunction parseClass(node: Code) {\n const lang = (node.lang || '') as string;\n if (!lang.startsWith('{.')) {\n return '';\n }\n return lang.slice(2, -1);\n}\n","import { BlockContent, Text } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { Node, Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nexport function columns() {\n return (tree: Node) => {\n visit(tree, 'containerDirective', (node: ContainerDirective) => {\n if (node.name === 'columns') {\n node.data = {\n hProperties: {\n className: 'columns',\n },\n };\n } else if (node.name === 'column') {\n node.data = {\n hProperties: {\n className: 'column',\n },\n };\n\n if (node.attributes?.imgsrc) {\n const altText = getAltText(node);\n\n const img = {\n type: 'image',\n url: node.attributes.imgsrc,\n alt: altText,\n } as unknown as BlockContent;\n\n if (altText) {\n Object.assign(node.children[0], img);\n } else {\n node.children.unshift(img);\n }\n }\n }\n });\n };\n}\n\nfunction getAltText(column: ContainerDirective) {\n const firstChild = column.children[0] as Parent;\n if (!firstChild) {\n return false;\n }\n\n const firstChildChildren = firstChild.children as Node[];\n if (!Array.isArray(firstChildChildren)) {\n return false;\n }\n\n const firstChildFirstChild = firstChildChildren[0] as Text;\n if (!firstChildFirstChild) {\n return false;\n }\n\n return firstChildFirstChild.value;\n}\n","import { Root } from 'mdast';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { boxouts } from './boxouts';\nimport { environment } from './environment';\nimport { moveAnswersToEnd } from './move-answers-to-end';\n\nexport async function combinedMdastPhase(\n mdast: Root,\n ctx: Context,\n file: VFile,\n targetPdf?: boolean\n) {\n const processor = unified()\n .use(environment, ctx, targetPdf)\n .use(boxouts, ctx.refStore);\n\n if (targetPdf) {\n processor.use(moveAnswersToEnd);\n }\n\n return processor.run(mdast, file) as Promise;\n}\n","import path from 'path';\n\nimport { Literal, Root } from 'mdast';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\n\nexport function embedAssetUrl(ctx: Context) {\n return async (tree: Root) => {\n let activeDir = '';\n\n // nodes need to be visited in the correct order\n // to derive the document directory\n visit(tree, (node, index, parent) => {\n // to ensure relative paths to assets across multiple .Rmd files\n if (node.type === 'textDirective' && node.name === 'directory') {\n const firstChild = node.children[0] as Literal;\n activeDir = firstChild.value || '';\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n }\n\n if (node.type === 'image') {\n node.url = getPath(node.url, activeDir, ctx);\n }\n\n // also fix for raw html nodes sometimes output by knitr\n if (node.type === 'html') {\n const props = getProps(node.value);\n if (props !== null && props.src) {\n const { src, ...otherProps } = props;\n Object.assign(node, {\n type: 'image',\n url: getPath(src, activeDir, ctx),\n value: '',\n data: otherProps,\n });\n }\n }\n });\n };\n}\n\nfunction getPath(url: string, dirname: string, ctx: Context) {\n return path.isAbsolute(url) ||\n url.startsWith('http') ||\n ctx.options.noEmbedAssetUrl\n ? url\n : path.join(dirname, url);\n}\n\nfunction getProps(value: string) {\n const matchImg = value.match(/^$/);\n if (matchImg !== null) {\n return propsToObject(value.slice(5, -1));\n }\n const matchPdf = value.match(/^$/);\n if (matchPdf !== null) {\n return propsToObject(value.slice(7, -1));\n }\n return null;\n}\n\nfunction propsToObject(str: string) {\n return str\n .split(/(\\w+)=\"(.*?)\"/)\n .filter((s) => s.trim() !== '')\n .reduce((acc: Record, value, idx, arr) => {\n if (idx % 2 === 1) {\n const key = arr[idx - 1];\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n","import { Element, Literal } from 'hast';\nimport startCase from 'lodash/startCase.js';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { toHast } from 'mdast-util-to-hast';\nimport { Node, Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\n\nconst platforms = ['mac', 'windows', 'linux'];\nconst programs = ['cli', 'github-desktop'];\n\nexport function environment(ctx: Context, targetPdf?: boolean) {\n const platformFlag = ctx.options.envPlatform;\n if (platformFlag !== undefined && !platforms.includes(platformFlag)) {\n throw new Error(\n `[environment]: envPlatform ${platformFlag} should be one of ${platforms}`\n );\n }\n\n const programFlag = ctx.options.envProgram;\n if (programFlag !== undefined && !programs.includes(programFlag)) {\n throw new Error(\n `[environment]: envProgram ${programFlag} should be one of ${programs}`\n );\n }\n\n return async (tree: Node) => {\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (node.name === 'environment') {\n if (targetPdf || (platformFlag && programFlag)) {\n removeNode(parent, index);\n } else {\n createEnvironmentConfig(node, platformFlag, programFlag);\n }\n }\n }\n );\n\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (platforms.includes(node.name)) {\n node.data = {\n hProperties: {\n className: ['platform', node.name],\n },\n };\n if (platformFlag && platformFlag !== node.name) {\n removeNode(parent, index);\n }\n }\n },\n true\n );\n\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (programs.includes(node.name)) {\n node.data = {\n hProperties: {\n className: ['program', node.name],\n },\n };\n if (programFlag && programFlag !== node.name) {\n removeNode(parent, index);\n }\n }\n },\n true\n );\n };\n}\n\nfunction removeNode(parent: Parent, index: number) {\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n}\n\ntype HastNode = Element | Literal;\n\nfunction createEnvironmentConfig(\n node: Parent,\n platformFlag?: string,\n programFlag?: string\n) {\n const hName = 'div';\n\n const hProperties = {\n id: 'environment',\n className: 'boxout',\n };\n\n const hChildren: HastNode[] = [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['type'],\n },\n children: [\n {\n type: 'text',\n value: 'Environment',\n },\n ],\n },\n ...node.children.map((node) => toHast(node as any) as HastNode),\n ];\n\n if (!platformFlag) {\n hChildren.push({\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'platforms',\n },\n children: [\n {\n type: 'element',\n tagName: 'h3',\n children: [\n {\n type: 'text',\n value: 'Platform',\n },\n ],\n },\n ...platforms.map((platform, idx) => {\n return createRadioInput('platform', platform, idx);\n }),\n ],\n });\n }\n\n if (!programFlag) {\n hChildren.push({\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'programs',\n },\n children: [\n {\n type: 'element',\n tagName: 'h3',\n children: [\n {\n type: 'text',\n value: 'Program',\n },\n ],\n },\n ...programs.map((program, idx) => {\n return createRadioInput('program', program, idx);\n }),\n ],\n });\n }\n\n node.data = {\n hName,\n hProperties,\n hChildren,\n };\n}\n\nfunction createRadioInput(\n name: string,\n value: string,\n idx: number\n): Element {\n return {\n type: 'element',\n tagName: 'label',\n properties: {\n [`data-${name}`]: value,\n },\n children: [\n {\n type: 'element',\n tagName: 'input',\n properties: {\n type: 'radio',\n name,\n value,\n checked: idx === 0,\n },\n children: [],\n },\n {\n type: 'element',\n tagName: 'span',\n children: [\n {\n type: 'text',\n value: startCase(value),\n },\n ],\n },\n ],\n };\n}\n","import { Element, ElementContent } from 'hast';\nimport kebabCase from 'lodash/kebabCase.js';\nimport { Image } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\n\nexport function images(ctx: Context) {\n return (tree: Node) => {\n visit(tree, 'image', (node) => {\n template(node, ++ctx.figureCounter);\n });\n };\n}\n\nfunction template(node: Image, count: number) {\n const image: Element = {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'img-bg',\n },\n children: [\n {\n type: 'element',\n tagName: 'img',\n properties: {\n src: node.url,\n alt: node.alt,\n },\n children: [],\n },\n ],\n };\n\n if (node.data?.width && /^\\d+px/.test(String(node.data.width))) {\n image.properties = {\n ...image.properties,\n style: `width: ${node.data.width};`,\n };\n }\n\n const alt = getAltText(node);\n const slug = kebabCase(alt ? alt : `Figure ${count}`);\n\n const caption = {\n type: 'element',\n tagName: 'figcaption',\n children: [\n {\n type: 'element',\n tagName: 'a',\n properties: {\n href: `#${slug}`,\n },\n children: createLabel(alt, count),\n },\n ],\n };\n\n Object.assign(node, {\n type: 'custom-image',\n data: {\n hName: 'figure',\n hProperties: {\n className: ['img-wrapper'],\n id: slug,\n },\n hChildren: [image, caption],\n },\n });\n}\n\nfunction createLabel(alt: string, count: number): ElementContent[] {\n if (alt) {\n return [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'caption-count',\n },\n children: [\n {\n type: 'text',\n value: `Figure ${count}:`,\n },\n ],\n },\n {\n type: 'text',\n value: ` ${alt}`,\n },\n ];\n }\n return [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'caption-count',\n },\n children: [\n {\n type: 'text',\n value: `Figure ${count}`,\n },\n ],\n },\n ];\n}\n\nfunction getAltText(node: Image) {\n const altText = node.alt || '';\n if (altText.includes('unnamed-chunk')) {\n return '';\n }\n return altText;\n}\n","import headings from 'remark-autolink-headings';\nimport directive from 'remark-directive';\nimport footnotes from 'remark-footnotes';\nimport frontmatter from 'remark-frontmatter';\nimport gfm from 'remark-gfm';\nimport markdown from 'remark-parse';\nimport slug from 'remark-slug';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { aliasDirectiveToSvg } from '../latex/directive-to-svg';\n// import { aliasDirectiveToTex } from '../latex/directive-to-tex';\nimport { createSvg } from '../utils/icons';\nimport { codeBlocks } from './code-blocks';\nimport { columns } from './columns';\nimport { embedAssetUrl } from './embed-asset-url';\nimport { images } from './images';\nimport { pagebreaks } from './pagebreaks';\nimport { removeEmptyParagraphs } from './remove-empty-paragraphs';\nimport { youtubeVideos } from './youtube-videos';\n\nexport async function mdastPhase(file: VFile, ctx: Context) {\n // https://github.com/unifiedjs/unified\n // convert markdown to syntax tree: complex transforms\n // should be more robust and straightforward\n const processor = unified()\n // third-party plugins:\n .use(markdown)\n .use(directive)\n .use(frontmatter)\n .use(footnotes, { inlineNotes: true })\n .use(gfm)\n // .use(sectionize)\n .use(slug)\n .use(headings, {\n content: createSvg('link-icon'),\n linkProperties: { className: 'link' },\n })\n // custom plugins:\n .use(columns)\n .use(embedAssetUrl, ctx)\n .use(youtubeVideos)\n .use(aliasDirectiveToSvg, ctx)\n .use(removeEmptyParagraphs)\n // .use(aliasDirectiveToTex, ctx)\n .use(codeBlocks, ctx)\n .use(images, ctx)\n .use(pagebreaks);\n\n const parsed = processor.parse(file);\n return processor.run(parsed, file);\n}\n","import { Node, Parent } from 'hast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\n\nexport function moveAnswersToEnd() {\n return (tree: Node) => {\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n // remove answer from task rehype\n if (node.name === 'task' && node.data) {\n const children = (node.data.hChildren ||\n []) as ContainerDirective[];\n node.data.hChildren = children.filter(\n (o) => o.name !== 'answer'\n );\n }\n\n if (node.name === 'answer') {\n // these nodes have already been moved to the end\n if (node.attributes?.movedToEnd === 'yes') {\n return;\n }\n\n // remove answer block from task node\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n\n // add to root node\n const treeParent = tree as Parent;\n const treeChildren = (treeParent.children || []) as Node[];\n\n node.attributes = {\n ...(node.attributes || {}),\n movedToEnd: 'yes',\n };\n\n treeChildren.push(node);\n }\n }\n );\n };\n}\n","import { LeafDirective } from 'mdast-util-directive';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nexport function pagebreaks() {\n return async (tree: Node) => {\n visit(tree, 'leafDirective', (node: LeafDirective) => {\n if (node.name === 'pagebreak') {\n node.data = {\n hName: 'hr',\n hProperties: {\n className: 'pagebreak',\n },\n };\n }\n });\n };\n}\n","import { Paragraph, Parent } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nexport function removeEmptyParagraphs() {\n return async (tree: Node) => {\n visit(tree, 'paragraph', (node: Paragraph, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (node.children.length === 0) {\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n }\n });\n };\n}\n","import { Literal } from 'mdast';\nimport { LeafDirective } from 'mdast-util-directive';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function youtubeVideos() {\n return async (tree: Node, file: VFile) => {\n visit(tree, 'leafDirective', (node: LeafDirective) => {\n if (node.name === 'video') {\n const attributes = node.attributes;\n const title = getTitle(node, file);\n node.data = {\n hName: 'a',\n hProperties: {\n className: ['boxout', 'video'],\n href: getYoutubeUrl(attributes?.id || ''),\n title: attributes?.title || null,\n target: '_blank',\n },\n hChildren: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'content',\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'type',\n },\n children: [\n {\n type: 'text',\n value: 'Video',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'title',\n },\n children: [\n {\n type: 'text',\n value: title,\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'duration',\n },\n children: [\n {\n type: 'element',\n tagName: 'strong',\n children: [\n {\n type: 'text',\n value: 'Duration',\n },\n ],\n },\n {\n type: 'text',\n value: formatDuration(attributes?.duration || ''),\n },\n ],\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'thumbnail',\n },\n children: [\n {\n type: 'element',\n tagName: 'img',\n properties: {\n src: getYoutubeThumbnailUrl(attributes?.id || ''),\n alt: '',\n },\n children: [],\n },\n ],\n },\n ],\n };\n }\n });\n };\n}\n\nfunction getTitle(node: LeafDirective, file: VFile) {\n const children = node.children as Node[];\n const firstChild = children[0] as Literal;\n const title = firstChild?.value || '';\n if (title.trim() === '') {\n failMessage(file, 'Video has no title', node.position);\n }\n return title;\n}\n\nfunction getYoutubeUrl(id: string) {\n return `https://youtu.be/${id}`;\n}\n\nfunction getYoutubeThumbnailUrl(id: string) {\n return `http://img.youtube.com/vi/${id}/mqdefault.jpg`;\n}\n\nfunction formatDuration(duration: string = '') {\n const match = duration.match(/^(\\d+)m(\\d+)s$/);\n if (match === null) {\n return '';\n }\n return `${match[1]}:${match[2].padStart(2, '0')}`;\n}\n","import puppeteer from 'puppeteer';\n\n// const footerTemplate = `\n//
\n// Page of \n//
\n// `;\n\nexport async function convertToPdf(html: string) {\n const browser = await puppeteer.launch({\n headless: true,\n args: [\n // attempted fix for windows https://stackoverflow.com/questions/59979188#66549119\n '--disable-gpu',\n '--disable-dev-shm-usage',\n '--disable-setuid-sandbox',\n '--no-first-run',\n '--no-sandbox',\n '--no-zygote',\n ],\n });\n const page = await browser.newPage();\n page.setDefaultNavigationTimeout(0);\n await page.setContent(html);\n await page.evaluateHandle('document.fonts.ready');\n const pdf = await page.pdf({\n format: 'a4',\n printBackground: true,\n // displayHeaderFooter: true,\n // footerTemplate,\n margin: {\n top: '20px',\n left: '40px',\n right: '40px',\n bottom: '40px',\n },\n });\n await browser.close();\n return pdf;\n}\n","export function allowNoWhitespaceBeforeHeading(contents: string) {\n return contents\n .split('\\n')\n .map((line) => {\n const match = line.match(/^(#+)(\\w)(.*?)$/);\n if (match !== null) {\n return `${match[1]} ${match[2]}${match[3]}`;\n }\n return line;\n })\n .join('\\n');\n}\n","const blockList = ['\\\\newpage', '\\\\pagebreak'];\n\nexport function convertNewPageToDirective(contents: string) {\n return contents\n .split('\\n')\n .map((a) => (blockList.some((b) => a.includes(b)) ? '::pagebreak' : a))\n .join('\\n');\n}\n\nexport function convertEmptyMBoxToDirective(contents: string) {\n return contents\n .split('\\n')\n .map((line) => {\n if (\n line.includes('\\\\mbox') &&\n line.replace('{', '').replace('}', '').trim() === '\\\\mbox'\n ) {\n return '::pagebreak';\n }\n return line;\n })\n .join('\\n');\n}\n","export function convertTextBfToMd(contents: string) {\n const pattern = /\\\\textbf\\{(.*?)\\}/g;\n return contents.replace(pattern, (_, str) => `**${str}**`);\n}\n\nexport function convertUrlToMd(contents: string) {\n const pattern = /\\\\url\\{(.*?)\\}/g;\n return contents.replace(pattern, (_, str) => str);\n}\n","export function convertMacroToDirective(contents: string) {\n return contents\n .split('\\n')\n .map((line) => {\n const container = parseCustomContainer(line);\n if (container !== null) {\n return renderContainerDirective(container);\n }\n return line;\n })\n .join('\\n');\n}\n\ntype Container = {\n name: string;\n title: string;\n attributes: string;\n};\n\nfunction parseCustomContainer(line: string): Container | null {\n const match = line.match(/^#{1,6}\\s*\\[(\\D.+)](.*)/);\n if (!Array.isArray(match)) {\n return null;\n }\n const [, attributeStr = '', extra = ''] = match;\n const [name, ...attributesArr] = attributeStr\n .split(',')\n .map((s) => s.trim());\n const title = extra.trim();\n const attributes = transformAttributes(name, attributesArr);\n return { name, title, attributes };\n}\n\nfunction renderContainerDirective({ name, title, attributes }: Container) {\n const colons = getColons(name);\n if (name.startsWith('/')) {\n return colons;\n }\n const newTitle = title ? `[${title}]` : '';\n const newAttributes = attributes ? `{${attributes}}` : '';\n return colons + name + newTitle + newAttributes;\n}\n\nfunction getColons(name: string) {\n switch (name.replace('/', '')) {\n case 'task':\n case 'columns':\n return '::::';\n case 'video':\n return '::';\n default:\n return ':::';\n }\n}\n\nfunction transformAttributes(\n containerName: string,\n attributesArr: string[]\n) {\n return attributesArr\n .map((attribute) => {\n const [key, value] = attribute.split('=').map((s) => s.trim());\n if (containerName === 'video' && key === 'videoid') {\n return `id=${value}`;\n }\n return attribute;\n })\n .join(' ');\n}\n","import { VFile } from 'vfile';\n\nimport { allowNoWhitespaceBeforeHeading } from './allow-no-whitespace-before-heading';\nimport {\n convertEmptyMBoxToDirective,\n convertNewPageToDirective,\n} from './convert-block-tex';\nimport { convertTextBfToMd, convertUrlToMd } from './convert-inline-tex';\nimport { convertMacroToDirective } from './convert-macro-to-directive';\nimport { reformatPandocSimpleTables } from './reformat-pandoc-simple-tables';\n\n// Some of the original coursework syntax can't easily be parsed by\n// existing plugins for unified.js, so in a \"pre-parse\" phase\n// I transform some syntax using regex so it can be parsed.\n// A successful generic approach I found is to convert problem syntax to a\n// custom markdown directive: https://github.com/remarkjs/remark-directive\n\nexport function preParsePhase(file: VFile) {\n let result = file.value as string;\n result = removeCommentedSections(result);\n result = escapeDollarsInCodeBlocks(result);\n result = allowNoWhitespaceBeforeHeading(result);\n result = convertMacroToDirective(result);\n result = convertTextBfToMd(result);\n result = convertUrlToMd(result);\n result = convertNewPageToDirective(result);\n result = convertEmptyMBoxToDirective(result);\n result = reformatPandocSimpleTables(result);\n file.value = result;\n return file;\n}\n\nfunction removeCommentedSections(md: string) {\n return md.replace(//g, '').replace(/\\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n\";","export default \"\\n \\n \\n\\n\";","export default \"\\n \\n\\n\";","module.exports = import(\"@double-great/remark-lint-alt-text\");;","module.exports = import(\"@mapbox/remark-lint-link-text\");;","module.exports = import(\"base64-arraybuffer\");;","module.exports = import(\"chalk\");;","module.exports = import(\"dictionary-en-gb\");;","module.exports = import(\"figures\");;","module.exports = import(\"hash-sum\");;","module.exports = import(\"image-size\");;","module.exports = import(\"js-yaml\");;","module.exports = import(\"lodash/cloneDeep.js\");;","module.exports = import(\"lodash/kebabCase.js\");;","module.exports = import(\"lodash/startCase.js\");;","module.exports = import(\"markdown-table\");;","module.exports = import(\"mathjax-full/js/adaptors/liteAdaptor.js\");;","module.exports = import(\"mathjax-full/js/core/MathItem.js\");;","module.exports = import(\"mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js\");;","module.exports = import(\"mathjax-full/js/handlers/html.js\");;","module.exports = import(\"mathjax-full/js/handlers/html/HTMLDocument.js\");;","module.exports = import(\"mathjax-full/js/input/mathml.js\");;","module.exports = import(\"mathjax-full/js/input/tex.js\");;","module.exports = import(\"mathjax-full/js/input/tex/AllPackages.js\");;","module.exports = import(\"mathjax-full/js/mathjax.js\");;","module.exports = import(\"mathjax-full/js/output/svg.js\");;","module.exports = import(\"mdast-util-toc\");;","module.exports = import(\"mime/lite.js\");;","module.exports = import(\"node-fetch\");;","module.exports = import(\"puppeteer\");;","module.exports = import(\"refractor\");;","module.exports = import(\"rehype-document\");;","module.exports = import(\"rehype-format\");;","module.exports = import(\"rehype-parse\");;","module.exports = import(\"rehype-raw\");;","module.exports = import(\"rehype-stringify\");;","module.exports = import(\"remark-autolink-headings\");;","module.exports = import(\"remark-directive\");;","module.exports = import(\"remark-footnotes\");;","module.exports = import(\"remark-frontmatter\");;","module.exports = import(\"remark-gfm\");;","module.exports = import(\"remark-parse\");;","module.exports = import(\"remark-rehype\");;","module.exports = import(\"remark-retext\");;","module.exports = import(\"remark-slug\");;","module.exports = import(\"retext-english\");;","module.exports = import(\"retext-spell\");;","module.exports = import(\"speech-rule-engine\");;","module.exports = import(\"to-vfile\");;","module.exports = import(\"unist-util-visit\");;","module.exports = import(\"yargs\");;","module.exports = import(\"yup\");;","module.exports = require(\"child_process\");","module.exports = require(\"fs\");","module.exports = require(\"os\");","module.exports = require(\"path\");","module.exports = require(\"url\");","/**\n * @typedef {import('mdast').Root|import('mdast').Content} Node\n * @typedef {import('mdast').Definition} Definition\n * @typedef {import('unist-util-visit').Visitor} DefinitionVisitor\n */\n\nimport {visit} from 'unist-util-visit'\n\nconst own = {}.hasOwnProperty\n\n/**\n *\n * @param {Node} node\n */\nexport function definitions(node) {\n /** @type {Object.} */\n const cache = Object.create(null)\n\n if (!node || !node.type) {\n throw new Error('mdast-util-definitions expected node')\n }\n\n visit(node, 'definition', ondefinition)\n\n return getDefinition\n\n /** @type {DefinitionVisitor} */\n function ondefinition(definition) {\n const id = clean(definition.identifier)\n if (id && !own.call(cache, id)) {\n cache[id] = definition\n }\n }\n\n /**\n * Get a node from the bound definition-cache.\n *\n * @param {string} identifier\n * @returns {Definition|null}\n */\n function getDefinition(identifier) {\n const id = clean(identifier)\n return id && own.call(cache, id) ? cache[id] : null\n }\n}\n\n/**\n * @param {string} [value]\n * @returns {string}\n */\nfunction clean(value) {\n return String(value || '').toUpperCase()\n}\n","/**\n * @typedef {import('mdast').BlockContent} BlockContent\n * @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').ElementContent} ElementContent\n * @typedef {import('./index.js').H} H\n */\n\nimport {sanitizeUri} from 'micromark-util-sanitize-uri'\nimport {u} from 'unist-builder'\nimport {all} from './traverse.js'\nimport {wrap} from './wrap.js'\n\n/**\n * @param {H} h\n */\nexport function footer(h) {\n let index = -1\n /** @type {Array} */\n const listItems = []\n\n while (++index < h.footnoteOrder.length) {\n const def = h.footnoteById[h.footnoteOrder[index].toUpperCase()]\n\n if (!def) {\n continue\n }\n\n const content = all(h, def)\n const id = String(def.identifier)\n const safeId = sanitizeUri(id.toLowerCase())\n let referenceIndex = 0\n /** @type {Array} */\n const backReferences = []\n\n while (++referenceIndex <= h.footnoteCounts[id]) {\n /** @type {Element} */\n const backReference = {\n type: 'element',\n tagName: 'a',\n properties: {\n href:\n '#' +\n h.clobberPrefix +\n 'fnref-' +\n safeId +\n (referenceIndex > 1 ? '-' + referenceIndex : ''),\n dataFootnoteBackref: true,\n className: ['data-footnote-backref'],\n ariaLabel: h.footnoteBackLabel\n },\n children: [{type: 'text', value: '↩'}]\n }\n\n if (referenceIndex > 1) {\n backReference.children.push({\n type: 'element',\n tagName: 'sup',\n children: [{type: 'text', value: String(referenceIndex)}]\n })\n }\n\n if (backReferences.length > 0) {\n backReferences.push({type: 'text', value: ' '})\n }\n\n backReferences.push(backReference)\n }\n\n const tail = content[content.length - 1]\n\n if (tail && tail.type === 'element' && tail.tagName === 'p') {\n const tailTail = tail.children[tail.children.length - 1]\n if (tailTail && tailTail.type === 'text') {\n tailTail.value += ' '\n } else {\n tail.children.push({type: 'text', value: ' '})\n }\n\n tail.children.push(...backReferences)\n } else {\n content.push(...backReferences)\n }\n\n /** @type {Element} */\n const listItem = {\n type: 'element',\n tagName: 'li',\n properties: {id: h.clobberPrefix + 'fn-' + safeId},\n children: wrap(content, true)\n }\n\n if (def.position) {\n listItem.position = def.position\n }\n\n listItems.push(listItem)\n }\n\n if (listItems.length === 0) {\n return null\n }\n\n return {\n type: 'element',\n tagName: 'section',\n properties: {dataFootnotes: true, className: ['footnotes']},\n children: [\n {\n type: 'element',\n tagName: 'h2',\n properties: {id: 'footnote-label', className: ['sr-only']},\n children: [u('text', h.footnoteLabel)]\n },\n {type: 'text', value: '\\n'},\n {\n type: 'element',\n tagName: 'ol',\n properties: {},\n children: wrap(listItems, true)\n },\n {type: 'text', value: '\\n'}\n ]\n }\n}\n","/**\n * @typedef {import('mdast').Blockquote} Blockquote\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {wrap} from '../wrap.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Blockquote} node\n */\nexport function blockquote(h, node) {\n return h(node, 'blockquote', wrap(all(h, node), true))\n}\n","/**\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Text} Text\n * @typedef {import('mdast').Break} Break\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {Break} node\n * @returns {Array}\n */\nexport function hardBreak(h, node) {\n return [h(node, 'br'), u('text', '\\n')]\n}\n","/**\n * @typedef {import('mdast').Code} Code\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {Code} node\n */\nexport function code(h, node) {\n const value = node.value ? node.value + '\\n' : ''\n // To do: next major, use `node.lang` w/o regex, the splitting’s been going\n // on for years in remark now.\n const lang = node.lang && node.lang.match(/^[^ \\t]+(?=[ \\t]|$)/)\n /** @type {Properties} */\n const props = {}\n\n if (lang) {\n props.className = ['language-' + lang]\n }\n\n const code = h(node, 'code', props, [u('text', value)])\n\n if (node.meta) {\n code.data = {meta: node.meta}\n }\n\n return h(node.position, 'pre', [code])\n}\n","/**\n * @typedef {import('mdast').Delete} Delete\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Delete} node\n */\nexport function strikethrough(h, node) {\n return h(node, 'del', all(h, node))\n}\n","/**\n * @typedef {import('mdast').Emphasis} Emphasis\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Emphasis} node\n */\nexport function emphasis(h, node) {\n return h(node, 'em', all(h, node))\n}\n","/**\n * @typedef {import('mdast').FootnoteReference} FootnoteReference\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {sanitizeUri} from 'micromark-util-sanitize-uri'\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {FootnoteReference} node\n */\nexport function footnoteReference(h, node) {\n const id = String(node.identifier)\n const safeId = sanitizeUri(id.toLowerCase())\n const index = h.footnoteOrder.indexOf(id)\n /** @type {number} */\n let counter\n\n if (index === -1) {\n h.footnoteOrder.push(id)\n h.footnoteCounts[id] = 1\n counter = h.footnoteOrder.length\n } else {\n h.footnoteCounts[id]++\n counter = index + 1\n }\n\n const reuseCounter = h.footnoteCounts[id]\n\n return h(node, 'sup', [\n h(\n node.position,\n 'a',\n {\n href: '#' + h.clobberPrefix + 'fn-' + safeId,\n id:\n h.clobberPrefix +\n 'fnref-' +\n safeId +\n (reuseCounter > 1 ? '-' + reuseCounter : ''),\n dataFootnoteRef: true,\n ariaDescribedBy: 'footnote-label'\n },\n [u('text', String(counter))]\n )\n ])\n}\n","/**\n * @typedef {import('mdast').Footnote} Footnote\n * @typedef {import('../index.js').Handler} Handler\n *\n * @todo\n * `footnote` (or “inline note”) are a pandoc footnotes feature (`^[a note]`)\n * that does not exist in GFM.\n * We still have support for it, so that things remain working with\n * `micromark-extension-footnote` and `mdast-util-footnote`, but in the future\n * we might be able to remove it?\n */\n\nimport {footnoteReference} from './footnote-reference.js'\n\n/**\n * @type {Handler}\n * @param {Footnote} node\n */\nexport function footnote(h, node) {\n const footnoteById = h.footnoteById\n let no = 1\n\n while (no in footnoteById) no++\n\n const identifier = String(no)\n\n footnoteById[identifier] = {\n type: 'footnoteDefinition',\n identifier,\n children: [{type: 'paragraph', children: node.children}],\n position: node.position\n }\n\n return footnoteReference(h, {\n type: 'footnoteReference',\n identifier,\n position: node.position\n })\n}\n","/**\n * @typedef {import('mdast').Heading} Heading\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Heading} node\n */\nexport function heading(h, node) {\n return h(node, 'h' + node.depth, all(h, node))\n}\n","/**\n * @typedef {import('mdast').HTML} HTML\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * Return either a `raw` node in dangerous mode, otherwise nothing.\n *\n * @type {Handler}\n * @param {HTML} node\n */\nexport function html(h, node) {\n return h.dangerous ? h.augment(node, u('raw', node.value)) : null\n}\n","/**\n * @typedef {import('mdast').LinkReference} LinkReference\n * @typedef {import('mdast').ImageReference} ImageReference\n * @typedef {import('./index.js').Handler} Handler\n * @typedef {import('./index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\nimport {all} from './traverse.js'\n\n/**\n * Return the content of a reference without definition as plain text.\n *\n * @type {Handler}\n * @param {ImageReference|LinkReference} node\n * @returns {Content|Array}\n */\nexport function revert(h, node) {\n const subtype = node.referenceType\n let suffix = ']'\n\n if (subtype === 'collapsed') {\n suffix += '[]'\n } else if (subtype === 'full') {\n suffix += '[' + (node.label || node.identifier) + ']'\n }\n\n if (node.type === 'imageReference') {\n return u('text', '![' + node.alt + suffix)\n }\n\n const contents = all(h, node)\n const head = contents[0]\n\n if (head && head.type === 'text') {\n head.value = '[' + head.value\n } else {\n contents.unshift(u('text', '['))\n }\n\n const tail = contents[contents.length - 1]\n\n if (tail && tail.type === 'text') {\n tail.value += suffix\n } else {\n contents.push(u('text', suffix))\n }\n\n return contents\n}\n","/**\n * @typedef {import('mdast').ImageReference} ImageReference\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\nimport {revert} from '../revert.js'\n\n/**\n * @type {Handler}\n * @param {ImageReference} node\n */\nexport function imageReference(h, node) {\n const def = h.definition(node.identifier)\n\n if (!def) {\n return revert(h, node)\n }\n\n /** @type {Properties} */\n const props = {src: normalize(def.url || ''), alt: node.alt}\n\n if (def.title !== null && def.title !== undefined) {\n props.title = def.title\n }\n\n return h(node, 'img', props)\n}\n","/**\n * @typedef {import('mdast').Image} Image\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\n\n/**\n * @type {Handler}\n * @param {Image} node\n */\nexport function image(h, node) {\n /** @type {Properties} */\n const props = {src: normalize(node.url), alt: node.alt}\n\n if (node.title !== null && node.title !== undefined) {\n props.title = node.title\n }\n\n return h(node, 'img', props)\n}\n","/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {InlineCode} node\n */\nexport function inlineCode(h, node) {\n return h(node, 'code', [u('text', node.value.replace(/\\r?\\n|\\r/g, ' '))])\n}\n","/**\n * @typedef {import('mdast').LinkReference} LinkReference\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\nimport {revert} from '../revert.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {LinkReference} node\n */\nexport function linkReference(h, node) {\n const def = h.definition(node.identifier)\n\n if (!def) {\n return revert(h, node)\n }\n\n /** @type {Properties} */\n const props = {href: normalize(def.url || '')}\n\n if (def.title !== null && def.title !== undefined) {\n props.title = def.title\n }\n\n return h(node, 'a', props, all(h, node))\n}\n","/**\n * @typedef {import('mdast').Link} Link\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Link} node\n */\nexport function link(h, node) {\n /** @type {Properties} */\n const props = {href: normalize(node.url)}\n\n if (node.title !== null && node.title !== undefined) {\n props.title = node.title\n }\n\n return h(node, 'a', props, all(h, node))\n}\n","/**\n * @typedef {import('mdast').ListItem} ListItem\n * @typedef {import('mdast').List} List\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('hast').Element} Element\n * @typedef {import('../index.js').Handler} Handler\n * @typedef {import('../index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {ListItem} node\n * @param {List} parent\n */\nexport function listItem(h, node, parent) {\n const result = all(h, node)\n const loose = parent ? listLoose(parent) : listItemLoose(node)\n /** @type {Properties} */\n const props = {}\n /** @type {Array} */\n const wrapped = []\n\n if (typeof node.checked === 'boolean') {\n /** @type {Element} */\n let paragraph\n\n if (\n result[0] &&\n result[0].type === 'element' &&\n result[0].tagName === 'p'\n ) {\n paragraph = result[0]\n } else {\n paragraph = h(null, 'p', [])\n result.unshift(paragraph)\n }\n\n if (paragraph.children.length > 0) {\n paragraph.children.unshift(u('text', ' '))\n }\n\n paragraph.children.unshift(\n h(null, 'input', {\n type: 'checkbox',\n checked: node.checked,\n disabled: true\n })\n )\n\n // According to github-markdown-css, this class hides bullet.\n // See: .\n props.className = ['task-list-item']\n }\n\n let index = -1\n\n while (++index < result.length) {\n const child = result[index]\n\n // Add eols before nodes, except if this is a loose, first paragraph.\n if (\n loose ||\n index !== 0 ||\n child.type !== 'element' ||\n child.tagName !== 'p'\n ) {\n wrapped.push(u('text', '\\n'))\n }\n\n if (child.type === 'element' && child.tagName === 'p' && !loose) {\n wrapped.push(...child.children)\n } else {\n wrapped.push(child)\n }\n }\n\n const tail = result[result.length - 1]\n\n // Add a final eol.\n if (tail && (loose || !('tagName' in tail) || tail.tagName !== 'p')) {\n wrapped.push(u('text', '\\n'))\n }\n\n return h(node, 'li', props, wrapped)\n}\n\n/**\n * @param {List} node\n * @return {Boolean}\n */\nfunction listLoose(node) {\n let loose = node.spread\n const children = node.children\n let index = -1\n\n while (!loose && ++index < children.length) {\n loose = listItemLoose(children[index])\n }\n\n return Boolean(loose)\n}\n\n/**\n * @param {ListItem} node\n * @return {Boolean}\n */\nfunction listItemLoose(node) {\n const spread = node.spread\n\n return spread === undefined || spread === null\n ? node.children.length > 1\n : spread\n}\n","/**\n * @typedef {import('mdast').List} List\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {wrap} from '../wrap.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {List} node\n * @returns {Element}\n */\nexport function list(h, node) {\n /** @type {Properties} */\n const props = {}\n const name = node.ordered ? 'ol' : 'ul'\n const items = all(h, node)\n let index = -1\n\n if (typeof node.start === 'number' && node.start !== 1) {\n props.start = node.start\n }\n\n // Like GitHub, add a class for custom styling.\n while (++index < items.length) {\n const item = items[index]\n\n if (\n item.type === 'element' &&\n item.tagName === 'li' &&\n item.properties &&\n Array.isArray(item.properties.className) &&\n item.properties.className.includes('task-list-item')\n ) {\n props.className = ['contains-task-list']\n break\n }\n }\n\n return h(node, name, props, wrap(items, true))\n}\n","/**\n * @typedef {import('mdast').Paragraph} Paragraph\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Paragraph} node\n */\nexport function paragraph(h, node) {\n return h(node, 'p', all(h, node))\n}\n","/**\n * @typedef {import('mdast').Root} Root\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\nimport {all} from '../traverse.js'\nimport {wrap} from '../wrap.js'\n\n/**\n * @type {Handler}\n * @param {Root} node\n */\nexport function root(h, node) {\n // @ts-expect-error `root`s are also fine.\n return h.augment(node, u('root', wrap(all(h, node))))\n}\n","/**\n * @typedef {import('mdast').Strong} Strong\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Strong} node\n */\nexport function strong(h, node) {\n return h(node, 'strong', all(h, node))\n}\n","/**\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('hast').Element} Element\n * @typedef {import('../index.js').Handler} Handler\n * @typedef {import('../index.js').Content} Content\n */\n\nimport {pointStart, pointEnd} from 'unist-util-position'\nimport {wrap} from '../wrap.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Table} node\n */\nexport function table(h, node) {\n const rows = node.children\n let index = -1\n const align = node.align || []\n /** @type {Array} */\n const result = []\n\n while (++index < rows.length) {\n const row = rows[index].children\n const name = index === 0 ? 'th' : 'td'\n /** @type {Array} */\n const out = []\n let cellIndex = -1\n const length = node.align ? align.length : row.length\n\n while (++cellIndex < length) {\n const cell = row[cellIndex]\n out.push(\n h(cell, name, {align: align[cellIndex]}, cell ? all(h, cell) : [])\n )\n }\n\n result[index] = h(rows[index], 'tr', wrap(out, true))\n }\n\n return h(\n node,\n 'table',\n wrap(\n [h(result[0].position, 'thead', wrap([result[0]], true))].concat(\n result[1]\n ? h(\n {\n start: pointStart(result[1]),\n end: pointEnd(result[result.length - 1])\n },\n 'tbody',\n wrap(result.slice(1), true)\n )\n : []\n ),\n true\n )\n )\n}\n","/**\n * @typedef {import('mdast').Text} Text\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {Text} node\n */\nexport function text(h, node) {\n return h.augment(\n node,\n u('text', String(node.value).replace(/[ \\t]*(\\r?\\n|\\r)[ \\t]*/g, '$1'))\n )\n}\n","/**\n * @typedef {import('mdast').ThematicBreak} ThematicBreak\n * @typedef {import('hast').Element} Element\n * @typedef {import('../index.js').Handler} Handler\n */\n\n/**\n * @type {Handler}\n * @param {ThematicBreak} [node]\n * @returns {Element}\n */\nexport function thematicBreak(h, node) {\n return h(node, 'hr')\n}\n","import {blockquote} from './blockquote.js'\nimport {hardBreak} from './break.js'\nimport {code} from './code.js'\nimport {strikethrough} from './delete.js'\nimport {emphasis} from './emphasis.js'\nimport {footnoteReference} from './footnote-reference.js'\nimport {footnote} from './footnote.js'\nimport {heading} from './heading.js'\nimport {html} from './html.js'\nimport {imageReference} from './image-reference.js'\nimport {image} from './image.js'\nimport {inlineCode} from './inline-code.js'\nimport {linkReference} from './link-reference.js'\nimport {link} from './link.js'\nimport {listItem} from './list-item.js'\nimport {list} from './list.js'\nimport {paragraph} from './paragraph.js'\nimport {root} from './root.js'\nimport {strong} from './strong.js'\nimport {table} from './table.js'\nimport {text} from './text.js'\nimport {thematicBreak} from './thematic-break.js'\n\nexport const handlers = {\n blockquote,\n break: hardBreak,\n code,\n delete: strikethrough,\n emphasis,\n footnoteReference,\n footnote,\n heading,\n html,\n imageReference,\n image,\n inlineCode,\n linkReference,\n link,\n listItem,\n list,\n paragraph,\n root,\n strong,\n table,\n text,\n thematicBreak,\n toml: ignore,\n yaml: ignore,\n definition: ignore,\n footnoteDefinition: ignore\n}\n\n// Return nothing for nodes that are ignored.\nfunction ignore() {\n return null\n}\n","/**\n * @typedef {import('mdast').Root|import('mdast').Parent['children'][number]} MdastNode\n * @typedef {import('hast').Root|import('hast').Parent['children'][number]} HastNode\n * @typedef {import('mdast').Parent} Parent\n * @typedef {import('mdast').Definition} Definition\n * @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('hast').Text} Text\n * @typedef {import('hast').Comment} Comment\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Root} Root\n * @typedef {import('hast').ElementContent} Content\n * @typedef {import('unist-util-position').PositionLike} PositionLike\n *\n * @typedef EmbeddedHastFields\n * @property {string} [hName] Defines the tag name of an element\n * @property {Properties} [hProperties] Defines the properties of an element\n * @property {Array} [hChildren] Defines the (hast) children of an element\n *\n * @typedef {Record & EmbeddedHastFields} Data unist data with embedded hast fields\n *\n * @typedef {MdastNode & {data?: Data}} NodeWithData unist node with embedded hast data\n *\n * @callback Handler\n * @param {H} h Handle context\n * @param {any} node mdast node to handle\n * @param {Parent|null} parent Parent of `node`\n * @returns {Content|Array|null|undefined} hast node\n *\n * @callback HFunctionProps\n * @param {MdastNode|PositionLike|null|undefined} node mdast node or unist position\n * @param {string} tagName HTML tag name\n * @param {Properties} props Properties\n * @param {Array?} [children] hast content\n * @returns {Element}\n *\n * @callback HFunctionNoProps\n * @param {MdastNode|PositionLike|null|undefined} node mdast node or unist position\n * @param {string} tagName HTML tag name\n * @param {Array?} [children] hast content\n * @returns {Element}\n *\n * @typedef HFields\n * @property {boolean} dangerous Whether HTML is allowed\n * @property {string} clobberPrefix Prefix to use to prevent DOM clobbering\n * @property {string} footnoteLabel Label to use to introduce the footnote section\n * @property {string} footnoteBackLabel Label to use to go back to a footnote call from the footnote section\n * @property {(identifier: string) => Definition|null} definition Definition cache\n * @property {Record} footnoteById Footnote cache\n * @property {Array} footnoteOrder Order in which footnotes occur\n * @property {Record} footnoteCounts Counts the same footnote was used\n * @property {Handlers} handlers Applied handlers\n * @property {Handler} unknownHandler Handler for any none not in `passThrough` or otherwise handled\n * @property {(left: NodeWithData|PositionLike|null|undefined, right: Content) => Content} augment Like `h` but lower-level and usable on non-elements.\n * @property {Array} passThrough List of node types to pass through untouched (except for their children).\n *\n * @typedef Options\n * @property {boolean} [allowDangerousHtml=false]\n * Whether to allow `html` nodes and inject them as `raw` HTML\n * @property {string} [clobberPrefix='user-content-']\n * Prefix to use before the `id` attribute to prevent it from *clobbering*.\n * attributes.\n * DOM clobbering is this:\n *\n * ```html\n *

\n * \n * ```\n *\n * Elements by their ID are made available in browsers on the `window` object.\n * Using a prefix prevents this from being a problem.\n * @property {string} [footnoteLabel='Footnotes']\n * Label to use for the footnotes section.\n * Affects screen reader users.\n * Change it if you’re authoring in a different language.\n * @property {string} [footnoteBackLabel='Back to content']\n * Label to use from backreferences back to their footnote call.\n * Affects screen reader users.\n * Change it if you’re authoring in a different language.\n * @property {Handlers} [handlers]\n * Object mapping mdast nodes to functions handling them\n * @property {Array} [passThrough]\n * List of custom mdast node types to pass through (keep) in hast\n * @property {Handler} [unknownHandler]\n * Handler for all unknown nodes.\n *\n * @typedef {Record} Handlers\n * Map of node types to handlers\n * @typedef {HFunctionProps & HFunctionNoProps & HFields} H\n * Handle context\n */\n\nimport {u} from 'unist-builder'\nimport {visit} from 'unist-util-visit'\nimport {pointStart, pointEnd} from 'unist-util-position'\nimport {generated} from 'unist-util-generated'\nimport {definitions} from 'mdast-util-definitions'\nimport {one} from './traverse.js'\nimport {footer} from './footer.js'\nimport {handlers} from './handlers/index.js'\n\nconst own = {}.hasOwnProperty\n\n/**\n * Factory to transform.\n * @param {MdastNode} tree mdast node\n * @param {Options} [options] Configuration\n * @returns {H} `h` function\n */\nfunction factory(tree, options) {\n const settings = options || {}\n const dangerous = settings.allowDangerousHtml || false\n /** @type {Record} */\n const footnoteById = {}\n\n h.dangerous = dangerous\n h.clobberPrefix =\n settings.clobberPrefix === undefined || settings.clobberPrefix === null\n ? 'user-content-'\n : settings.clobberPrefix\n h.footnoteLabel = settings.footnoteLabel || 'Footnotes'\n h.footnoteBackLabel = settings.footnoteBackLabel || 'Back to content'\n h.definition = definitions(tree)\n h.footnoteById = footnoteById\n /** @type {Array} */\n h.footnoteOrder = []\n /** @type {Record} */\n h.footnoteCounts = {}\n h.augment = augment\n h.handlers = {...handlers, ...settings.handlers}\n h.unknownHandler = settings.unknownHandler\n h.passThrough = settings.passThrough\n\n visit(tree, 'footnoteDefinition', (definition) => {\n const id = String(definition.identifier).toUpperCase()\n\n // Mimick CM behavior of link definitions.\n // See: .\n if (!own.call(footnoteById, id)) {\n footnoteById[id] = definition\n }\n })\n\n // @ts-expect-error Hush, it’s fine!\n return h\n\n /**\n * Finalise the created `right`, a hast node, from `left`, an mdast node.\n * @param {(NodeWithData|PositionLike)?} left\n * @param {Content} right\n * @returns {Content}\n */\n function augment(left, right) {\n // Handle `data.hName`, `data.hProperties, `data.hChildren`.\n if (left && 'data' in left && left.data) {\n /** @type {Data} */\n const data = left.data\n\n if (data.hName) {\n if (right.type !== 'element') {\n right = {\n type: 'element',\n tagName: '',\n properties: {},\n children: []\n }\n }\n\n right.tagName = data.hName\n }\n\n if (right.type === 'element' && data.hProperties) {\n right.properties = {...right.properties, ...data.hProperties}\n }\n\n if ('children' in right && right.children && data.hChildren) {\n right.children = data.hChildren\n }\n }\n\n if (left) {\n const ctx = 'type' in left ? left : {position: left}\n\n if (!generated(ctx)) {\n right.position = {start: pointStart(ctx), end: pointEnd(ctx)}\n }\n }\n\n return right\n }\n\n /**\n * Create an element for `node`.\n *\n * @type {HFunctionProps}\n */\n function h(node, tagName, props, children) {\n if (Array.isArray(props)) {\n children = props\n props = {}\n }\n\n // @ts-expect-error augmenting an element yields an element.\n return augment(node, {\n type: 'element',\n tagName,\n properties: props || {},\n children: children || []\n })\n }\n}\n\n/**\n * Transform `tree` (an mdast node) to a hast node.\n *\n * @param {MdastNode} tree mdast node\n * @param {Options} [options] Configuration\n * @returns {HastNode|null|undefined} hast node\n */\nexport function toHast(tree, options) {\n const h = factory(tree, options)\n const node = one(h, tree, null)\n const foot = footer(h)\n\n if (foot) {\n // @ts-expect-error If there’s a footer, there were definitions, meaning block\n // content.\n // So assume `node` is a parent node.\n node.children.push(u('text', '\\n'), foot)\n }\n\n return Array.isArray(node) ? {type: 'root', children: node} : node\n}\n\nexport {handlers as defaultHandlers} from './handlers/index.js'\n","/**\n * @typedef {import('mdast').Root|import('mdast').Parent['children'][number]} MdastNode\n * @typedef {import('./index.js').H} H\n * @typedef {import('./index.js').Handler} Handler\n * @typedef {import('./index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\n\nconst own = {}.hasOwnProperty\n\n/**\n * Transform an unknown node.\n * @type {Handler}\n * @param {MdastNode} node\n */\nfunction unknown(h, node) {\n const data = node.data || {}\n\n if (\n 'value' in node &&\n !(\n own.call(data, 'hName') ||\n own.call(data, 'hProperties') ||\n own.call(data, 'hChildren')\n )\n ) {\n return h.augment(node, u('text', node.value))\n }\n\n return h(node, 'div', all(h, node))\n}\n\n/**\n * @type {Handler}\n * @param {MdastNode} node\n */\nexport function one(h, node, parent) {\n const type = node && node.type\n /** @type {Handler} */\n let fn\n\n // Fail on non-nodes.\n if (!type) {\n throw new Error('Expected node, got `' + node + '`')\n }\n\n if (own.call(h.handlers, type)) {\n fn = h.handlers[type]\n } else if (h.passThrough && h.passThrough.includes(type)) {\n fn = returnNode\n } else {\n fn = h.unknownHandler\n }\n\n return (typeof fn === 'function' ? fn : unknown)(h, node, parent)\n}\n\n/**\n * @type {Handler}\n * @param {MdastNode} node\n */\nfunction returnNode(h, node) {\n // @ts-expect-error: Pass through custom node.\n return 'children' in node ? {...node, children: all(h, node)} : node\n}\n\n/**\n * @param {H} h\n * @param {MdastNode} parent\n */\nexport function all(h, parent) {\n /** @type {Array} */\n const values = []\n\n if ('children' in parent) {\n const nodes = parent.children\n let index = -1\n\n while (++index < nodes.length) {\n const result = one(h, nodes[index], parent)\n\n if (result) {\n if (index && nodes[index - 1].type === 'break') {\n if (!Array.isArray(result) && result.type === 'text') {\n result.value = result.value.replace(/^\\s+/, '')\n }\n\n if (!Array.isArray(result) && result.type === 'element') {\n const head = result.children[0]\n\n if (head && head.type === 'text') {\n head.value = head.value.replace(/^\\s+/, '')\n }\n }\n }\n\n if (Array.isArray(result)) {\n values.push(...result)\n } else {\n values.push(result)\n }\n }\n }\n }\n\n return values\n}\n","/**\n * @typedef {import('./index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * Wrap `nodes` with line feeds between each entry.\n * Optionally adds line feeds at the start and end.\n *\n * @param {Array} nodes\n * @param {boolean} [loose=false]\n * @returns {Array}\n */\nexport function wrap(nodes, loose) {\n /** @type {Array} */\n const result = []\n let index = -1\n\n if (loose) {\n result.push(u('text', '\\n'))\n }\n\n while (++index < nodes.length) {\n if (index) result.push(u('text', '\\n'))\n result.push(nodes[index])\n }\n\n if (loose && nodes.length > 0) {\n result.push(u('text', '\\n'))\n }\n\n return result\n}\n","// This module is generated by `script/`.\n//\n// CommonMark handles attention (emphasis, strong) markers based on what comes\n// before or after them.\n// One such difference is if those characters are Unicode punctuation.\n// This script is generated from the Unicode data.\nexport const unicodePunctuationRegex =\n /[!-/:-@[-`{-~\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\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\\u1B5A-\\u1B60\\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\\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]/\n","/**\n * @typedef {import('micromark-util-types').Code} Code\n */\nimport {unicodePunctuationRegex} from './lib/unicode-punctuation-regex.js'\n/**\n * Check whether the character code represents an ASCII alpha (`a` through `z`,\n * case insensitive).\n *\n * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha.\n *\n * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`)\n * to U+005A (`Z`).\n *\n * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`)\n * to U+007A (`z`).\n */\n\nexport const asciiAlpha = regexCheck(/[A-Za-z]/)\n/**\n * Check whether the character code represents an ASCII digit (`0` through `9`).\n *\n * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to\n * U+0039 (`9`).\n */\n\nexport const asciiDigit = regexCheck(/\\d/)\n/**\n * Check whether the character code represents an ASCII hex digit (`a` through\n * `f`, case insensitive, or `0` through `9`).\n *\n * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex\n * digit, or an ASCII lower hex digit.\n *\n * An **ASCII upper hex digit** is a character in the inclusive range U+0041\n * (`A`) to U+0046 (`F`).\n *\n * An **ASCII lower hex digit** is a character in the inclusive range U+0061\n * (`a`) to U+0066 (`f`).\n */\n\nexport const asciiHexDigit = regexCheck(/[\\dA-Fa-f]/)\n/**\n * Check whether the character code represents an ASCII alphanumeric (`a`\n * through `z`, case insensitive, or `0` through `9`).\n *\n * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha\n * (see `asciiAlpha`).\n */\n\nexport const asciiAlphanumeric = regexCheck(/[\\dA-Za-z]/)\n/**\n * Check whether the character code represents ASCII punctuation.\n *\n * An **ASCII punctuation** is a character in the inclusive ranges U+0021\n * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT\n * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT\n * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`).\n */\n\nexport const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/)\n/**\n * Check whether the character code represents an ASCII atext.\n *\n * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in\n * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`),\n * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F\n * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E\n * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE\n * (`{`) to U+007E TILDE (`~`).\n *\n * See:\n * **\\[RFC5322]**:\n * [Internet Message Format](https://tools.ietf.org/html/rfc5322).\n * P. Resnick.\n * IETF.\n */\n\nexport const asciiAtext = regexCheck(/[#-'*+\\--9=?A-Z^-~]/)\n/**\n * Check whether a character code is an ASCII control character.\n *\n * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL)\n * to U+001F (US), or U+007F (DEL).\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function asciiControl(code) {\n return (\n // Special whitespace codes (which have negative values), C0 and Control\n // character DEL\n code !== null && (code < 32 || code === 127)\n )\n}\n/**\n * Check whether a character code is a markdown line ending (see\n * `markdownLineEnding`) or markdown space (see `markdownSpace`).\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function markdownLineEndingOrSpace(code) {\n return code !== null && (code < 0 || code === 32)\n}\n/**\n * Check whether a character code is a markdown line ending.\n *\n * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN\n * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR).\n *\n * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE\n * RETURN (CR) are replaced by these virtual characters depending on whether\n * they occurred together.\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function markdownLineEnding(code) {\n return code !== null && code < -2\n}\n/**\n * Check whether a character code is a markdown space.\n *\n * A **markdown space** is the concrete character U+0020 SPACE (SP) and the\n * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT).\n *\n * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is\n * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL\n * SPACE (VS) characters, depending on the column at which the tab occurred.\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function markdownSpace(code) {\n return code === -2 || code === -1 || code === 32\n}\n/**\n * Check whether the character code represents Unicode whitespace.\n *\n * Note that this does handle micromark specific markdown whitespace characters.\n * See `markdownLineEndingOrSpace` to check that.\n *\n * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator,\n * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF),\n * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\\[UNICODE]**).\n *\n * See:\n * **\\[UNICODE]**:\n * [The Unicode Standard](https://www.unicode.org/versions/).\n * Unicode Consortium.\n */\n\nexport const unicodeWhitespace = regexCheck(/\\s/)\n/**\n * Check whether the character code represents Unicode punctuation.\n *\n * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation,\n * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf`\n * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po`\n * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII\n * punctuation (see `asciiPunctuation`).\n *\n * See:\n * **\\[UNICODE]**:\n * [The Unicode Standard](https://www.unicode.org/versions/).\n * Unicode Consortium.\n */\n// Size note: removing ASCII from the regex and using `asciiPunctuation` here\n// In fact adds to the bundle size.\n\nexport const unicodePunctuation = regexCheck(unicodePunctuationRegex)\n/**\n * Create a code check from a regex.\n *\n * @param {RegExp} regex\n * @returns {(code: Code) => code is number}\n */\n\nfunction regexCheck(regex) {\n return check\n /**\n * Check whether a code matches the bound regex.\n *\n * @param {Code} code Character code\n * @returns {code is number} Whether the character code matches the bound regex\n */\n\n function check(code) {\n return code !== null && regex.test(String.fromCharCode(code))\n }\n}\n","const characterReferences = {'\"': 'quot', '&': 'amp', '<': 'lt', '>': 'gt'}\n\n/**\n * Encode only the dangerous HTML characters.\n *\n * This ensures that certain characters which have special meaning in HTML are\n * dealt with.\n * Technically, we can skip `>` and `\"` in many cases, but CM includes them.\n *\n * @param {string} value\n * @returns {string}\n */\nexport function encode(value) {\n return value.replace(/[\"&<>]/g, replace)\n\n /**\n * @param {string} value\n * @returns {string}\n */\n function replace(value) {\n // @ts-expect-error Hush, it’s fine.\n return '&' + characterReferences[value] + ';'\n }\n}\n","import {asciiAlphanumeric} from 'micromark-util-character'\nimport {encode} from 'micromark-util-encode'\n\n/**\n * Make a value safe for injection as a URL.\n *\n * This encodes unsafe characters with percent-encoding and skips already\n * encoded sequences (see `normalizeUri` below).\n * Further unsafe characters are encoded as character references (see\n * `micromark-util-encode`).\n *\n * Then, a regex of allowed protocols can be given, in which case the URL is\n * sanitized.\n * For example, `/^(https?|ircs?|mailto|xmpp)$/i` can be used for `a[href]`,\n * or `/^https?$/i` for `img[src]`.\n * If the URL includes an unknown protocol (one not matched by `protocol`, such\n * as a dangerous example, `javascript:`), the value is ignored.\n *\n * @param {string|undefined} url\n * @param {RegExp} [protocol]\n * @returns {string}\n */\nexport function sanitizeUri(url, protocol) {\n const value = encode(normalizeUri(url || ''))\n\n if (!protocol) {\n return value\n }\n\n const colon = value.indexOf(':')\n const questionMark = value.indexOf('?')\n const numberSign = value.indexOf('#')\n const slash = value.indexOf('/')\n\n if (\n // If there is no protocol, it’s relative.\n colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol.\n (slash > -1 && colon > slash) ||\n (questionMark > -1 && colon > questionMark) ||\n (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed.\n protocol.test(value.slice(0, colon))\n ) {\n return value\n }\n\n return ''\n}\n/**\n * Normalize a URL (such as used in definitions).\n *\n * Encode unsafe characters with percent-encoding, skipping already encoded\n * sequences.\n *\n * @param {string} value\n * @returns {string}\n */\n\nfunction normalizeUri(value) {\n /** @type {string[]} */\n const result = []\n let index = -1\n let start = 0\n let skip = 0\n\n while (++index < value.length) {\n const code = value.charCodeAt(index)\n /** @type {string} */\n\n let replace = '' // A correct percent encoded value.\n\n if (\n code === 37 &&\n asciiAlphanumeric(value.charCodeAt(index + 1)) &&\n asciiAlphanumeric(value.charCodeAt(index + 2))\n ) {\n skip = 2\n } // ASCII.\n else if (code < 128) {\n if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) {\n replace = String.fromCharCode(code)\n }\n } // Astral.\n else if (code > 55295 && code < 57344) {\n const next = value.charCodeAt(index + 1) // A correct surrogate pair.\n\n if (code < 56320 && next > 56319 && next < 57344) {\n replace = String.fromCharCode(code, next)\n skip = 1\n } // Lone surrogate.\n else {\n replace = '\\uFFFD'\n }\n } // Unicode.\n else {\n replace = String.fromCharCode(code)\n }\n\n if (replace) {\n result.push(value.slice(start, index), encodeURIComponent(replace))\n start = index + skip + 1\n replace = ''\n }\n\n if (skip) {\n index += skip\n skip = 0\n }\n }\n\n return result.join('') + value.slice(start)\n}\n","/**\n * Throw a given error.\n *\n * @param {Error|null|undefined} [error]\n * Maybe error.\n * @returns {asserts error is null|undefined}\n */\nexport function bail(error) {\n if (error) {\n throw error\n }\n}\n","export default function isPlainObject(value) {\n\tif (Object.prototype.toString.call(value) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === null || prototype === Object.prototype;\n}\n","/**\n * @typedef {(error?: Error|null|undefined, ...output: Array) => void} Callback\n * @typedef {(...input: Array) => any} Middleware\n *\n * @typedef {(...input: Array) => void} Run\n * Call all middleware.\n * @typedef {(fn: Middleware) => Pipeline} Use\n * Add `fn` (middleware) to the list.\n * @typedef {{run: Run, use: Use}} Pipeline\n * Middleware.\n */\n\n/**\n * Create new middleware.\n *\n * @returns {Pipeline}\n */\nexport function trough() {\n /** @type {Array} */\n const fns = []\n /** @type {Pipeline} */\n const pipeline = {run, use}\n\n return pipeline\n\n /** @type {Run} */\n function run(...values) {\n let middlewareIndex = -1\n /** @type {Callback} */\n const callback = values.pop()\n\n if (typeof callback !== 'function') {\n throw new TypeError('Expected function as last argument, not ' + callback)\n }\n\n next(null, ...values)\n\n /**\n * Run the next `fn`, or we’re done.\n *\n * @param {Error|null|undefined} error\n * @param {Array} output\n */\n function next(error, ...output) {\n const fn = fns[++middlewareIndex]\n let index = -1\n\n if (error) {\n callback(error)\n return\n }\n\n // Copy non-nullish input into values.\n while (++index < values.length) {\n if (output[index] === null || output[index] === undefined) {\n output[index] = values[index]\n }\n }\n\n // Save the newly created `output` for the next call.\n values = output\n\n // Next or done.\n if (fn) {\n wrap(fn, next)(...output)\n } else {\n callback(null, ...output)\n }\n }\n }\n\n /** @type {Use} */\n function use(middelware) {\n if (typeof middelware !== 'function') {\n throw new TypeError(\n 'Expected `middelware` to be a function, not ' + middelware\n )\n }\n\n fns.push(middelware)\n return pipeline\n }\n}\n\n/**\n * Wrap `middleware`.\n * Can be sync or async; return a promise, receive a callback, or return new\n * values and errors.\n *\n * @param {Middleware} middleware\n * @param {Callback} callback\n */\nexport function wrap(middleware, callback) {\n /** @type {boolean} */\n let called\n\n return wrapped\n\n /**\n * Call `middleware`.\n * @this {any}\n * @param {Array} parameters\n * @returns {void}\n */\n function wrapped(...parameters) {\n const fnExpectsCallback = middleware.length > parameters.length\n /** @type {any} */\n let result\n\n if (fnExpectsCallback) {\n parameters.push(done)\n }\n\n try {\n result = middleware.apply(this, parameters)\n } catch (error) {\n const exception = /** @type {Error} */ (error)\n\n // Well, this is quite the pickle.\n // `middleware` received a callback and called it synchronously, but that\n // threw an error.\n // The only thing left to do is to throw the thing instead.\n if (fnExpectsCallback && called) {\n throw exception\n }\n\n return done(exception)\n }\n\n if (!fnExpectsCallback) {\n if (result instanceof Promise) {\n result.then(then, done)\n } else if (result instanceof Error) {\n done(result)\n } else {\n then(result)\n }\n }\n }\n\n /**\n * Call `callback`, only once.\n * @type {Callback}\n */\n function done(error, ...output) {\n if (!called) {\n called = true\n callback(error, ...output)\n }\n }\n\n /**\n * Call `done` with one value.\n *\n * @param {any} [value]\n */\n function then(value) {\n done(null, value)\n }\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('vfile').VFileCompatible} VFileCompatible\n * @typedef {import('vfile').VFileValue} VFileValue\n * @typedef {import('..').Processor} Processor\n * @typedef {import('..').Plugin} Plugin\n * @typedef {import('..').Preset} Preset\n * @typedef {import('..').Pluggable} Pluggable\n * @typedef {import('..').PluggableList} PluggableList\n * @typedef {import('..').Transformer} Transformer\n * @typedef {import('..').Parser} Parser\n * @typedef {import('..').Compiler} Compiler\n * @typedef {import('..').RunCallback} RunCallback\n * @typedef {import('..').ProcessCallback} ProcessCallback\n *\n * @typedef Context\n * @property {Node} tree\n * @property {VFile} file\n */\n\nimport {bail} from 'bail'\nimport isBuffer from 'is-buffer'\nimport extend from 'extend'\nimport isPlainObj from 'is-plain-obj'\nimport {trough} from 'trough'\nimport {VFile} from 'vfile'\n\n// Expose a frozen processor.\nexport const unified = base().freeze()\n\nconst own = {}.hasOwnProperty\n\n// Function to create the first processor.\n/**\n * @returns {Processor}\n */\nfunction base() {\n const transformers = trough()\n /** @type {Processor['attachers']} */\n const attachers = []\n /** @type {Record} */\n let namespace = {}\n /** @type {boolean|undefined} */\n let frozen\n let freezeIndex = -1\n\n // Data management.\n // @ts-expect-error: overloads are handled.\n processor.data = data\n processor.Parser = undefined\n processor.Compiler = undefined\n\n // Lock.\n processor.freeze = freeze\n\n // Plugins.\n processor.attachers = attachers\n // @ts-expect-error: overloads are handled.\n processor.use = use\n\n // API.\n processor.parse = parse\n processor.stringify = stringify\n // @ts-expect-error: overloads are handled.\n processor.run = run\n processor.runSync = runSync\n // @ts-expect-error: overloads are handled.\n processor.process = process\n processor.processSync = processSync\n\n // Expose.\n return processor\n\n // Create a new processor based on the processor in the current scope.\n /** @type {Processor} */\n function processor() {\n const destination = base()\n let index = -1\n\n while (++index < attachers.length) {\n destination.use(...attachers[index])\n }\n\n destination.data(extend(true, {}, namespace))\n\n return destination\n }\n\n /**\n * @param {string|Record} [key]\n * @param {unknown} [value]\n * @returns {unknown}\n */\n function data(key, value) {\n if (typeof key === 'string') {\n // Set `key`.\n if (arguments.length === 2) {\n assertUnfrozen('data', frozen)\n namespace[key] = value\n return processor\n }\n\n // Get `key`.\n return (own.call(namespace, key) && namespace[key]) || null\n }\n\n // Set space.\n if (key) {\n assertUnfrozen('data', frozen)\n namespace = key\n return processor\n }\n\n // Get space.\n return namespace\n }\n\n /** @type {Processor['freeze']} */\n function freeze() {\n if (frozen) {\n return processor\n }\n\n while (++freezeIndex < attachers.length) {\n const [attacher, ...options] = attachers[freezeIndex]\n\n if (options[0] === false) {\n continue\n }\n\n if (options[0] === true) {\n options[0] = undefined\n }\n\n /** @type {Transformer|void} */\n const transformer = attacher.call(processor, ...options)\n\n if (typeof transformer === 'function') {\n transformers.use(transformer)\n }\n }\n\n frozen = true\n freezeIndex = Number.POSITIVE_INFINITY\n\n return processor\n }\n\n /**\n * @param {Pluggable|null|undefined} [value]\n * @param {...unknown} options\n * @returns {Processor}\n */\n function use(value, ...options) {\n /** @type {Record|undefined} */\n let settings\n\n assertUnfrozen('use', frozen)\n\n if (value === null || value === undefined) {\n // Empty.\n } else if (typeof value === 'function') {\n addPlugin(value, ...options)\n } else if (typeof value === 'object') {\n if (Array.isArray(value)) {\n addList(value)\n } else {\n addPreset(value)\n }\n } else {\n throw new TypeError('Expected usable value, not `' + value + '`')\n }\n\n if (settings) {\n namespace.settings = Object.assign(namespace.settings || {}, settings)\n }\n\n return processor\n\n /**\n * @param {import('..').Pluggable} value\n * @returns {void}\n */\n function add(value) {\n if (typeof value === 'function') {\n addPlugin(value)\n } else if (typeof value === 'object') {\n if (Array.isArray(value)) {\n const [plugin, ...options] = value\n addPlugin(plugin, ...options)\n } else {\n addPreset(value)\n }\n } else {\n throw new TypeError('Expected usable value, not `' + value + '`')\n }\n }\n\n /**\n * @param {Preset} result\n * @returns {void}\n */\n function addPreset(result) {\n addList(result.plugins)\n\n if (result.settings) {\n settings = Object.assign(settings || {}, result.settings)\n }\n }\n\n /**\n * @param {PluggableList|null|undefined} [plugins]\n * @returns {void}\n */\n function addList(plugins) {\n let index = -1\n\n if (plugins === null || plugins === undefined) {\n // Empty.\n } else if (Array.isArray(plugins)) {\n while (++index < plugins.length) {\n const thing = plugins[index]\n add(thing)\n }\n } else {\n throw new TypeError('Expected a list of plugins, not `' + plugins + '`')\n }\n }\n\n /**\n * @param {Plugin} plugin\n * @param {...unknown} [value]\n * @returns {void}\n */\n function addPlugin(plugin, value) {\n let index = -1\n /** @type {Processor['attachers'][number]|undefined} */\n let entry\n\n while (++index < attachers.length) {\n if (attachers[index][0] === plugin) {\n entry = attachers[index]\n break\n }\n }\n\n if (entry) {\n if (isPlainObj(entry[1]) && isPlainObj(value)) {\n value = extend(true, entry[1], value)\n }\n\n entry[1] = value\n } else {\n // @ts-expect-error: fine.\n attachers.push([...arguments])\n }\n }\n }\n\n /** @type {Processor['parse']} */\n function parse(doc) {\n processor.freeze()\n const file = vfile(doc)\n const Parser = processor.Parser\n assertParser('parse', Parser)\n\n if (newable(Parser, 'parse')) {\n // @ts-expect-error: `newable` checks this.\n return new Parser(String(file), file).parse()\n }\n\n // @ts-expect-error: `newable` checks this.\n return Parser(String(file), file) // eslint-disable-line new-cap\n }\n\n /** @type {Processor['stringify']} */\n function stringify(node, doc) {\n processor.freeze()\n const file = vfile(doc)\n const Compiler = processor.Compiler\n assertCompiler('stringify', Compiler)\n assertNode(node)\n\n if (newable(Compiler, 'compile')) {\n // @ts-expect-error: `newable` checks this.\n return new Compiler(node, file).compile()\n }\n\n // @ts-expect-error: `newable` checks this.\n return Compiler(node, file) // eslint-disable-line new-cap\n }\n\n /**\n * @param {Node} node\n * @param {VFileCompatible|RunCallback} [doc]\n * @param {RunCallback} [callback]\n * @returns {Promise|void}\n */\n function run(node, doc, callback) {\n assertNode(node)\n processor.freeze()\n\n if (!callback && typeof doc === 'function') {\n callback = doc\n doc = undefined\n }\n\n if (!callback) {\n return new Promise(executor)\n }\n\n executor(null, callback)\n\n /**\n * @param {null|((node: Node) => void)} resolve\n * @param {(error: Error) => void} reject\n * @returns {void}\n */\n function executor(resolve, reject) {\n // @ts-expect-error: `doc` can’t be a callback anymore, we checked.\n transformers.run(node, vfile(doc), done)\n\n /**\n * @param {Error|null} error\n * @param {Node} tree\n * @param {VFile} file\n * @returns {void}\n */\n function done(error, tree, file) {\n tree = tree || node\n if (error) {\n reject(error)\n } else if (resolve) {\n resolve(tree)\n } else {\n // @ts-expect-error: `callback` is defined if `resolve` is not.\n callback(null, tree, file)\n }\n }\n }\n }\n\n /** @type {Processor['runSync']} */\n function runSync(node, file) {\n /** @type {Node|undefined} */\n let result\n /** @type {boolean|undefined} */\n let complete\n\n processor.run(node, file, done)\n\n assertDone('runSync', 'run', complete)\n\n // @ts-expect-error: we either bailed on an error or have a tree.\n return result\n\n /**\n * @param {Error|null} [error]\n * @param {Node} [tree]\n * @returns {void}\n */\n function done(error, tree) {\n bail(error)\n result = tree\n complete = true\n }\n }\n\n /**\n * @param {VFileCompatible} doc\n * @param {ProcessCallback} [callback]\n * @returns {Promise|undefined}\n */\n function process(doc, callback) {\n processor.freeze()\n assertParser('process', processor.Parser)\n assertCompiler('process', processor.Compiler)\n\n if (!callback) {\n return new Promise(executor)\n }\n\n executor(null, callback)\n\n /**\n * @param {null|((file: VFile) => void)} resolve\n * @param {(error?: Error|null|undefined) => void} reject\n * @returns {void}\n */\n function executor(resolve, reject) {\n const file = vfile(doc)\n\n processor.run(processor.parse(file), file, (error, tree, file) => {\n if (error || !tree || !file) {\n done(error)\n } else {\n /** @type {unknown} */\n const result = processor.stringify(tree, file)\n\n if (result === undefined || result === null) {\n // Empty.\n } else if (looksLikeAVFileValue(result)) {\n file.value = result\n } else {\n file.result = result\n }\n\n done(error, file)\n }\n })\n\n /**\n * @param {Error|null|undefined} [error]\n * @param {VFile|undefined} [file]\n * @returns {void}\n */\n function done(error, file) {\n if (error || !file) {\n reject(error)\n } else if (resolve) {\n resolve(file)\n } else {\n // @ts-expect-error: `callback` is defined if `resolve` is not.\n callback(null, file)\n }\n }\n }\n }\n\n /** @type {Processor['processSync']} */\n function processSync(doc) {\n /** @type {boolean|undefined} */\n let complete\n\n processor.freeze()\n assertParser('processSync', processor.Parser)\n assertCompiler('processSync', processor.Compiler)\n\n const file = vfile(doc)\n\n processor.process(file, done)\n\n assertDone('processSync', 'process', complete)\n\n return file\n\n /**\n * @param {Error|null|undefined} [error]\n * @returns {void}\n */\n function done(error) {\n complete = true\n bail(error)\n }\n }\n}\n\n/**\n * Check if `value` is a constructor.\n *\n * @param {unknown} value\n * @param {string} name\n * @returns {boolean}\n */\nfunction newable(value, name) {\n return (\n typeof value === 'function' &&\n // Prototypes do exist.\n // type-coverage:ignore-next-line\n value.prototype &&\n // A function with keys in its prototype is probably a constructor.\n // Classes’ prototype methods are not enumerable, so we check if some value\n // exists in the prototype.\n // type-coverage:ignore-next-line\n (keys(value.prototype) || name in value.prototype)\n )\n}\n\n/**\n * Check if `value` is an object with keys.\n *\n * @param {Record} value\n * @returns {boolean}\n */\nfunction keys(value) {\n /** @type {string} */\n let key\n\n for (key in value) {\n if (own.call(value, key)) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Assert a parser is available.\n *\n * @param {string} name\n * @param {unknown} value\n * @returns {asserts value is Parser}\n */\nfunction assertParser(name, value) {\n if (typeof value !== 'function') {\n throw new TypeError('Cannot `' + name + '` without `Parser`')\n }\n}\n\n/**\n * Assert a compiler is available.\n *\n * @param {string} name\n * @param {unknown} value\n * @returns {asserts value is Compiler}\n */\nfunction assertCompiler(name, value) {\n if (typeof value !== 'function') {\n throw new TypeError('Cannot `' + name + '` without `Compiler`')\n }\n}\n\n/**\n * Assert the processor is not frozen.\n *\n * @param {string} name\n * @param {unknown} frozen\n * @returns {asserts frozen is false}\n */\nfunction assertUnfrozen(name, frozen) {\n if (frozen) {\n throw new Error(\n 'Cannot call `' +\n name +\n '` on a frozen processor.\\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.'\n )\n }\n}\n\n/**\n * Assert `node` is a unist node.\n *\n * @param {unknown} node\n * @returns {asserts node is Node}\n */\nfunction assertNode(node) {\n // `isPlainObj` unfortunately uses `any` instead of `unknown`.\n // type-coverage:ignore-next-line\n if (!isPlainObj(node) || typeof node.type !== 'string') {\n throw new TypeError('Expected node, got `' + node + '`')\n // Fine.\n }\n}\n\n/**\n * Assert that `complete` is `true`.\n *\n * @param {string} name\n * @param {string} asyncName\n * @param {unknown} complete\n * @returns {asserts complete is true}\n */\nfunction assertDone(name, asyncName, complete) {\n if (!complete) {\n throw new Error(\n '`' + name + '` finished async. Use `' + asyncName + '` instead'\n )\n }\n}\n\n/**\n * @param {VFileCompatible} [value]\n * @returns {VFile}\n */\nfunction vfile(value) {\n return looksLikeAVFile(value) ? value : new VFile(value)\n}\n\n/**\n * @param {VFileCompatible} [value]\n * @returns {value is VFile}\n */\nfunction looksLikeAVFile(value) {\n return Boolean(\n value &&\n typeof value === 'object' &&\n 'message' in value &&\n 'messages' in value\n )\n}\n\n/**\n * @param {unknown} [value]\n * @returns {value is VFileValue}\n */\nfunction looksLikeAVFileValue(value) {\n return typeof value === 'string' || isBuffer(value)\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist').Literal} Literal\n * @typedef {Object.} Props\n * @typedef {Array.|string} ChildrenOrValue\n *\n * @typedef {(, C extends Node[]>(type: T, props: P, children: C) => {type: T, children: C} & P)} BuildParentWithProps\n * @typedef {(>(type: T, props: P, value: string) => {type: T, value: string} & P)} BuildLiteralWithProps\n * @typedef {(>(type: T, props: P) => {type: T} & P)} BuildVoidWithProps\n * @typedef {((type: T, children: C) => {type: T, children: C})} BuildParent\n * @typedef {((type: T, value: string) => {type: T, value: string})} BuildLiteral\n * @typedef {((type: T) => {type: T})} BuildVoid\n */\n\nexport var u = /**\n * @type {BuildVoid & BuildVoidWithProps & BuildLiteral & BuildLiteralWithProps & BuildParent & BuildParentWithProps}\n */ (\n /**\n * @param {string} type Type of node\n * @param {Props|ChildrenOrValue} [props] Additional properties for node (or `children` or `value`)\n * @param {ChildrenOrValue} [value] `children` or `value` of node\n * @returns {Node}\n */\n function (type, props, value) {\n /** @type {Node} */\n var node = {type: String(type)}\n\n if (\n (value === undefined || value === null) &&\n (typeof props === 'string' || Array.isArray(props))\n ) {\n value = props\n } else {\n Object.assign(node, props)\n }\n\n if (Array.isArray(value)) {\n node.children = value\n } else if (value !== undefined && value !== null) {\n node.value = String(value)\n }\n\n return node\n }\n)\n","/**\n * @typedef {Object} PointLike\n * @property {number} [line]\n * @property {number} [column]\n * @property {number} [offset]\n *\n * @typedef {Object} PositionLike\n * @property {PointLike} [start]\n * @property {PointLike} [end]\n *\n * @typedef {Object} NodeLike\n * @property {PositionLike} [position]\n */\n\n/**\n * Check if `node` is *generated*.\n *\n * @param {NodeLike} [node]\n * @returns {boolean}\n */\nexport function generated(node) {\n return (\n !node ||\n !node.position ||\n !node.position.start ||\n !node.position.start.line ||\n !node.position.start.column ||\n !node.position.end ||\n !node.position.end.line ||\n !node.position.end.column\n )\n}\n","/**\n * @typedef {import('unist').Position} Position\n * @typedef {import('unist').Node} Node\n * @typedef {Record & {type: string, position?: PositionLike|undefined}} NodeLike\n * @typedef {import('unist').Point} Point\n *\n * @typedef {Partial} PointLike\n *\n * @typedef PositionLike\n * @property {PointLike} [start]\n * @property {PointLike} [end]\n */\n\nexport const pointStart = point('start')\nexport const pointEnd = point('end')\n\n/**\n * Get the positional info of `node`.\n *\n * @param {NodeLike|Node} [node]\n * @returns {Position}\n */\nexport function position(node) {\n return {start: pointStart(node), end: pointEnd(node)}\n}\n\n/**\n * Get the positional info of `node`.\n *\n * @param {'start'|'end'} type\n */\nfunction point(type) {\n return point\n\n /**\n * Get the positional info of `node`.\n *\n * @param {NodeLike|Node} [node]\n * @returns {Point}\n */\n function point(node) {\n const point = (node && node.position && node.position[type]) || {}\n\n return {\n line: point.line || null,\n column: point.column || null,\n offset: point.offset > -1 ? point.offset : null\n }\n }\n}\n","/**\n * @typedef {import('unist').Point} Point\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Position} Position\n * @typedef {object & {type: string, position?: Position|undefined}} NodeLike\n */\n\n/**\n * Stringify one point, a position (start and end points), or a node’s\n * positional information.\n *\n * @param {Node|NodeLike|Position|Point|null} [value]\n * @returns {string}\n */\nexport function stringifyPosition(value) {\n // Nothing.\n if (!value || typeof value !== 'object') {\n return ''\n }\n\n // Node.\n if ('position' in value || 'type' in value) {\n return position(value.position)\n }\n\n // Position.\n if ('start' in value || 'end' in value) {\n return position(value)\n }\n\n // Point.\n if ('line' in value || 'column' in value) {\n return point(value)\n }\n\n // ?\n return ''\n}\n\n/**\n * @param {Point|undefined} point\n * @returns {string}\n */\nfunction point(point) {\n return index(point && point.line) + ':' + index(point && point.column)\n}\n\n/**\n * @param {Position|undefined} pos\n * @returns {string}\n */\nfunction position(pos) {\n return point(pos && pos.start) + '-' + point(pos && pos.end)\n}\n\n/**\n * @param {number|undefined} value\n * @returns {number}\n */\nfunction index(value) {\n return value && typeof value === 'number' ? value : 1\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Position} Position\n * @typedef {import('unist').Point} Point\n * @typedef {object & {type: string, position?: Position|undefined}} NodeLike\n */\n\nimport {stringifyPosition} from 'unist-util-stringify-position'\n\nexport class VFileMessage extends Error {\n /**\n * Constructor of a message for `reason` at `place` from `origin`.\n * When an error is passed in as `reason`, copies the `stack`.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n */\n constructor(reason, place, origin) {\n /** @type {[string|null, string|null]} */\n const parts = [null, null]\n /** @type {Position} */\n let position = {\n // @ts-expect-error: we always follows the structure of `position`.\n start: {line: null, column: null},\n // @ts-expect-error: \"\n end: {line: null, column: null}\n }\n\n super()\n\n if (typeof place === 'string') {\n origin = place\n place = undefined\n }\n\n if (typeof origin === 'string') {\n const index = origin.indexOf(':')\n\n if (index === -1) {\n parts[1] = origin\n } else {\n parts[0] = origin.slice(0, index)\n parts[1] = origin.slice(index + 1)\n }\n }\n\n if (place) {\n // Node.\n if ('type' in place || 'position' in place) {\n if (place.position) {\n position = place.position\n }\n }\n // Position.\n else if ('start' in place || 'end' in place) {\n position = place\n }\n // Point.\n else if ('line' in place || 'column' in place) {\n position.start = place\n }\n }\n\n // Fields from `Error`\n this.name = stringifyPosition(place) || '1:1'\n this.message = typeof reason === 'object' ? reason.message : reason\n this.stack = typeof reason === 'object' ? reason.stack : ''\n\n /**\n * Reason for message.\n * @type {string}\n */\n this.reason = this.message\n /**\n * If true, marks associated file as no longer processable.\n * @type {boolean?}\n */\n // eslint-disable-next-line no-unused-expressions\n this.fatal\n /**\n * Starting line of error.\n * @type {number?}\n */\n this.line = position.start.line\n /**\n * Starting column of error.\n * @type {number?}\n */\n this.column = position.start.column\n /**\n * Namespace of warning.\n * @type {string?}\n */\n this.source = parts[0]\n /**\n * Category of message.\n * @type {string?}\n */\n this.ruleId = parts[1]\n /**\n * Full range information, when available.\n * Has start and end properties, both set to an object with line and column, set to number?.\n * @type {Position?}\n */\n this.position = position\n\n // The following fields are “well known”.\n // Not standard.\n // Feel free to add other non-standard fields to your messages.\n\n /* eslint-disable no-unused-expressions */\n /**\n * You can use this to specify the source value that’s being reported, which\n * is deemed incorrect.\n * @type {string?}\n */\n this.actual\n /**\n * You can use this to suggest values that should be used instead of\n * `actual`, one or more values that are deemed as acceptable.\n * @type {Array?}\n */\n this.expected\n /**\n * You may add a file property with a path of a file (used throughout the VFile ecosystem).\n * @type {string?}\n */\n this.file\n /**\n * You may add a url property with a link to documentation for the message.\n * @type {string?}\n */\n this.url\n /**\n * You may add a note property with a long form description of the message (supported by vfile-reporter).\n * @type {string?}\n */\n this.note\n /* eslint-enable no-unused-expressions */\n }\n}\n\nVFileMessage.prototype.file = ''\nVFileMessage.prototype.name = ''\nVFileMessage.prototype.reason = ''\nVFileMessage.prototype.message = ''\nVFileMessage.prototype.stack = ''\nVFileMessage.prototype.fatal = null\nVFileMessage.prototype.column = null\nVFileMessage.prototype.line = null\nVFileMessage.prototype.source = null\nVFileMessage.prototype.ruleId = null\nVFileMessage.prototype.position = null\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"process\");","/**\n * @typedef URL\n * @property {string} hash\n * @property {string} host\n * @property {string} hostname\n * @property {string} href\n * @property {string} origin\n * @property {string} password\n * @property {string} pathname\n * @property {string} port\n * @property {string} protocol\n * @property {string} search\n * @property {any} searchParams\n * @property {string} username\n * @property {() => string} toString\n * @property {() => string} toJSON\n */\n\n/**\n * @param {unknown} fileURLOrPath\n * @returns {fileURLOrPath is URL}\n */\n// From: \nexport function isUrl(fileURLOrPath) {\n return (\n fileURLOrPath !== null &&\n typeof fileURLOrPath === 'object' &&\n // @ts-expect-error: indexable.\n fileURLOrPath.href &&\n // @ts-expect-error: indexable.\n fileURLOrPath.origin\n )\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Position} Position\n * @typedef {import('unist').Point} Point\n * @typedef {Record & {type: string, position?: Position|undefined}} NodeLike\n * @typedef {import('./minurl.shared.js').URL} URL\n * @typedef {import('..').VFileData} VFileData\n * @typedef {import('..').VFileValue} VFileValue\n *\n * @typedef {'ascii'|'utf8'|'utf-8'|'utf16le'|'ucs2'|'ucs-2'|'base64'|'base64url'|'latin1'|'binary'|'hex'} BufferEncoding\n * Encodings supported by the buffer class.\n * This is a copy of the typing from Node, copied to prevent Node globals from\n * being needed.\n * Copied from: \n *\n * @typedef {VFileValue|VFileOptions|VFile|URL} VFileCompatible\n * Things that can be passed to the constructor.\n *\n * @typedef VFileCoreOptions\n * @property {VFileValue} [value]\n * @property {string} [cwd]\n * @property {Array} [history]\n * @property {string|URL} [path]\n * @property {string} [basename]\n * @property {string} [stem]\n * @property {string} [extname]\n * @property {string} [dirname]\n * @property {VFileData} [data]\n *\n * @typedef Map\n * Raw source map, see:\n * .\n * @property {number} version\n * @property {Array} sources\n * @property {Array} names\n * @property {string|undefined} [sourceRoot]\n * @property {Array|undefined} [sourcesContent]\n * @property {string} mappings\n * @property {string} file\n *\n * @typedef {{[key: string]: unknown} & VFileCoreOptions} VFileOptions\n * Configuration: a bunch of keys that will be shallow copied over to the new\n * file.\n *\n * @typedef {Record} VFileReporterSettings\n * @typedef {(files: Array, options: T) => string} VFileReporter\n */\n\nimport buffer from 'is-buffer'\nimport {VFileMessage} from 'vfile-message'\nimport {path} from './minpath.js'\nimport {proc} from './minproc.js'\nimport {urlToPath, isUrl} from './minurl.js'\n\n// Order of setting (least specific to most), we need this because otherwise\n// `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a\n// stem can be set.\nconst order = ['history', 'path', 'basename', 'stem', 'extname', 'dirname']\n\nexport class VFile {\n /**\n * Create a new virtual file.\n *\n * If `options` is `string` or `Buffer`, treats it as `{value: options}`.\n * If `options` is a `VFile`, shallow copies its data over to the new file.\n * All other given fields are set on the newly created `VFile`.\n *\n * Path related properties are set in the following order (least specific to\n * most specific): `history`, `path`, `basename`, `stem`, `extname`,\n * `dirname`.\n *\n * It’s not possible to set either `dirname` or `extname` without setting\n * either `history`, `path`, `basename`, or `stem` as well.\n *\n * @param {VFileCompatible} [value]\n */\n constructor(value) {\n /** @type {VFileOptions} */\n let options\n\n if (!value) {\n options = {}\n } else if (typeof value === 'string' || buffer(value)) {\n // @ts-expect-error Looks like a buffer.\n options = {value}\n } else if (isUrl(value)) {\n options = {path: value}\n } else {\n // @ts-expect-error Looks like file or options.\n options = value\n }\n\n /**\n * Place to store custom information.\n * It’s OK to store custom data directly on the file, moving it to `data`\n * gives a little more privacy.\n * @type {VFileData}\n */\n this.data = {}\n\n /**\n * List of messages associated with the file.\n * @type {Array}\n */\n this.messages = []\n\n /**\n * List of file paths the file moved between.\n * @type {Array}\n */\n this.history = []\n\n /**\n * Base of `path`.\n * Defaults to `process.cwd()` (`/` in browsers).\n * @type {string}\n */\n this.cwd = proc.cwd()\n\n /* eslint-disable no-unused-expressions */\n /**\n * Raw value.\n * @type {VFileValue}\n */\n this.value\n\n // The below are non-standard, they are “well-known”.\n // As in, used in several tools.\n\n /**\n * Whether a file was saved to disk.\n * This is used by vfile reporters.\n * @type {boolean}\n */\n this.stored\n\n /**\n * Sometimes files have a non-string representation.\n * This can be stored in the `result` field.\n * One example is when turning markdown into React nodes.\n * This is used by unified to store non-string results.\n * @type {unknown}\n */\n this.result\n\n /**\n * Sometimes files have a source map associated with them.\n * This can be stored in the `map` field.\n * This should be a `RawSourceMap` type from the `source-map` module.\n * @type {Map|undefined}\n */\n this.map\n /* eslint-enable no-unused-expressions */\n\n // Set path related properties in the correct order.\n let index = -1\n\n while (++index < order.length) {\n const prop = order[index]\n\n // Note: we specifically use `in` instead of `hasOwnProperty` to accept\n // `vfile`s too.\n if (prop in options && options[prop] !== undefined) {\n // @ts-expect-error: TS is confused by the different types for `history`.\n this[prop] = prop === 'history' ? [...options[prop]] : options[prop]\n }\n }\n\n /** @type {string} */\n let prop\n\n // Set non-path related properties.\n for (prop in options) {\n // @ts-expect-error: fine to set other things.\n if (!order.includes(prop)) this[prop] = options[prop]\n }\n }\n\n /**\n * Access full path (`~/index.min.js`).\n *\n * @returns {string}\n */\n get path() {\n return this.history[this.history.length - 1]\n }\n\n /**\n * Set full path (`~/index.min.js`).\n * Cannot be nullified.\n *\n * @param {string|URL} path\n */\n set path(path) {\n if (isUrl(path)) {\n path = urlToPath(path)\n }\n\n assertNonEmpty(path, 'path')\n\n if (this.path !== path) {\n this.history.push(path)\n }\n }\n\n /**\n * Access parent path (`~`).\n */\n get dirname() {\n return typeof this.path === 'string' ? path.dirname(this.path) : undefined\n }\n\n /**\n * Set parent path (`~`).\n * Cannot be set if there's no `path` yet.\n */\n set dirname(dirname) {\n assertPath(this.basename, 'dirname')\n this.path = path.join(dirname || '', this.basename)\n }\n\n /**\n * Access basename (including extname) (`index.min.js`).\n */\n get basename() {\n return typeof this.path === 'string' ? path.basename(this.path) : undefined\n }\n\n /**\n * Set basename (`index.min.js`).\n * Cannot contain path separators.\n * Cannot be nullified either (use `file.path = file.dirname` instead).\n */\n set basename(basename) {\n assertNonEmpty(basename, 'basename')\n assertPart(basename, 'basename')\n this.path = path.join(this.dirname || '', basename)\n }\n\n /**\n * Access extname (including dot) (`.js`).\n */\n get extname() {\n return typeof this.path === 'string' ? path.extname(this.path) : undefined\n }\n\n /**\n * Set extname (including dot) (`.js`).\n * Cannot be set if there's no `path` yet and cannot contain path separators.\n */\n set extname(extname) {\n assertPart(extname, 'extname')\n assertPath(this.dirname, 'extname')\n\n if (extname) {\n if (extname.charCodeAt(0) !== 46 /* `.` */) {\n throw new Error('`extname` must start with `.`')\n }\n\n if (extname.includes('.', 1)) {\n throw new Error('`extname` cannot contain multiple dots')\n }\n }\n\n this.path = path.join(this.dirname, this.stem + (extname || ''))\n }\n\n /**\n * Access stem (w/o extname) (`index.min`).\n */\n get stem() {\n return typeof this.path === 'string'\n ? path.basename(this.path, this.extname)\n : undefined\n }\n\n /**\n * Set stem (w/o extname) (`index.min`).\n * Cannot be nullified, and cannot contain path separators.\n */\n set stem(stem) {\n assertNonEmpty(stem, 'stem')\n assertPart(stem, 'stem')\n this.path = path.join(this.dirname || '', stem + (this.extname || ''))\n }\n\n /**\n * Serialize the file.\n *\n * @param {BufferEncoding} [encoding='utf8'] If `file.value` is a buffer, `encoding` is used to serialize buffers.\n * @returns {string}\n */\n toString(encoding) {\n return (this.value || '').toString(encoding)\n }\n\n /**\n * Create a message and associates it w/ the file.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n * @returns {VFileMessage}\n */\n message(reason, place, origin) {\n const message = new VFileMessage(reason, place, origin)\n\n if (this.path) {\n message.name = this.path + ':' + message.name\n message.file = this.path\n }\n\n message.fatal = false\n\n this.messages.push(message)\n\n return message\n }\n\n /**\n * Info: create a message, associate it with the file, and mark the fatality\n * as `null`.\n * Calls `message()` internally.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n * @returns {VFileMessage}\n */\n info(reason, place, origin) {\n const message = this.message(reason, place, origin)\n\n message.fatal = null\n\n return message\n }\n\n /**\n * Fail: create a message, associate it with the file, mark the fatality as\n * `true`.\n * Note: fatal errors mean a file is no longer processable.\n * Calls `message()` internally.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n * @returns {never}\n */\n fail(reason, place, origin) {\n const message = this.message(reason, place, origin)\n\n message.fatal = true\n\n throw message\n }\n}\n\n/**\n * Assert that `part` is not a path (as in, does not contain `path.sep`).\n *\n * @param {string|undefined} part\n * @param {string} name\n * @returns {void}\n */\nfunction assertPart(part, name) {\n if (part && part.includes(path.sep)) {\n throw new Error(\n '`' + name + '` cannot be a path: did not expect `' + path.sep + '`'\n )\n }\n}\n\n/**\n * Assert that `part` is not empty.\n *\n * @param {string|undefined} part\n * @param {string} name\n * @returns {asserts part is string}\n */\nfunction assertNonEmpty(part, name) {\n if (!part) {\n throw new Error('`' + name + '` cannot be empty')\n }\n}\n\n/**\n * Assert `path` exists.\n *\n * @param {string|undefined} path\n * @param {string} name\n * @returns {asserts path is string}\n */\nfunction assertPath(path, name) {\n if (!path) {\n throw new Error('Setting `' + name + '` requires `path` to be set too')\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","var webpackThen = typeof Symbol === \"function\" ? Symbol(\"webpack then\") : \"__webpack_then__\";\nvar webpackExports = typeof Symbol === \"function\" ? Symbol(\"webpack exports\") : \"__webpack_exports__\";\nvar webpackError = typeof Symbol === \"function\" ? Symbol(\"webpack error\") : \"__webpack_error__\";\nvar completeQueue = (queue) => {\n\tif(queue) {\n\t\tqueue.forEach((fn) => (fn.r--));\n\t\tqueue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));\n\t}\n}\nvar completeFunction = (fn) => (!--fn.r && fn());\nvar queueFunction = (queue, fn) => (queue ? queue.push(fn) : completeFunction(fn));\nvar wrapDeps = (deps) => (deps.map((dep) => {\n\tif(dep !== null && typeof dep === \"object\") {\n\t\tif(dep[webpackThen]) return dep;\n\t\tif(dep.then) {\n\t\t\tvar queue = [];\n\t\t\tdep.then((r) => {\n\t\t\t\tobj[webpackExports] = r;\n\t\t\t\tcompleteQueue(queue);\n\t\t\t\tqueue = 0;\n\t\t\t}, (e) => {\n\t\t\t\tobj[webpackError] = e;\n\t\t\t\tcompleteQueue(queue);\n\t\t\t\tqueue = 0;\n\t\t\t});\n\t\t\tvar obj = {};\n\t\t\tobj[webpackThen] = (fn, reject) => (queueFunction(queue, fn), dep['catch'](reject));\n\t\t\treturn obj;\n\t\t}\n\t}\n\tvar ret = {};\n\tret[webpackThen] = (fn) => (completeFunction(fn));\n\tret[webpackExports] = dep;\n\treturn ret;\n}));\n__webpack_require__.a = (module, body, hasAwait) => {\n\tvar queue = hasAwait && [];\n\tvar exports = module.exports;\n\tvar currentDeps;\n\tvar outerResolve;\n\tvar reject;\n\tvar isEvaluating = true;\n\tvar nested = false;\n\tvar whenAll = (deps, onResolve, onReject) => {\n\t\tif (nested) return;\n\t\tnested = true;\n\t\tonResolve.r += deps.length;\n\t\tdeps.map((dep, i) => (dep[webpackThen](onResolve, onReject)));\n\t\tnested = false;\n\t};\n\tvar promise = new Promise((resolve, rej) => {\n\t\treject = rej;\n\t\touterResolve = () => (resolve(exports), completeQueue(queue), queue = 0);\n\t});\n\tpromise[webpackExports] = exports;\n\tpromise[webpackThen] = (fn, rejectFn) => {\n\t\tif (isEvaluating) { return completeFunction(fn); }\n\t\tif (currentDeps) whenAll(currentDeps, fn, rejectFn);\n\t\tqueueFunction(queue, fn);\n\t\tpromise['catch'](rejectFn);\n\t};\n\tmodule.exports = promise;\n\tbody((deps) => {\n\t\tcurrentDeps = wrapDeps(deps);\n\t\tvar fn;\n\t\tvar getResult = () => (currentDeps.map((d) => {\n\t\t\tif(d[webpackError]) throw d[webpackError];\n\t\t\treturn d[webpackExports];\n\t\t}))\n\t\tvar promise = new Promise((resolve, reject) => {\n\t\t\tfn = () => (resolve(getResult));\n\t\t\tfn.r = 0;\n\t\t\twhenAll(currentDeps, fn, reject);\n\t\t});\n\t\treturn fn.r ? promise : getResult();\n\t}, (err) => (err && reject(promise[webpackError] = err), outerResolve()));\n\tisEvaluating = false;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","","// startup\n// Load entry module and return exports\n// This entry module used 'module' so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(9877);\n",""],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"cli.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAmBA;AACA;AAEA;;AAGA;AAEA;AACA;AACA;AACA;AAHA;;AAMA;AACA;AAMA;;AAEA;AACA;AAOA;AAEA;AAFA;AAIA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AAIA;;AAEA;AAOA;AACA;AAMA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;AClHA;AACA;AACA;AAGA;AAEA;AAAA;AAAA;AAEA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AACA;AAHA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAnBA;;AAsBA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;;;ACnIA;AAEA;AAuCA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AASA;;;;;;;;;;;;;;;;;;;;;;;;ACtDA;AAEA;AACA;AAEA;AACA;AACA;AAUA;AACA;AACA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;;AAEA;AAKA;AAAA;AAAA;AAAA;AACA;AACA;AAEA;;AACA;AACA;AACA;;AACA;AACA;AAEA;AACA;AACA;AACA;AAHA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;;;;;;;;;;;;;;;;;;;;;AC9DA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AADA;AAIA;AACA;AACA;AATA;AAYA;AACA;;AACA;AACA;AAGA;;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AC9CA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AADA;AAJA;AAUA;AACA;;AACA;AACA;AAGA;;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AC3BA;AACA;AACA;AAIA;AACA;AAEA;AAMA;AACA;AAAA;;AAIA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1BA;AAEA;AAEA;AACA;AACA;AACA;;AAGA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;;AAGA;AACA;;AACA;AACA;AAhBA;AAkBA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAHA;AAUA;AAEA;AAAA;AAAA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AALA;AAOA;;;;;;;;;;;;;;;;;;AC9KA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AADA;AAGA;AALA;AAOA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AC/BA;AAGA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AAEA;AAQA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAFA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AAEA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AClEA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAHA;AAcA;AACA;;;;;;;;;;;;;;;;;;;AC3BA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAHA;AAcA;AACA;;;;;;;;;;;;;;;;;;;;AC5BA;AAEA;AACA;AAGA;AAEA;AAKA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAJA;AAcA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAGA;AACA;AACA;AACA;AADA;AAGA;AANA;AARA;AAqBA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAKA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AARA;AAuBA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;AC5GA;AACA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AADA;AAGA;AANA;AASA;AACA;AACA;AACA;AADA;AAGA;AANA;AAdA;AAwBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAPA;AAkBA;;;;;;;;;;;;;;;;;;AC1DA;AAEA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AACA;AACA;AACA;AALA;AAQA;AACA;AACA;AACA;AACA;AALA;AASA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AANA;AAQA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAjCA;AAvBA;AAyEA;;AC1HA;AAEA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAKA;AACA;AAFA;AAMA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AANA;AAQA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;ACpDA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;AAEA;AACA;AAIA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAUA;;;;;;;;;;;;;;;;;;;;;;AC5CA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;;AAGA;;AAEA;AACA;AACA;AAGA;AACA;;AACA;AACA;AAEA;AAGA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AAGA;AACA;;AACA;AACA;AAGA;;AACA;AAIA;AACA;AACA;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AAKA;AACA;AACA;AACA;AACA;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AAIA;;AAGA;AACA;;AAGA;;AAMA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAUA;;AAGA;AACA;;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAUA;AACA;;;AAGA;AACA;;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAUA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AAGA;AACA;AACA;AACA;;AACA;AACA;AACA;AAEA;;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACrVA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAJA;AAMA;AACA;AACA;AACA;AAHA;AAKA;AAjBA;AAmBA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACpCA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAVA;AAeA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;AAGA;AACA;;AAGA;AACA;AACA;AAFA;AAMA;AACA;AAFA;AAMA;AACA;AAKA;AACA;AARA;AAYA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AA1CA;AAlBA;;AAkEA;AAEA;;AAGA;AACA;AAEA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;AAIA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AAIA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxKA;AAGA;AACA;AAEA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC3BA;AAGA;AAEA;AACA;AACA;AAIA;AACA;AACA;;AACA;AACA;AAKA;AACA;;AACA;AACA;;AACA;AACA;AAKA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;ACpCA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;ACjBA;AAEA;AACA;AACA;AACA;;AACA;AACA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAWA;AACA;AACA;;;;;;;;;;;;ACvBA;AAGA;;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAWA;AACA;AACA;;;;;;;;;;;;;;;;ACzBA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC9BA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;AAKA;;AAEA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnCA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrBA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AAEA;AAEA;AAFA;AAFA;AAOA;;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAKA;;AAWA;AACA;AAEA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACrEA;AAIA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AAIA;AACA;AACA;AAEA;;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAHA;AAKA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACjFA;AACA;AAKA;AAmBA;AACA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;;AAEA;AACA;AACA;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AALA;AAOA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;AAJA;AAMA;;;;;;;;;;;;;;;;;;;;;AClHA;AAGA;AAEA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAjBA;AAmBA;AACA;AACA;;AAEA;AAKA;AACA;AAEA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AAAA;AAAA;AAAA;AACA;;AAEA;AAIA;AACA;AAEA;;AACA;AACA;AACA;AACA;;AAEA;AAEA;AAGA;AAAA;;AAGA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAEA;AACA;AAFA;AARA;AAeA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AArBA;AAgCA;;AAEA;AAIA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AAEA;AACA;AACA;AACA;AACA;AAHA;AAKA;;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAAA;AAAA;;AACA;AACA;AACA;;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AARA;AAWA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAKA;;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;AC7MA;AAGA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAEA;;AACA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAJA;AAJA;AAPA;AAFA;AAwBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAaA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;ACxHA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AADA;AAKA;AACA;AACA;AACA;AADA;AADA;;AAMA;AACA;AAEA;AACA;AACA;AACA;AAHA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AAEA;;AACA;AACA;AACA;;AAEA;;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACzDA;AAIA;AACA;AACA;AAEA;AAMA;;AAIA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACxBA;AAGA;AAIA;AACA;AACA;AAGA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAKA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AAIA;AACA;AACA;AACA;;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACzEA;AAEA;AAEA;AAIA;AACA;AAEA;AACA;;AACA;AACA;AAGA;;AAEA;;AACA;AACA;AAGA;;AAEA;AACA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AADA;AADA;;AASA;AACA;AACA;AACA;AACA;AAIA;AAIA;AACA;;AAEA;AACA;AACA;AACA;AADA;AADA;;AASA;AACA;AACA;AACA;AACA;AAGA;AACA;;AAEA;AACA;AACA;AACA;;AAIA;AAKA;AAEA;AACA;AACA;AAFA;AAKA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAWA;AACA;AAnBA;AAsBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAWA;AACA;AAnBA;AAsBA;;AAEA;AACA;AACA;AACA;AAHA;AAKA;;AAEA;AAKA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AATA;AAYA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAlBA;AA8BA;;;;;;;;;;;;;;;;;;AChOA;AAGA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAPA;;AAmBA;AACA;AAEA;AAFA;AAIA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAJA;AAeA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AANA;AAFA;AAWA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AAFA;AAKA;;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAKA;AAAA;AALA;AAUA;AACA;AAAA;AAAA;AAFA;AATA;AAAA;AAwBA;AACA;AACA;;;;;;;;;;;;;;;;;AClDA;AAEA;AACA;AACA;AAIA;AACA;;AAGA;AACA;AAEA;AAGA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAGA;AACA;AAEA;AAEA;AAFA;AAKA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;AC5CA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAFA;AAMA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACfA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACbA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAcA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAFA;AAJA;AAWA;AACA;AAFA;AAjBA;AAjCA;AA2DA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAPA;AAnEA;AAuFA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;AClIA;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AAJA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AALA;AAYA;AACA;AACA;;;;;;;;;;;;;ACvCA;AACA;AAGA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;ACXA;AAEA;AACA;AAIA;AAEA;AACA;AAGA;AAIA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;;;;ACRA;AACA;AAGA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;AAQA;AACA;;AACA;AACA;AACA;;AACA;AACA;AAGA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AAPA;AASA;;AAEA;AAIA;AAEA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;AClEA;AACA;AAIA;AACA;AACA;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxCA;AAEA;AAEA;AACA;AAGA;;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AAKA;;AAEA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACzIA;AAEA;AAGA;AAUA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AAEA;AACA;AAAA;AAAA;AACA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACzDA;AAEA;AACA;AAEA;AAEA;AACA;;AAIA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AALA;AAOA;;;;;;;;;;;;;;;;ACdA;AAEA;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AChBA;AAEA;AAEA;;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC1CA;AACA;AACA;AAQA;AAKA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AARA;AAkBA;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AACA;AAHA;AAPA;AAcA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAJA;AAMA;;;;;;;;;;;;;;;;ACpEA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AAKA;AACA;AACA;AAEA;AAKA;AACA;AACA;AAEA;AAKA;AACA;AACA;;AAEA;AAMA;AACA;AACA;AACA;AACA;;;;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;;AAJA;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA;AACA;AAEA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AAGA;AAIA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AAEA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;;;;;;;;;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACpHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACjGA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC5HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACnHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC1OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtlBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACzJA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5YA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;;;;;AEAA;AACA;AACA;AACA","sources":["webpack://compiler/./src/build-unit.ts","webpack://compiler/./src/cli/cli.ts","webpack://compiler/./src/context.ts","webpack://compiler/./src/course/index.ts","webpack://compiler/./src/course/load-course.ts","webpack://compiler/./src/course/load-unit.ts","webpack://compiler/./src/hast/index.ts","webpack://compiler/./src/hast/inline-files.ts","webpack://compiler/./src/hast/responsive-tables.ts","webpack://compiler/./src/html/index.ts","webpack://compiler/./src/html/pdf.ts","webpack://compiler/./src/html/wrapper/index.ts","webpack://compiler/./src/html/wrapper/main.ts","webpack://compiler/./src/html/wrapper/sidebar.ts","webpack://compiler/./src/html/wrapper/view-options/readability.ts","webpack://compiler/./src/html/wrapper/view-options/theme.ts","webpack://compiler/./src/html/wrapper/view-options/index.ts","webpack://compiler/./src/index.ts","webpack://compiler/./src/knitr/knitr.ts","webpack://compiler/./src/latex/directive-to-svg.ts","webpack://compiler/./src/latex/mathjax-tex.ts","webpack://compiler/./src/latex/tex-to-directive.ts","webpack://compiler/./src/linter/assert-asset-exists.ts","webpack://compiler/./src/linter/assert-columns.ts","webpack://compiler/./src/linter/assert-no-h1.ts","webpack://compiler/./src/linter/assert-no-image-attributes.ts","webpack://compiler/./src/linter/assert-no-tex-tabular.ts","webpack://compiler/./src/linter/assert-task-answer.ts","webpack://compiler/./src/linter/assert-video-attributes.ts","webpack://compiler/./src/linter/assert-weblink-target.ts","webpack://compiler/./src/linter/index.ts","webpack://compiler/./src/linter/lint-latex.ts","webpack://compiler/./src/linter/report.ts","webpack://compiler/./src/mdast/boxouts.ts","webpack://compiler/./src/mdast/code-blocks.ts","webpack://compiler/./src/mdast/columns.ts","webpack://compiler/./src/mdast/combined.ts","webpack://compiler/./src/mdast/embed-asset-url.ts","webpack://compiler/./src/mdast/environment.ts","webpack://compiler/./src/mdast/images.ts","webpack://compiler/./src/mdast/index.ts","webpack://compiler/./src/mdast/move-answers-to-end.ts","webpack://compiler/./src/mdast/pagebreaks.ts","webpack://compiler/./src/mdast/remove-empty-paragraphs.ts","webpack://compiler/./src/mdast/youtube-videos.ts","webpack://compiler/./src/pdf/index.ts","webpack://compiler/./src/pre-parse/allow-no-whitespace-before-heading.ts","webpack://compiler/./src/pre-parse/convert-block-tex.ts","webpack://compiler/./src/pre-parse/convert-inline-tex.ts","webpack://compiler/./src/pre-parse/convert-macro-to-directive.ts","webpack://compiler/./src/pre-parse/index.ts","webpack://compiler/./src/pre-parse/reformat-pandoc-simple-tables.ts","webpack://compiler/./src/utils/cache-to-file.ts","webpack://compiler/./src/utils/check-for-latest-version.ts","webpack://compiler/./src/utils/counter.ts","webpack://compiler/./src/utils/get-asset-hast.ts","webpack://compiler/./src/utils/get-svg-hast.ts","webpack://compiler/./src/utils/icons.ts","webpack://compiler/./src/utils/message.ts","webpack://compiler/./src/utils/timer.ts","webpack://compiler/./src/utils/utils.ts","webpack://compiler/../node_modules/extend/index.js","webpack://compiler/../node_modules/is-buffer/index.js","webpack://compiler/../node_modules/mdurl/encode.js","webpack://compiler/./assets/crest.svg","webpack://compiler/./assets/dag-logo.svg","webpack://compiler/./assets/hamburger-icon.svg","webpack://compiler/./assets/hexagons.svg","webpack://compiler/./assets/link-icon.svg","webpack://compiler/./assets/uofg.svg","webpack://compiler/external module \"@double-great/remark-lint-alt-text\"","webpack://compiler/external module \"@mapbox/remark-lint-link-text\"","webpack://compiler/external module \"base64-arraybuffer\"","webpack://compiler/external module \"chalk\"","webpack://compiler/external module \"dictionary-en-gb\"","webpack://compiler/external module \"figures\"","webpack://compiler/external module \"hash-sum\"","webpack://compiler/external module \"image-size\"","webpack://compiler/external module \"js-yaml\"","webpack://compiler/external module \"lodash/cloneDeep.js\"","webpack://compiler/external module \"lodash/kebabCase.js\"","webpack://compiler/external module \"lodash/startCase.js\"","webpack://compiler/external module \"markdown-table\"","webpack://compiler/external module \"mathjax-full/js/adaptors/liteAdaptor.js\"","webpack://compiler/external module \"mathjax-full/js/core/MathItem.js\"","webpack://compiler/external module \"mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js\"","webpack://compiler/external module \"mathjax-full/js/handlers/html.js\"","webpack://compiler/external module \"mathjax-full/js/handlers/html/HTMLDocument.js\"","webpack://compiler/external module \"mathjax-full/js/input/mathml.js\"","webpack://compiler/external module \"mathjax-full/js/input/tex.js\"","webpack://compiler/external module \"mathjax-full/js/input/tex/AllPackages.js\"","webpack://compiler/external module \"mathjax-full/js/mathjax.js\"","webpack://compiler/external module \"mathjax-full/js/output/svg.js\"","webpack://compiler/external module \"mdast-util-toc\"","webpack://compiler/external module \"mime/lite.js\"","webpack://compiler/external module \"node-fetch\"","webpack://compiler/external module \"puppeteer\"","webpack://compiler/external module \"refractor\"","webpack://compiler/external module \"rehype-document\"","webpack://compiler/external module \"rehype-format\"","webpack://compiler/external module \"rehype-parse\"","webpack://compiler/external module \"rehype-raw\"","webpack://compiler/external module \"rehype-stringify\"","webpack://compiler/external module \"remark-autolink-headings\"","webpack://compiler/external module \"remark-directive\"","webpack://compiler/external module \"remark-footnotes\"","webpack://compiler/external module \"remark-frontmatter\"","webpack://compiler/external module \"remark-gfm\"","webpack://compiler/external module \"remark-parse\"","webpack://compiler/external module \"remark-rehype\"","webpack://compiler/external module \"remark-retext\"","webpack://compiler/external module \"remark-slug\"","webpack://compiler/external module \"retext-english\"","webpack://compiler/external module \"retext-spell\"","webpack://compiler/external module \"speech-rule-engine\"","webpack://compiler/external module \"to-vfile\"","webpack://compiler/external module \"unist-util-visit\"","webpack://compiler/external module \"yargs\"","webpack://compiler/external module \"yup\"","webpack://compiler/external node-commonjs \"child_process\"","webpack://compiler/external node-commonjs \"fs\"","webpack://compiler/external node-commonjs \"os\"","webpack://compiler/external node-commonjs \"path\"","webpack://compiler/external node-commonjs \"url\"","webpack://compiler/../node_modules/mdast-util-definitions/index.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/footer.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/blockquote.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/break.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/code.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/delete.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/emphasis.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/footnote-reference.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/footnote.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/heading.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/html.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/revert.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/image-reference.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/image.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/inline-code.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/link-reference.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/link.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/list-item.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/list.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/paragraph.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/root.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/strong.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/table.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/text.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/thematic-break.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/handlers/index.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/index.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/traverse.js","webpack://compiler/../node_modules/mdast-util-to-hast/lib/wrap.js","webpack://compiler/../node_modules/micromark-util-character/lib/unicode-punctuation-regex.js","webpack://compiler/../node_modules/micromark-util-character/index.js","webpack://compiler/../node_modules/micromark-util-encode/index.js","webpack://compiler/../node_modules/micromark-util-sanitize-uri/index.js","webpack://compiler/../node_modules/bail/index.js","webpack://compiler/../node_modules/unified/node_modules/is-plain-obj/index.js","webpack://compiler/../node_modules/trough/index.js","webpack://compiler/../node_modules/unified/lib/index.js","webpack://compiler/../node_modules/unist-builder/index.js","webpack://compiler/../node_modules/unist-util-generated/index.js","webpack://compiler/../node_modules/unist-util-position/index.js","webpack://compiler/../node_modules/unist-util-stringify-position/index.js","webpack://compiler/../node_modules/vfile-message/index.js","webpack://compiler/external node-commonjs \"process\"","webpack://compiler/../node_modules/vfile/lib/minurl.shared.js","webpack://compiler/../node_modules/vfile/lib/index.js","webpack://compiler/webpack/bootstrap","webpack://compiler/webpack/runtime/async module","webpack://compiler/webpack/runtime/compat get default export","webpack://compiler/webpack/runtime/define property getters","webpack://compiler/webpack/runtime/hasOwnProperty shorthand","webpack://compiler/webpack/before-startup","webpack://compiler/webpack/startup","webpack://compiler/webpack/after-startup"],"sourcesContent":["import { EOL } from 'os';\n\nimport { Parent as HastParent } from 'hast';\nimport { Parent as MdastParent, Root } from 'mdast';\nimport { VFile } from 'vfile';\n\nimport { Context } from './context';\nimport { Unit } from './course/types';\nimport { hastPhase } from './hast';\nimport { htmlPhase } from './html';\nimport { knitr } from './knitr/knitr';\nimport { texToAliasDirective } from './latex/tex-to-directive';\nimport { createReport, reportErrors } from './linter';\nimport { assertNoImageAttributes } from './linter/assert-no-image-attributes';\nimport { mdastPhase } from './mdast';\nimport { combinedMdastPhase } from './mdast/combined';\nimport { convertToPdf } from './pdf';\nimport { preParsePhase } from './pre-parse';\n\nexport type BuiltUnit = {\n unit: Unit;\n md: string;\n files: VFile[];\n html?: {\n mdast: MdastParent;\n hast: HastParent;\n html: string;\n };\n pdf?: {\n mdast: MdastParent;\n hast: HastParent;\n html: string;\n pdf: Buffer;\n };\n};\n\nexport async function buildUnit(unit: Unit, ctx: Context) {\n const unifiedFile = await knitr(unit, ctx);\n\n const mdast = (await inSituTransforms(unifiedFile, ctx)) as Root;\n // console.log(mdast);\n\n await createReport(unifiedFile, mdast, ctx);\n\n const result: BuiltUnit = {\n unit,\n md: combineMdFiles(unifiedFile),\n files: [unifiedFile],\n };\n\n if (!ctx.options.noHtml) {\n result.html = await syntaxTreeTransforms(\n mdast,\n unifiedFile,\n unit,\n ctx\n );\n }\n\n if (!ctx.options.noPdf) {\n const transformed = await syntaxTreeTransforms(\n mdast,\n unifiedFile,\n unit,\n ctx,\n true\n );\n result.pdf = {\n ...transformed,\n pdf: await convertToPdf(transformed.html),\n };\n }\n\n if (!ctx.options.noReport) {\n reportErrors(result.files, ctx);\n }\n\n return result;\n}\n\nasync function inSituTransforms(file: VFile, ctx: Context) {\n assertNoImageAttributes(file);\n preParsePhase(file);\n texToAliasDirective(file, ctx);\n return mdastPhase(file, ctx);\n}\n\nfunction combineMdFiles(file: VFile) {\n return removeDirectoryLines(file.value as string);\n}\n\nfunction removeDirectoryLines(md: string) {\n return md\n .split(EOL)\n .filter((line) => !/^:directory\\[.+\\]$/.test(line))\n .join(EOL);\n}\n\nasync function syntaxTreeTransforms(\n _mdast: Root,\n file: VFile,\n unit: Unit,\n ctx: Context,\n targetPdf?: boolean\n) {\n const mdast = await combinedMdastPhase(_mdast, ctx, file, targetPdf);\n const hast = (await hastPhase(\n mdast,\n ctx,\n file,\n targetPdf\n )) as HastParent;\n const html = await htmlPhase(hast, mdast, file, unit, ctx, targetPdf);\n return { mdast, hast, html };\n}\n","import chalk from 'chalk';\nimport figures from 'figures';\nimport yargs from 'yargs';\n\nimport { Options } from '../context';\nimport { rMarkdown } from '..';\n\nconst { argv } = yargs(process.argv.slice(2))\n .option('week', {\n type: 'number',\n description: 'Build specific week (1-based index)',\n })\n .option('watch', {\n type: 'boolean',\n description: 'Watch coursework for changes',\n })\n .option('noDoc', {\n type: 'boolean',\n description: 'Only compile content HTML',\n })\n .option('noHtml', {\n type: 'boolean',\n description: \"Don't create HTML file\",\n })\n .option('noPdf', {\n type: 'boolean',\n description: \"Don't create PDF file\",\n })\n .option('noSyntaxHighlight', {\n type: 'boolean',\n description: 'No syntax highlighting',\n })\n .option('noReport', {\n type: 'boolean',\n description: 'Bypass linter',\n })\n .option('noEmbedAssets', {\n type: 'boolean',\n description: \"Don't embed assets\",\n })\n .option('noEmbedAssetUrl', {\n type: 'boolean',\n description: \"Don't complete asset Url\",\n })\n .option('noCache', {\n type: 'boolean',\n description: 'No cache',\n })\n .option('noTexSvg', {\n type: 'boolean',\n description: 'No Tex Svg',\n })\n .option('noHexagons', {\n type: 'boolean',\n description: 'No cover hexagons',\n })\n .option('spelling', {\n type: 'boolean',\n description: 'Check spelling',\n })\n .option('pythonBin', {\n type: 'string',\n description: 'Custom path to python binary',\n })\n .option('force', {\n type: 'boolean',\n description: 'Compile even with fatal errors',\n })\n .option('verbose', {\n type: 'boolean',\n description: 'Show error stack',\n })\n .option('envPlatform', {\n type: 'string',\n description: 'Specify which environment platform to display',\n })\n .option('envProgram', {\n type: 'string',\n description: 'Specify which environment program to display',\n })\n .option('output', {\n type: 'string',\n description: 'output to stdout',\n choices: ['md', 'html'],\n });\n\nconst dirPath = String(argv._[0] || '.');\n\nconst options: Options = {\n week: argv.week,\n watch: argv.watch,\n noDoc: argv.noDoc,\n noHtml: argv.noHtml,\n noPdf: argv.noPdf,\n noSyntaxHighlight: argv.noSyntaxHighlight,\n noReport: argv.noReport,\n noEmbedAssets: argv.noEmbedAssets,\n noEmbedAssetUrl: argv.noEmbedAssetUrl,\n noCache: argv.noCache,\n noTexSvg: argv.noTexSvg,\n noHexagons: argv.noHexagons,\n spelling: argv.spelling,\n pythonBin: argv.pythonBin,\n force: argv.force,\n verbose: argv.verbose,\n envPlatform: argv.envPlatform,\n envProgram: argv.envProgram,\n output: argv.output as 'md' | 'html',\n};\n\nasync function run() {\n try {\n const weeks = await rMarkdown(dirPath, options);\n if (weeks.length === 1) {\n const result = weeks[0];\n if (options.output === 'html') {\n console.log(result.html?.html || '');\n }\n if (options.output === 'md') {\n console.log(result.md);\n }\n }\n } catch (err: any) {\n console.log(chalk.red(figures.cross + ' ' + err.message));\n if (options.verbose) {\n console.error(err);\n }\n process.exit(1);\n }\n}\n\nrun();\n","import { collectCoursework } from './course';\nimport { Course } from './course/types';\nimport { getBuildDir, getCacheDir } from './utils/utils';\n\nexport type Options = {\n noDoc?: boolean;\n noHtml?: boolean;\n noPdf?: boolean;\n noSyntaxHighlight?: boolean;\n noReport?: boolean;\n reportOnlyErrors?: boolean;\n noEmbedAssets?: boolean;\n noEmbedAssetUrl?: boolean;\n noCache?: boolean;\n noTexSvg?: boolean;\n noHexagons?: boolean;\n week?: number;\n watch?: boolean;\n shouldFail?: boolean;\n spelling?: boolean;\n force?: boolean;\n noWrite?: boolean;\n format?: boolean;\n pythonBin?: string;\n verbose?: boolean;\n envPlatform?: string;\n envProgram?: string;\n output?: 'md' | 'html';\n};\n\nexport type Context = {\n dirPath: string;\n buildDir: string;\n cacheDir: string;\n course: Course;\n options: Options;\n mmlStore?: string[];\n refStore: Record;\n figureCounter: number;\n};\n\nexport async function createContext(\n dirPath: string,\n options: Options = {}\n): Promise {\n return {\n course: await collectCoursework(dirPath),\n dirPath,\n buildDir: getBuildDir(dirPath),\n cacheDir: getCacheDir(dirPath),\n options,\n refStore: {},\n figureCounter: 0,\n };\n}\n","import path from 'path';\n\nimport kebabCase from 'lodash/kebabCase.js';\nimport { toVFile } from 'to-vfile';\n\nimport { checkLocalFileExists } from '../utils/utils';\nimport { loadCourseYaml } from './load-course';\nimport { loadUnitYaml } from './load-unit';\nimport {\n Course,\n CourseYaml,\n Unit,\n UnitTitles,\n UnitTitlesInput,\n} from './types';\nimport { FileRef } from './types';\n\nexport async function collectCoursework(dirPath: string): Promise {\n const course = await loadCourseYaml(dirPath);\n const coursePath = path.join(process.cwd(), dirPath);\n const units = await Promise.all(\n course.units.map((unit) => collectUnit(unit, course, dirPath))\n );\n return { ...course, coursePath, units };\n}\n\nasync function collectUnit(\n unit: FileRef,\n course: CourseYaml,\n dirPath: string\n): Promise {\n const { content, ...yaml } = await loadUnitYaml(dirPath, unit.src);\n const unitPath = path.join(process.cwd(), dirPath, unit.src);\n const files = await Promise.all(\n content.map(async (c) => {\n const filePath = path.resolve(dirPath, unit.src, '..', c.src);\n if (!(await checkLocalFileExists(filePath))) {\n throw new Error(`No Rmd file exists at ${filePath}`);\n }\n return toVFile.read(filePath, 'utf-8');\n })\n );\n const titles = getUnitTitles({\n courseTitle: course.title,\n unitName: yaml.name,\n unitTitle: yaml.title,\n });\n return { ...yaml, unitPath, parts: content, files, titles };\n}\n\nexport function getUnitTitles({\n courseTitle,\n unitName,\n unitTitle,\n}: UnitTitlesInput): UnitTitles {\n return {\n courseTitle,\n unitTitle: `${unitName}: ${unitTitle}`,\n unitName,\n docTitle: `${unitTitle} | ${courseTitle}`,\n fileName: kebabCase(unitName),\n };\n}\n","import path from 'path';\n\nimport yaml from 'js-yaml';\nimport * as yup from 'yup';\n\nimport { checkLocalFileExists, readFile } from '../utils/utils';\nimport { CourseYaml } from './types';\n\n// export const validCatalogValues = [\n// 'STATS5077',\n// 'STATS5078',\n// 'STATS5075',\n// 'STATS5084',\n// 'STATS5074',\n// 'STATS5081',\n// 'STATS5080',\n// 'STATS5073',\n// 'STATS5076',\n// 'STATS5079',\n// 'STATS5082',\n// 'STATS5094',\n// 'STATS5083',\n// ];\n\nconst courseSchema = yup.object().shape({\n title: yup.string().required(),\n units: yup.array().of(\n yup.object().shape({\n src: yup.string().required(),\n })\n ),\n catalog: yup.string(),\n authors: yup.string().required(),\n academic_year: yup.string().required(),\n});\n\nexport async function loadCourseYaml(dirPath: string) {\n const courseYamlPath = path.join(dirPath, 'course.yaml');\n if (!(await checkLocalFileExists(courseYamlPath))) {\n throw Error(\n `No course.yaml file exists in ${path.join(process.cwd(), dirPath)}`\n );\n }\n const fileContents = await readFile(courseYamlPath);\n const course = yaml.load(fileContents);\n return courseSchema.validateSync(course) as CourseYaml;\n}\n","import path from 'path';\n\nimport yaml from 'js-yaml';\nimport * as yup from 'yup';\n\nimport { checkLocalFileExists, readFile } from '../utils/utils';\nimport { UnitYaml } from './types';\n\nconst unitSchema = yup.object().shape({\n name: yup.string().required(),\n title: yup.string().required(),\n content: yup.array().of(\n yup.object().shape({\n src: yup.string().required(),\n })\n ),\n});\n\nexport async function loadUnitYaml(dirPath: string, src: string) {\n const contentsPath = path.join(dirPath, src);\n if (!(await checkLocalFileExists(contentsPath))) {\n throw Error(\n `No yaml file exists at ${path.join(process.cwd(), contentsPath)}`\n );\n }\n const fileContents = await readFile(contentsPath);\n const unit = yaml.load(fileContents);\n return unitSchema.validateSync(unit) as UnitYaml;\n}\n","import { Root } from 'mdast';\nimport rehypeRaw from 'rehype-raw';\nimport remark2rehype from 'remark-rehype';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { inlineRelativeAssets } from './inline-files';\nimport { responsiveTables } from './responsive-tables';\n\nexport async function hastPhase(\n mdast: Root,\n ctx: Context,\n file: VFile,\n targetPdf?: boolean\n) {\n const processor = unified()\n .use(remark2rehype, { allowDangerousHtml: true })\n .use(rehypeRaw)\n .use(responsiveTables);\n\n if (!ctx.options.noEmbedAssets) {\n processor.use(inlineRelativeAssets, ctx);\n }\n\n return processor.run(mdast, file);\n}\n","import path from 'path';\n\nimport { encode as base46Encode } from 'base64-arraybuffer';\nimport { Element, Properties } from 'hast';\nimport sizeOf from 'image-size';\nimport mimes from 'mime/lite.js';\nimport fetch from 'node-fetch';\nimport { toVFile } from 'to-vfile';\n// import { optimize } from 'svgo';\nimport { Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\n// import { pdfToSvg } from '../pdf/pdf-to-svg';\nimport { cacheToFile } from '../utils/cache-to-file';\nimport { getSvgHast } from '../utils/get-svg-hast';\nimport { failMessage } from '../utils/message';\nimport { readFile, rehypeParser } from '../utils/utils';\n\nexport function inlineRelativeAssets(ctx: Context) {\n return async (tree: Element, file: VFile) => {\n const transformations: Promise[] = [];\n visit(tree, 'element', (node) => {\n if (node.tagName === 'img') {\n transformations.push(embed(node, file, ctx));\n }\n });\n await Promise.all(transformations);\n };\n}\n\nasync function embed(node: Element, file: VFile, ctx: Context) {\n const src = getImageSrc(node);\n const parsed = path.parse(src);\n try {\n switch (parsed.ext) {\n case '.png':\n case '.jpg':\n case '.jpeg':\n case '.gif':\n return await embedImage(node, ctx, file);\n case '.svg':\n return await embedSvg(node, ctx);\n case '.pdf':\n // return await embedPdfSvg(node);\n throw new Error(\n `Unhandled file extension: .pdf (convert to .svg)`\n );\n case '.html':\n return await embedHtml(node);\n default:\n throw new Error(`Unhandled file extension: ${parsed.ext}`);\n }\n } catch (_err) {\n console.log(_err);\n const err = _err as Error;\n failMessage(file, err?.message || '', node.position);\n }\n}\n\nasync function embedImage(node: Element, ctx: Context, file: VFile) {\n const src = getImageSrc(node);\n const mime = mimes.getType(path.extname(src));\n try {\n const image = await getImage(src, ctx);\n const { width } = sizeOf(Buffer.from(image, 'base64'));\n node.properties = {\n ...node.properties,\n src: `data:${mime};base64,${image}`,\n style: [`max-width: ${width}px`],\n };\n } catch (err) {\n console.log(err);\n failMessage(file, `Image not found: ${src}`);\n }\n}\n\nasync function embedSvg(imgNode: Element, ctx: Context) {\n const src = getImageSrc(imgNode);\n const contents = await readFile(src);\n const idx = contents.indexOf(' String(x)).filter((s) => s !== removeClass);\n }\n return [];\n}\n\nfunction getImageSrc(node: Element) {\n const properties = (node.properties || {}) as { src: string };\n if (!properties.src) {\n throw new Error('Image has no src');\n }\n return properties.src;\n}\n\nasync function getImage(src: string, ctx: Context) {\n if (src.startsWith('http')) {\n return cacheToFile({\n ctx,\n prefix: 'youtube',\n key: src,\n execFn: getImageDataFromWeb,\n });\n }\n return readFile(src, 'base64');\n}\n\nasync function getImageDataFromWeb(src: string) {\n const response = await fetch(src);\n const buffer = await response.arrayBuffer();\n return base46Encode(buffer);\n}\n\n// async function embedPdfSvg(imgNode: Element) {\n// const src = getImageSrc(imgNode);\n// const svgNode = (await pdfToSvg(src)) as Element;\n// console.log('hey!');\n// console.log(svgNode);\n\n// const properties = {\n// ...imgNode.properties,\n// ...svgNode.properties,\n// } as Properties;\n\n// delete properties.src;\n\n// Object.assign(imgNode, svgNode, { properties });\n// }\n\nasync function embedHtml(imgNode: Element) {\n const src = getImageSrc(imgNode);\n const value = await readFile(src);\n const vfile = toVFile({ value });\n const parsed = rehypeParser().parse(vfile) as Parent;\n\n Object.assign(imgNode, {\n tagName: 'div',\n properties: {\n className: 'interactive-element',\n },\n children: parsed.children,\n });\n}\n","import { Element } from 'hast';\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\ntype ParentProps = {\n className: string[];\n};\n\nexport function responsiveTables() {\n return async (tree: Element, file: VFile) => {\n visit(tree, 'element', (node, idx, _parent) => {\n if (node.tagName !== 'table') {\n return;\n }\n\n const parent = _parent as Element;\n const properties = (parent?.properties || {}) as ParentProps;\n const className = properties.className || [];\n\n if (!className.includes('table-wrapper')) {\n Object.assign(node, {\n tagName: 'div',\n properties: {\n className: 'table-wrapper',\n },\n children: [cloneDeep(node)],\n });\n }\n });\n };\n}\n","import path from 'path';\n\nimport { Parent as HastParent, Root } from 'hast';\nimport startCase from 'lodash/startCase.js';\nimport { Parent as MdastParent } from 'mdast';\nimport doc, { Options } from 'rehype-document';\nimport format from 'rehype-format';\nimport stringify from 'rehype-stringify';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { Unit } from '../course/types';\nimport { getTemplateDir, readFile } from '../utils/utils';\nimport { pdfWrapper } from './pdf';\nimport { htmlWrapper } from './wrapper';\n\nexport async function htmlPhase(\n hast: HastParent,\n mdast: MdastParent,\n file: VFile,\n unit: Unit,\n ctx: Context,\n targetPdf?: boolean\n) {\n const processor = unified().use(stringify, { allowDangerousHtml: true });\n\n if (ctx.options.format) {\n // hangs in some scenarios so off by default, useful in tests\n processor.use(format);\n }\n\n if (!ctx.options.noDoc) {\n const cssPath = path.join(getTemplateDir(), 'template.css');\n const docOptions: Options = {\n title: unit.titles.docTitle,\n style: `\\n${await readFile(cssPath)}\\n`,\n };\n\n if (!targetPdf) {\n const jsPath = path.join(getTemplateDir(), 'template.js2');\n docOptions.script = `\\n${await readFile(jsPath)}\\n`;\n processor.use(htmlWrapper, unit, mdast, ctx);\n } else {\n processor.use(pdfWrapper, unit, ctx);\n }\n\n processor.use(doc, docOptions);\n }\n\n const transformed = await processor.run(hast as Root, file);\n\n const result = processor.stringify(transformed, file);\n\n return postTransforms(result, ctx);\n}\n\nfunction postTransforms(html: string, ctx: Context) {\n let result = '';\n result = referenceTransform(html, ctx.refStore);\n return result;\n}\n\nfunction referenceTransform(html: string, refStore: Context['refStore']) {\n return html.replace(/ref:\\/\\/(\\w+)/gms, (...match) => {\n const key = match[1];\n const link = refStore[key];\n const name = startCase(link);\n return `${name}`;\n });\n}\n","import { Node, Parent } from 'unist';\n\nimport { Context } from '../context';\nimport { Unit } from '../course/types';\n// import { UnitTitles } from '../course/types';\nimport { createDefs } from '../utils/icons';\nimport { createMain } from './wrapper/main';\n\nexport function pdfWrapper(unit: Unit, ctx: Context) {\n return async (tree: Node) => {\n const main = await createMain(\n unit.titles,\n ctx,\n (tree as Parent).children\n );\n const iconDefs = createDefs();\n return {\n type: 'root',\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'root',\n className: ['hide-sidebar', 'font-default', 'pdf'],\n },\n children: [iconDefs, main],\n },\n ],\n };\n };\n}\n","import { Parent } from 'mdast';\n\nimport { Context } from '../../context';\nimport { Unit } from '../../course/types';\nimport { createDefs, createSvg } from '../../utils/icons';\nimport { createMain } from './main';\nimport { createSidebar } from './sidebar';\n\nexport function htmlWrapper(unit: Unit, mdast: Parent, ctx: Context) {\n return async (tree: Parent) => {\n const hamburgerIcon = createSvg('hamburger-icon');\n const sidebar = await createSidebar(mdast);\n const main = await createMain(unit.titles, ctx, tree.children);\n const iconDefs = createDefs();\n return {\n type: 'root',\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'root',\n className: ['hide-sidebar'],\n },\n children: [iconDefs, main, hamburgerIcon, sidebar],\n },\n ],\n };\n };\n}\n","import { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport dagLogoSvg from '../../../assets/dag-logo.svg';\nimport coverSvg from '../../../assets/hexagons.svg';\nimport { Context } from '../../context';\nimport { Course, UnitTitles } from '../../course/types';\nimport { getAssetHast } from '../../utils/get-asset-hast';\n\nexport async function createMain(\n titles: UnitTitles,\n ctx: Context,\n content: Node[]\n) {\n const children = [];\n\n if (ctx.options.noHexagons) {\n children.push(createH1(titles));\n } else {\n children.push(createCover(titles, ctx.course));\n }\n\n children.push(...content);\n\n return {\n type: 'element',\n tagName: 'main',\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'wrapper',\n },\n children,\n },\n ],\n };\n}\n\nfunction createCover(titles: UnitTitles, course: Course) {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'cover',\n },\n children: [\n createH1(titles),\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'logos',\n },\n children: [\n createCoverHexagons(course.catalog || ''),\n getAssetHast(dagLogoSvg),\n ],\n },\n ],\n };\n}\n\nfunction createH1(titles: UnitTitles) {\n return {\n type: 'element',\n tagName: 'h1',\n children: [\n {\n type: 'text',\n value: titles.courseTitle,\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'unit',\n },\n children: [\n {\n type: 'text',\n value: titles.unitTitle,\n },\n ],\n },\n ],\n };\n}\n\nfunction createCoverHexagons(catalog: string) {\n const hexagons = getAssetHast(coverSvg);\n\n if (catalog !== '') {\n visit(hexagons, 'element', (node) => {\n if (node.tagName === 'g') {\n const properties = node.properties || {};\n const [className] = (properties.className || []) as string[];\n if (catalog === className) {\n properties.className = ['active'];\n } else {\n properties.className = [];\n }\n node.properties = properties;\n }\n });\n }\n\n return hexagons;\n}\n","import { Parent, Root } from 'mdast';\nimport { toHast } from 'mdast-util-to-hast';\nimport { toc as getToc } from 'mdast-util-toc';\n\nimport crestSvg from '../../../assets/crest.svg';\nimport uOfGSvg from '../../../assets/uofg.svg';\nimport { getAssetHast } from '../../utils/get-asset-hast';\nimport { createSvg } from '../../utils/icons';\nimport {\n createViewOptions,\n createViewOptionsButton,\n} from './view-options';\n\nexport async function createSidebar(mdast: Parent) {\n const logo = await createLogo();\n const toc = getToc(mdast as Root, { maxDepth: 3 }).map;\n const tocChildren = toc === null ? [] : [toHast(toc)];\n\n return {\n type: 'element',\n tagName: 'aside',\n children: [\n logo,\n createViewOptionsButton(),\n {\n type: 'element',\n tagName: 'nav',\n properties: {\n id: 'toc',\n },\n children: tocChildren,\n },\n {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'view-options',\n },\n children: createViewOptions(),\n },\n ],\n };\n}\n\nasync function createLogo() {\n const crest = getAssetHast(crestSvg);\n const uofg = getAssetHast(uOfGSvg);\n const hamburgerIcon = createSvg('hamburger-icon');\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'logo',\n },\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'logo-wrapper',\n },\n children: [crest, uofg],\n },\n hamburgerIcon,\n ],\n };\n}\n","import { Item } from './shared';\n\ntype ReadabilityItem = Item & {\n min: number;\n max: number;\n increment: number;\n};\n\nconst options: ReadabilityItem[] = [\n {\n value: 'fontSize',\n label: 'Font-size',\n min: 0.6,\n max: 2,\n increment: 0.1,\n },\n {\n value: 'lineSpacing',\n label: 'Line spacing',\n min: 0.6,\n max: 2,\n increment: 0.1,\n },\n {\n value: 'letterSpacing',\n label: 'Letter spacing',\n min: -0.1,\n max: 0.2,\n increment: 0.05,\n },\n {\n value: 'lineWidth',\n label: 'Line width',\n min: 0.6,\n max: 1.2,\n increment: 0.05,\n },\n];\n\nexport function createReadabilityList() {\n return {\n type: 'element',\n tagName: 'ul',\n properties: {\n id: 'readability',\n },\n children: options.map(createOption),\n };\n}\n\nfunction createOption(item: ReadabilityItem) {\n return {\n type: 'element',\n tagName: 'li',\n properties: {\n className: [item.value],\n 'data-min': item.min,\n 'data-max': item.max,\n 'data-increment': item.increment,\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['label'],\n },\n children: [\n {\n type: 'text',\n value: item.label,\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['actions'],\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['btn', 'minus'],\n },\n children: [\n {\n type: 'text',\n value: '−',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['btn', 'plus'],\n },\n children: [\n {\n type: 'text',\n value: '+',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['btn', 'reset'],\n },\n children: [\n {\n type: 'text',\n value: 'Reset',\n },\n ],\n },\n ],\n },\n ],\n };\n}\n","import { Item } from './shared';\n\nconst themes: Item[] = [\n {\n value: 'light',\n label: 'Light',\n },\n {\n value: 'dark',\n label: 'Dark',\n },\n {\n value: 'yellow-on-black',\n label: 'Yellow on Black',\n },\n {\n value: 'black-on-yellow',\n label: 'Black on Yellow',\n },\n {\n value: 'black-on-red',\n label: 'Black on Red',\n },\n {\n value: 'black-on-blue',\n label: 'Black on Blue',\n },\n];\n\nexport function createThemeList() {\n return {\n type: 'element',\n tagName: 'ul',\n properties: {\n id: 'themes',\n },\n children: themes.map(createThemeButton),\n };\n}\n\nfunction createThemeButton(theme: Item) {\n return {\n type: 'element',\n tagName: 'li',\n properties: {\n className: [theme.value],\n },\n children: [\n {\n type: 'text',\n value: theme.label,\n },\n ],\n };\n}\n","import { Node } from 'unist';\n\n// import { createFontList } from './font';\nimport { createReadabilityList } from './readability';\nimport { createThemeList } from './theme';\n\nexport function createViewOptionsButton() {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'view-options-toggle',\n },\n children: [\n {\n type: 'text',\n value: 'View options',\n },\n ],\n };\n}\n\nexport function createViewOptions(): Node[] {\n return [\n createTitle('Theme'),\n createThemeList(),\n // createTitle('Font'),\n // createFontList(),\n createTitle('Readability'),\n createReadabilityList(),\n ];\n}\n\nfunction createTitle(value: string) {\n return {\n type: 'element',\n tagName: 'h3',\n children: [\n {\n type: 'text',\n value,\n },\n ],\n };\n}\n","import path from 'path';\n\nimport chalk from 'chalk';\n\nimport { BuiltUnit, buildUnit } from './build-unit';\nimport { Context, Options, createContext } from './context';\nimport { checkForLatestVersion } from './utils/check-for-latest-version';\nimport { Timer, createTimer } from './utils/timer';\nimport { mkdir, writeFile } from './utils/utils';\n\nexport async function rMarkdown(dirPath: string, options: Options = {}) {\n if (!options.output) {\n await checkForLatestVersion();\n }\n\n const timer = createTimer();\n const ctx = await createContext(dirPath, options);\n\n const result = [];\n\n if (ctx.options.week) {\n // write single week\n const idx = ctx.options.week - 1;\n const input = ctx.course.units[idx];\n\n if (input === undefined) {\n const courseYaml = path.join(ctx.dirPath, 'course.yaml');\n throw new Error(\n `Week ${ctx.options.week} not found in ${courseYaml}`\n );\n }\n\n const built = await buildUnit(input, ctx);\n await writeUnit(built, ctx, timer);\n result.push(built);\n } else {\n // write full course\n for (const input of ctx.course.units) {\n const built = await buildUnit(input, ctx);\n await writeUnit(built, ctx, timer);\n result.push(built);\n }\n }\n\n return result;\n}\n\nasync function writeUnit(built: BuiltUnit, ctx: Context, timer: Timer) {\n if (ctx.options.noWrite) {\n return;\n }\n\n await mkdir(ctx.buildDir);\n const filePath = path.join(ctx.buildDir, built.unit.titles.fileName);\n\n if (built.html) {\n await writeFile(filePath + '.html', built.html.html);\n\n if (!ctx.options.output) {\n const status = chalk.green.bold(`Complete in ${timer.seconds()}s`);\n console.log(`✨ ${status} ${filePath}.html`);\n }\n }\n\n if (built.pdf) {\n await writeFile(filePath + '.pdf', built.pdf.pdf);\n\n // debug\n // await writeFile(filePath + '.pdf.html', built.pdf.html);\n\n if (!ctx.options.output) {\n const status = chalk.green.bold(`Complete in ${timer.seconds()}s`);\n console.log(`✨ ${status} ${filePath}.pdf`);\n }\n }\n}\n","import { exec } from 'child_process';\nimport { EOL } from 'os';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nimport chalk from 'chalk';\nimport hashSum from 'hash-sum';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { Unit } from '../course/types';\nimport { infoMessage, warnMessage } from '../utils/message';\nimport { mkdir, rmFile, writeFile } from '../utils/utils';\n\n// bypass knitr for debugging\n// export async function knitr(unit: Unit, ctx: Context) {\n// const file = new VFile();\n\n// file.value = unit.files.reduce((acc, o) => {\n// return acc + EOL + EOL + o.value;\n// }, '');\n\n// return file;\n// }\n\nexport async function knitr(unit: Unit, ctx: Context) {\n const parentFile = await createParentFile(unit, ctx);\n // console.log(parentFile.value);\n\n const result = await execKnitr(parentFile, ctx, unit.unitPath);\n // console.log(result);\n parentFile.value = result;\n return parentFile;\n}\n\n// creating a temporary file which includes all child files allows\n// R/Python state to be shared across multiple .Rmd files\n// https://yihui.org/knitr/options/#child-documents\nasync function createParentFile(unit: Unit, ctx: Context) {\n const file = new VFile();\n\n let value = '';\n\n // pass path to custom python binary to reticulate\n // https://rstudio.github.io/reticulate/articles/r_markdown.html\n if (ctx.options.pythonBin) {\n const reticulate = `reticulate::use_python(\"${ctx.options.pythonBin}\")`;\n value += `\\`\\`\\`{r, echo=FALSE}${EOL}${reticulate}${EOL}\\`\\`\\`${EOL}${EOL}`;\n }\n\n value += unit.files.reduce((acc, o) => {\n const [filePath] = o.history;\n\n // directory directive is used to ensure external assets\n // can have relative paths to the .Rmd document.\n // used in embed-asset-url mdast transform\n const fileDir = path.parse(filePath).dir;\n const directive = `:directory[${fileDir}]`;\n\n // child document\n // convert all file paths to forward slash (windows anaconda/knitr bug)\n const formattedPath = path\n .relative(ctx.cacheDir, filePath)\n .replace(/\\\\/g, '/');\n\n const childCodeBlock = `\\`\\`\\`{r, child='${formattedPath}'}${EOL}\\`\\`\\``;\n return acc + directive + EOL + EOL + childCodeBlock + EOL + EOL;\n }, '');\n\n // console.log(value);\n\n file.value = value;\n return file;\n}\n\nasync function execKnitr(file: VFile, ctx: Context, unitPath: string) {\n const md = file.value as string;\n const uniqueId = getUniqueId(md);\n const cachedFile = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n const cacheDir = path.join(ctx.cacheDir, uniqueId);\n await mkdir(cacheDir);\n await writeFile(cachedFile, md);\n\n return new Promise((resolve, reject) => {\n const cmd = createKnitrCommand(ctx, uniqueId, unitPath);\n\n exec(cmd, async (err, response, stdErr) => {\n if (stdErr) {\n console.log(chalk.grey(`[knitr] ${stdErr.trim()}`));\n }\n if (err) {\n console.error('ERROR', err);\n reject(err);\n } else {\n reportErrors(response, file, ctx);\n resolve(formatResponse(response));\n }\n await rmFile(cachedFile);\n });\n });\n}\n\nfunction getUniqueId(md: string) {\n const hash = hashSum(md);\n const ts = new Date().getTime().toString();\n return `knitr-${hash}-${ts}`;\n}\n\nfunction createKnitrCommand(\n ctx: Context,\n uniqueId: string,\n unitPath: string\n) {\n const rFileDir = getKnitrFileDir();\n const rFile = path.join(rFileDir, 'knitr.R');\n const baseDir = path.parse(unitPath).dir;\n const cachedFile = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n const cacheDir = path.join(ctx.cacheDir, uniqueId);\n\n // spawn args\n // return [rFile, cachedFile, baseDir, cacheDir];\n\n return `Rscript \"${rFile}\" \"${cachedFile}\" \"${baseDir}\" \"${cacheDir}\"`;\n}\n\nfunction getKnitrFileDir() {\n // temporary hack until this PR is merged\n // https://github.com/webpack/webpack/pull/15246\n if (process.env.NODE_ENV === 'production') {\n return __dirname;\n }\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\nfunction reportErrors(response: string, file: VFile, ctx: Context) {\n const lines = response\n .split(EOL)\n .filter((s) => !s.startsWith(':directory'));\n\n const trimmed = lines.join(EOL).trim();\n\n // Warning at the start of a document\n if (trimmed.startsWith('WARNING -')) {\n const match = trimmed.match(/^WARNING - (.+?)[\\r\\n]{2,}/ms);\n\n // Check the original file doesn't start with WARNING\n const original = String(ctx.course.units[0].files[0].value)\n .split(EOL)\n .filter((s) => !s.startsWith(':directory'))\n .join(EOL)\n .trim();\n\n if (match !== null && !original.startsWith('WARNING -')) {\n warnMessage(file, match[1], {\n start: {\n line: 1,\n column: 0,\n },\n end: {\n line: 1,\n column: lines[0].length,\n },\n });\n }\n\n // Python binary path\n } else if (trimmed.startsWith('$python [1]')) {\n const match = trimmed.match(/^\\$python\\s\\[1\\]\\s(\"\\S+\")/);\n if (match !== null) {\n infoMessage(file, match[1], {\n start: {\n line: 1,\n column: 0,\n },\n end: {\n line: 1,\n column: lines[0].length,\n },\n });\n }\n }\n\n // Errors throughout document\n lines.forEach((line, idx) => {\n const trimmedLine = line.trim();\n if (trimmedLine.startsWith('## Error')) {\n warnMessage(file, trimmedLine.replace('## ', ''), {\n start: {\n line: idx + 1,\n column: 0,\n },\n end: {\n line: idx + 1,\n column: line.length,\n },\n });\n }\n });\n}\n\nasync function formatResponse(response: string) {\n let md = response;\n md = removeCustomPythonBinNotice(md);\n md = removePythonWarningMessage(md);\n md = addCodeBlockClasses(md);\n md = addErrorCodeBlock(md);\n md = removeHashSigns(md);\n md = removeEmptyLog(md);\n md = addNewLineAfterKable(md);\n return md;\n}\n\nfunction removeCustomPythonBinNotice(md: string) {\n return md.replace(/^\\$python\\s\\[1\\]\\s\"\\S+\"/, '');\n}\n\nfunction removePythonWarningMessage(md: string) {\n return md.replace(/^WARNING - .+?[\\r\\n]+/m, '');\n}\n\nfunction addCodeBlockClasses(md: string) {\n return md\n .split('\\n')\n .reduce((acc: string[], line) => {\n if (line.startsWith('```{.knitr-output}')) {\n const lang = findLanguageForOutput(acc);\n acc.push(`\\`\\`\\`{.${lang}-output}`);\n } else {\n acc.push(line);\n }\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction removeHashSigns(md: string) {\n let insideCodeResponse = false;\n let openingLine = '';\n return md\n .split('\\n')\n .reduce((acc: string[], line) => {\n if (line.startsWith('```')) {\n insideCodeResponse = !insideCodeResponse;\n openingLine = insideCodeResponse ? line : '';\n }\n if (insideCodeResponse && openingLine.endsWith('-output}')) {\n acc.push(line.replace(/^##\\s+/, ''));\n } else {\n acc.push(line);\n }\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction removeEmptyLog(md: string) {\n return md.replace(/\\[1\\]\\s\"\"$/gm, '').trim();\n}\n\nfunction addErrorCodeBlock(md: string) {\n return md\n .split('\\n')\n .reduce((acc: string[], line, idx) => {\n if (line.startsWith('## Error') && acc[idx - 1].startsWith('```')) {\n const lang = findLanguageForOutput(acc.slice(0, -1));\n acc[acc.length - 1] = `\\`\\`\\`{.${lang}-error-output}`;\n }\n acc.push(line);\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction addNewLineAfterKable(md: string) {\n return md\n .split('\\n')\n .reduce((acc: string[], line, idx) => {\n if (acc[idx - 1]?.startsWith('|') && !line.startsWith('|')) {\n acc.push('', line);\n } else {\n acc.push(line);\n }\n return acc;\n }, [])\n .join('\\n');\n}\n\nfunction findLanguageForOutput(prev: string[]) {\n const pattern = /```(\\w*)/;\n const reversed = prev.slice().reverse();\n const prevClosingIdx = reversed.findIndex((s) => s.startsWith('```'));\n const prevOpening = reversed\n .slice(prevClosingIdx + 1)\n .find((s) => pattern.test(s)) as string;\n\n if (!prevOpening) {\n return 'r';\n }\n\n const match = prevOpening.match(pattern) as RegExpMatchArray;\n return match[1];\n}\n\n// experimental streaming output\n// async function spawnKnitr(file: VFile, ctx: Context, unitPath: string) {\n// const md = file.value as string;\n// const uniqueId = getUniqueId(md);\n// const cachedFile = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n// const cacheDir = path.join(ctx.cacheDir, uniqueId);\n// await mkdir(cacheDir);\n// await writeFile(cachedFile, md);\n\n// return new Promise((resolve, reject) => {\n// const args = createKnitrCommand(ctx, uniqueId, unitPath);\n// const knitr = spawn('Rscript', args);\n// const result: string[] = [];\n\n// knitr.stdout.on('data', (data) => {\n// const str = data.toString();\n// console.log(str);\n// result.push(str);\n// });\n\n// knitr.stdout.on('end', () => {\n// console.log('STDOUT END');\n// const end = result.join('');\n// console.log('END', end);\n// reportErrors(end, file);\n// resolve(formatResponse(end));\n// });\n\n// knitr.stdout.on('error', (err) => {\n// console.log('STDOUT ERROR', err, err.toString());\n// reject();\n// });\n\n// knitr.stderr.on('data', (data) => {\n// const str = data.toString();\n// console.log('STDERR ERROR', str);\n// });\n// }).then(async (result) => {\n// await rmFile(cachedFile);\n// return result;\n// });\n// }\n","import { Element, Literal } from 'hast';\nimport { Parent, Root } from 'mdast';\nimport { TextDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\nimport { rehypeParser } from '../utils/utils';\nimport { mmlToSpeech, mmlToSvg } from './mathjax-tex';\n\nexport function aliasDirectiveToSvg(ctx: Context) {\n return (tree: Root) => {\n visit(tree, 'textDirective', (node) => {\n if (!ctx.mmlStore || ctx.options.noTexSvg) {\n return;\n }\n switch (node.name) {\n case 'inlineMath':\n case 'blockMath': {\n const idx = getTexIdx(node as TextDirective);\n const mml = ctx.mmlStore[idx];\n const svg = renderSvg(mml);\n const properties = {\n ...svg.properties,\n className:\n node.name === 'inlineMath' ? 'inline-math' : 'block-math',\n id: getRefId(mml),\n };\n node.data = {\n hName: svg.tagName,\n hProperties: properties,\n hChildren: svg.children,\n };\n }\n }\n });\n };\n}\n\nfunction getTexIdx(node: Parent) {\n const firstChild = node.children[0] as Literal;\n return Number(firstChild.value || 0);\n}\n\nfunction getRefId(mml: string) {\n const match = mml.match(/;\n\n const newProperties: Record = {\n width: properties.width,\n height: properties.height,\n viewBox: properties.viewBox,\n role: 'img',\n };\n\n if (label !== '') {\n const uniqueId = `math-${Math.random().toString(16).slice(2)}`;\n newProperties['aria-labelledby'] = uniqueId;\n svg.children.unshift({\n type: 'element',\n tagName: 'title',\n properties: {\n id: uniqueId,\n },\n children: [\n {\n type: 'text',\n value: label,\n },\n ],\n });\n }\n\n svg.properties = newProperties;\n return svg;\n}\n","import { liteAdaptor } from 'mathjax-full/js/adaptors/liteAdaptor.js';\nimport { STATE } from 'mathjax-full/js/core/MathItem.js';\nimport { SerializedMmlVisitor } from 'mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js';\nimport { RegisterHTMLHandler } from 'mathjax-full/js/handlers/html.js';\nimport { HTMLDocument } from 'mathjax-full/js/handlers/html/HTMLDocument.js';\nimport { MathML } from 'mathjax-full/js/input/mathml.js';\nimport { TeX } from 'mathjax-full/js/input/tex.js';\nimport { AllPackages } from 'mathjax-full/js/input/tex/AllPackages.js';\nimport { mathjax } from 'mathjax-full/js/mathjax.js';\nimport { SVG } from 'mathjax-full/js/output/svg.js';\n// @ts-expect-error\nimport SRE from 'speech-rule-engine';\n\nexport function texToMml(tex: string = '') {\n const adaptor = liteAdaptor();\n // Busproofs requires an output jax, which we aren't using\n const packages = AllPackages.filter((name) => name !== 'bussproofs');\n const input = new TeX({ packages });\n const doc = new HTMLDocument('', adaptor, { InputJax: input });\n const node = doc.convert(tex, { end: STATE.CONVERT });\n const visitor = new SerializedMmlVisitor();\n return visitor.visitTree(node);\n}\n\nexport function mmlToSvg(mml: string) {\n const adaptor = liteAdaptor();\n RegisterHTMLHandler(adaptor);\n const input = new MathML();\n const output = new SVG({ fontCache: 'local' });\n const doc = mathjax.document('', { InputJax: input, OutputJax: output });\n const node = doc.convert(mml, { em: 25 });\n return adaptor.outerHTML(node);\n}\n\nexport function mmlToSpeech(mml: string) {\n return SRE.toSpeech(mml);\n}\n","import { liteAdaptor } from 'mathjax-full/js/adaptors/liteAdaptor.js';\nimport { MathDocument } from 'mathjax-full/js/core/MathDocument.js';\nimport * as MathItem from 'mathjax-full/js/core/MathItem.js';\nimport { SerializedMmlVisitor } from 'mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js';\nimport { RegisterHTMLHandler } from 'mathjax-full/js/handlers/html.js';\nimport { TeX } from 'mathjax-full/js/input/tex.js';\nimport { AllPackages } from 'mathjax-full/js/input/tex/AllPackages.js';\nimport { mathjax } from 'mathjax-full/js/mathjax.js';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { assertNoTexTabular } from '../linter/assert-no-tex-tabular';\nimport { failMessage } from '../utils/message';\n\n// This custom MathJax implementation has had to diverge from the provided demos found\n// here: https://github.com/mathjax/MathJax-demos-node, because they are all focused on\n// either converting LaTeX on its own or (referencing \"page\" demos) LaTeX embedded in\n// HTML, whereas at this stage in the processor we're dealing with LaTeX embedded in\n// Markdown. Due to TeX/LaTeX making heavy use of the backslash (\\) character, we need\n// to deal with it early as it conflicts with other libraries used later.\n\n// I use the MathJax \"page\" process as it will pick up LaTeX even without delimiters\n// and stores context required for numbered references (based on direct/tex2mml-page).\n// However this has a naive HTML handler which will munge HTML (and Python) in some\n// cases so I am careful to only mutate TeX and leave the rest of the Markdown alone.\n\n// I replace the TeX with a placeholder formatted as a Markdown directive, for example\n// :inlineMath[21] or :blockMath[42].\n\n// I convert the TeX to MathML and store it memory for use later (in directive-to-svg.ts).\n\nexport function texToAliasDirective(file: VFile, ctx: Context) {\n // simple regex tests\n assertNoTexTabular(file);\n\n const md = file.value as string;\n const store: string[] = [];\n const adaptor = liteAdaptor();\n const visitor = new SerializedMmlVisitor();\n RegisterHTMLHandler(adaptor);\n\n const doc = mathjax.document(md, {\n InputJax: new TeX({\n // Bussproofs requires an output jax\n packages: AllPackages.filter((name) => name !== 'bussproofs'),\n // Allow numbered references\n tags: 'ams',\n // Allow single $ delimiters\n inlineMath: [\n ['$', '$'],\n ['\\\\(', '\\\\)'],\n ],\n displayMath: [\n ['$$', '$$'],\n [`\\\\[`, `\\\\]`],\n ],\n }),\n // wrap verbatim latex with
\n ignoreHtmlClass: 'mathjax-ignore',\n renderActions: {\n typeset: [\n MathItem.STATE.TYPESET,\n ({ math }: MathDocument) => {\n for (const item of Array.from(math)) {\n let newMarkdown = '';\n\n // convert to MathML\n const mml = visitor.visitTree(item.root);\n assertNoMmlError(mml, file);\n\n // escaped dollar sign...\n if (item.math === '$') {\n newMarkdown = '$';\n }\n\n // double backslash...\n else if (item.math === '\\\\') {\n newMarkdown = '\\\\\\\\';\n }\n\n // reference link...\n else if (isReferenceLink(item.math)) {\n const refNum = extractRefNumFromMml(mml, item.math, file);\n const anchor = extractAnchorLinkFromMml(\n mml,\n item.math,\n file\n );\n newMarkdown = `[${refNum}](${anchor})`;\n }\n\n // normal use case (equation)...\n else {\n store.push(mml);\n const type = item.display ? 'blockMath' : 'inlineMath';\n newMarkdown = `:${type}[${store.length - 1}]`;\n }\n\n const tree = adaptor.parse(newMarkdown, 'text/html');\n item.typesetRoot = adaptor.firstChild(adaptor.body(tree));\n }\n },\n ],\n },\n });\n\n // add store to ctx\n ctx.mmlStore = store;\n\n doc.render();\n\n // replace md in VFile\n const result = adaptor.innerHTML(adaptor.body(doc.document));\n file.value = postParse(result);\n\n return file;\n}\n\nfunction assertNoMmlError(mml: string, file: VFile) {\n const match = mml.match(/(.+)<\\/mtext>/);\n if (match === null) {\n failMessage(file, `Invalid reference: ${tex}`);\n return;\n }\n if (match[1] === '???') {\n failMessage(\n file,\n `Invalid reference: ${tex}. You may only reference numbered sections.`\n );\n }\n return match[1] as string;\n}\n\nfunction extractAnchorLinkFromMml(mml: string, tex: string, file: VFile) {\n const match = mml.match(//);\n if (match === null) {\n failMessage(file, `Reference has no anchor link: ${tex}`);\n return;\n }\n return decodeURIComponent(match[1] || '') as string;\n}\n\nfunction postParse(html: string) {\n let result = html;\n result = unprotectHtml(result);\n result = removeUnresolvedLabels(result);\n return result;\n}\n\n// https://github.com/mathjax/MathJax-src/blob/41565a97529c8de57cb170e6a67baf311e61de13/ts/adaptors/lite/Parser.ts#L399-L403\nfunction unprotectHtml(html: string) {\n return html\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nfunction removeUnresolvedLabels(html: string) {\n return html.replace(/\\\\label{def:.*?}/gm, '');\n}\n","import { Image } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\nimport { checkLocalFileExists } from '../utils/utils';\n\nexport function assertAssetExists() {\n async function getAssetUrl(node: Image, file: VFile) {\n const url = (node.url || '') as string;\n if (!file.dirname) {\n throw new Error('VFile dirname undefined');\n }\n if (!url.startsWith('http')) {\n const exists = await checkLocalFileExists(url);\n if (!exists) {\n failMessage(file, `No asset found at ${url}`, node.position);\n }\n }\n }\n\n return async (tree: Node, file: VFile) => {\n const transformations: Promise[] = [];\n visit(tree, 'image', (node) => {\n transformations.push(getAssetUrl(node, file));\n });\n await Promise.all(transformations);\n };\n}\n","import { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertColumnStructure() {\n return (tree: Root, file: VFile) => {\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, index, _parent) => {\n if (node.name === 'columns') {\n const children = node.children as ContainerDirective[];\n const columns = children.filter((o) => o.name === 'column');\n if (columns.length < 2) {\n failMessage(\n file,\n 'Columns must contain at least 2 columns',\n node.position\n );\n }\n }\n if (node.name === 'column') {\n const parent = _parent as ContainerDirective;\n if (!parent || parent.name !== 'columns') {\n failMessage(\n file,\n 'Column must be nested inside columns',\n node.position\n );\n }\n }\n }\n );\n };\n}\n","import { Root } from 'mdast';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertNoH1() {\n return (tree: Root, file: VFile) => {\n visit(tree, 'heading', (node) => {\n if (node.depth === 1) {\n failMessage(\n file,\n 'Level 1 heading found. Only one Level 1 heading can be used in the document and it is automatically generated from .yaml file and should not be found in .Rmd file. Please use Level 2 (## Example) and below.',\n node.position\n );\n return;\n }\n });\n };\n}\n","import { VFile } from 'vfile';\n\nimport { warnMessage } from '../utils/message';\n\nexport function assertNoImageAttributes(file: VFile) {\n const md = file.value as string;\n md.split('\\n').forEach((line, idx) => {\n const match = line.match(/!\\[.*\\]\\(.*\\)({.+})/);\n if (match !== null) {\n warnMessage(\n file,\n `image attributes are not supported: ${match[1]}`,\n {\n start: {\n line: idx + 1,\n column: 0,\n },\n end: {\n line: idx + 1,\n column: line.length,\n },\n }\n );\n }\n });\n}\n","import { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\n// TODO: could possibly try converting to array here\n// https://stackoverflow.com/questions/51803244\n\nexport function assertNoTexTabular(file: VFile) {\n const md = file.value as string;\n md.split('\\n').forEach((line, idx) => {\n if (line.includes('\\\\begin{tabular}')) {\n failMessage(\n file,\n 'LaTeX tables are not allowed, please use Markdown syntax',\n {\n start: {\n line: idx + 1,\n column: 0,\n },\n end: {\n line: idx + 1,\n column: line.length,\n },\n }\n );\n }\n });\n}\n","import { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertTaskAnswerStructure() {\n return (tree: Root, file: VFile) => {\n let count = 0;\n visit(tree, 'containerDirective', (node, index, _parent) => {\n if (node.name === 'task') {\n count++;\n const children = node.children as ContainerDirective[];\n const answers = children.filter((o) => o.name === 'answer');\n if (answers.length < 1) {\n failMessage(file, `Task ${count} has no answer`, node.position);\n }\n if (answers.length > 1) {\n failMessage(file, 'Task has multiple answers', node.position);\n }\n }\n if (node.name === 'answer') {\n const parent = _parent as ContainerDirective;\n if (!parent || parent.name !== 'task') {\n failMessage(\n file,\n 'Answer must be nested inside task',\n node.position\n );\n }\n }\n });\n };\n}\n","import { Literal, Parent } from 'mdast';\nimport { Root } from 'mdast';\nimport { LeafDirective } from 'mdast-util-directive';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertVideoAttributes() {\n return async (tree: Root, file: VFile) => {\n visit(tree, 'leafDirective', (node: LeafDirective) => {\n if (node.name === 'video') {\n if (!node.attributes?.id) {\n failMessage(file, 'id attribute is required', node.position);\n }\n if (!node.attributes?.duration) {\n failMessage(\n file,\n 'duration attribute is required',\n node.position\n );\n }\n\n const title = getTitle(node);\n if (!title) {\n failMessage(file, 'title is required', node.position);\n }\n }\n });\n };\n}\n\nfunction getTitle(node: Parent) {\n const children = node.children as Node[];\n const firstChild = children[0] as Literal;\n return (firstChild?.value || '') as string;\n}\n","import { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function assertWeblinkTarget() {\n return (tree: Root, file: VFile) => {\n visit(tree, 'containerDirective', (node: ContainerDirective) => {\n if (node.name === 'weblink') {\n if (node.attributes?.target === undefined) {\n failMessage(\n file,\n 'Weblink has no target attribute',\n node.position\n );\n }\n }\n });\n };\n}\n","// @ts-expect-error\nimport lintAltText from '@double-great/remark-lint-alt-text';\n// @ts-expect-error\nimport lintLinkText from '@mapbox/remark-lint-link-text';\nimport dictionary from 'dictionary-en-gb';\nimport remark2retext from 'remark-retext';\nimport english from 'retext-english';\nimport spell from 'retext-spell';\nimport { unified } from 'unified';\nimport { Node } from 'unist';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { assertAssetExists } from './assert-asset-exists';\nimport { assertColumnStructure } from './assert-columns';\nimport { assertNoH1 } from './assert-no-h1';\nimport { assertTaskAnswerStructure } from './assert-task-answer';\nimport { assertVideoAttributes } from './assert-video-attributes';\nimport { assertWeblinkTarget } from './assert-weblink-target';\nimport { lintLatex } from './lint-latex';\nimport { printReport, reportHasFatalErrors } from './report';\n\nexport function reportErrors(files: VFile[], ctx: Context) {\n if (!ctx.options.noReport) {\n printReport(files, ctx);\n }\n if (reportHasFatalErrors(files, ctx)) {\n if (ctx.options.noReport) {\n printReport(files, {\n ...ctx,\n options: {\n ...ctx.options,\n reportOnlyErrors: true,\n },\n });\n }\n console.log('Report has fatal errors');\n if (ctx.options.force) {\n console.log('Compiling using force option...');\n } else {\n process.exit();\n }\n }\n}\n\nexport async function createReport(\n file: VFile,\n mdast: Node,\n ctx: Context\n) {\n const processor = unified()\n .use(assertAssetExists)\n .use(assertVideoAttributes)\n .use(assertTaskAnswerStructure)\n .use(assertColumnStructure)\n .use(assertWeblinkTarget)\n .use(assertNoH1)\n .use(lintLatex)\n .use(lintAltText)\n .use(lintLinkText);\n\n if (ctx.options.spelling) {\n const retextProcessor = unified()\n .use(english)\n .use(spell, { dictionary, max: 1 });\n processor.use(remark2retext, retextProcessor);\n }\n\n await processor.run(mdast, file);\n}\n","import { exec } from 'child_process';\n\nimport { Literal, Root } from 'mdast';\nimport { Position } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nexport function lintLatex() {\n return async (tree: Root, file: VFile) => {\n const transformations: Promise[] = [];\n\n visit(tree, 'math', (node: Literal) => {\n transformations.push(chktex(node, file));\n });\n\n await Promise.all(transformations);\n return tree;\n };\n}\n\nasync function chktex(node: Literal, file: VFile) {\n return new Promise((resolve, reject) => {\n exec(`chktex -q <<< \"${node.value}\"`, (err, response) => {\n if (err) {\n reject(err);\n } else {\n const messages = formatResponse(response);\n const position = node.position as Position;\n messages.forEach(({ line, column, message }) => {\n file.message(message, {\n line: position.start.line + line,\n column: position.start.column + column,\n });\n });\n resolve();\n }\n });\n });\n}\n\ntype Message = {\n line: number;\n column: number;\n message: string;\n};\n\nfunction formatResponse(response: string) {\n if (response.trim() === '') {\n return [];\n }\n\n function formatMessage(message: string) {\n return message.replace(/'/g, '').replace(/`/g, '');\n }\n\n return response\n .split(/Warning \\d+ in stdin line /)\n .filter(Boolean)\n .reduce((acc: Message[], s) => {\n const [key, value] = s.split(':');\n const line = Number(key);\n const trimmed = value.trim();\n\n const match = trimmed.match(/(.*)\\n(.*)\\n(\\s*)\\^/m);\n if (Array.isArray(match)) {\n const message = formatMessage(match[1]);\n acc.push({\n line,\n column: match[3].length,\n message: `${message}\\n\\n${match[2]}\\n${match[3]}^`,\n });\n } else {\n acc.push({\n line,\n column: 0,\n message: formatMessage(trimmed),\n });\n }\n\n return acc;\n }, []);\n}\n","import chalk from 'chalk';\nimport figures from 'figures';\nimport { VFile } from 'vfile';\nimport { VFileMessage } from 'vfile-message';\n\nimport { Context } from '../context';\nimport { MessageStatus } from '../utils/message';\n\nexport type Report = {\n failed: boolean;\n files: ReportFile[];\n};\n\nexport type ReportFile = Omit & {\n messages: ReportMessage[];\n};\n\nexport type ReportMessage = {\n status: MessageStatus;\n position: string;\n reason: string;\n line: number;\n column: number;\n};\n\nexport function printReport(files: VFile[], ctx: Context) {\n const { reportOnlyErrors, shouldFail } = ctx.options;\n\n if (reportOnlyErrors && shouldFail) {\n return;\n }\n\n for (const file of files) {\n // console.log(file.messages);\n const messages = reportOnlyErrors\n ? failingMessages(file.messages)\n : file.messages;\n\n if (messages.length !== 0) {\n // if (file.path !== undefined) {\n // console.log(`\\n${getFilePath(file.path)}`);\n // }\n messages.forEach((message) => {\n printMessage(message);\n });\n }\n }\n}\n\nexport function reportHasFatalErrors(files: VFile[], ctx: Context) {\n return files.some((file) => {\n const messages = file.messages as unknown as ReportMessage[];\n return messages.some(\n (message) => message.status === MessageStatus.fail\n );\n });\n}\n\nexport function reportHasWarnings(files: VFile[], ctx: Context) {\n return files.some((file) => {\n const messages = file.messages as unknown as ReportMessage[];\n return messages.some(\n (message) => message.status === MessageStatus.warning\n );\n });\n}\n\nfunction failingMessages(_messages: VFileMessage[]) {\n const messages = _messages as unknown as ReportMessage[];\n return messages.filter(\n (o) => o.status === MessageStatus.fail\n ) as unknown as VFileMessage[];\n}\n\nfunction printMessage(_message: VFileMessage) {\n const message = _message as unknown as ReportMessage;\n // console.log(message);\n const status = message.status;\n const position = chalk.grey(`${message.line}:${message.column}`);\n const reason = formatReason(message.reason, status);\n console.log(`${formatStatus(status)} ${position} ${reason}`);\n}\n\n// function getFilePath(filePath: string) {\n// return path.isAbsolute(filePath)\n// ? filePath\n// : path.join(process.cwd(), filePath);\n// }\n\nfunction formatStatus(status: MessageStatus) {\n const statusColour = getStatusColour(status);\n switch (status) {\n case MessageStatus.fail:\n return statusColour(figures.cross);\n default:\n return statusColour(figures.warning);\n // TODO: fail on unsupported status?\n }\n}\n\nfunction formatReason(reason: string, status: MessageStatus) {\n const statusColour = getStatusColour(status);\n const [first, ...rest] = reason.split('\\n');\n const formattedFirst = statusColour(first);\n const formattedRest = rest.map((line) => chalk.grey(line));\n return [formattedFirst, ...formattedRest].join('\\n');\n}\n\nfunction getStatusColour(status: MessageStatus) {\n switch (status) {\n case MessageStatus.fail:\n return chalk.red;\n default:\n return chalk.yellow;\n }\n}\n","import { Element, Parent as HastParent, Text } from 'hast';\nimport startCase from 'lodash/startCase.js';\nimport { Root } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { toHast } from 'mdast-util-to-hast';\nimport { Node, Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\nimport { createCounter } from '../utils/counter';\n\nexport function boxouts(refStore: Context['refStore']) {\n const counter = createCounter();\n return async (tree: Node) => {\n visit(tree, 'containerDirective', (node: ContainerDirective) => {\n switch (node.name) {\n case 'example':\n case 'error':\n case 'supplement':\n case 'background':\n case 'definition':\n case 'weblink':\n case 'theorem':\n case 'task':\n case 'proposition':\n case 'answer': {\n const name = node.name as string;\n const count = counter.increment(name);\n node.data = {\n hProperties: createAttributes(node, count, refStore),\n hChildren: createBoxout(node, count),\n };\n }\n }\n });\n };\n}\n\nfunction createAttributes(\n node: ContainerDirective,\n count: number,\n refStore: Context['refStore']\n) {\n const name = node.name as string;\n const id = `${name}-${count}`;\n\n const attributes = node.attributes as Record;\n const className = ['boxout', name];\n if (attributes.icon) {\n className.push(`${attributes.icon}-icon`);\n }\n\n if (node.attributes?.label !== undefined) {\n refStore[node.attributes.label] = id;\n }\n\n return { className, id };\n}\n\nexport function createBoxout(\n node: ContainerDirective,\n count: number\n): Node[] {\n const typeTitle = createBoxoutType(node, count);\n const titles = [typeTitle];\n\n const titleValue = getTitleValue(node);\n if (titleValue.length > 0) {\n const title = createTitle(node);\n titles.push(title);\n }\n\n const children = node.children as ContainerDirective[];\n\n const content = children\n .filter((o) => !o.data?.directiveLabel)\n .filter((o) => o.type !== 'containerDirective' && o.name !== 'answer')\n .map((o) => toHast(o, { allowDangerousHtml: true }))\n .filter(Boolean) as HastParent[];\n\n if (node.name === 'task') {\n const answer = children.find(\n (o) => o.type === 'containerDirective' && o.name === 'answer'\n );\n if (answer) {\n const answerHast = createAnswer(answer, count);\n content.push(answerHast as HastParent);\n }\n }\n\n return [...titles, ...content];\n}\n\nfunction createAnswer(node: ContainerDirective, count: number) {\n const { children } = toHast(node) as HastParent;\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n className: ['answer'],\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['answer-trigger'],\n 'data-answer-id': count,\n },\n children: [\n {\n type: 'text',\n value: 'Show answer',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'div',\n properties: {\n className: ['answer-reveal'],\n id: `answer-${count}`,\n },\n children,\n },\n ],\n };\n}\n\nfunction createBoxoutType(\n node: ContainerDirective,\n count: number\n): Element {\n const name = node.name as string;\n const label = startCase(name);\n let value = `${label} ${count}`;\n\n if (node.attributes?.optional !== undefined) {\n value += ` (Optional)`;\n }\n\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['type'],\n },\n children: [\n {\n type: 'text',\n value,\n },\n ],\n };\n}\n\nfunction createTitle(node: ContainerDirective): Element {\n return {\n type: 'element',\n tagName: 'h3',\n children: createTitleValue(node) as Element['children'],\n };\n}\n\nfunction createTitleValue(node: ContainerDirective) {\n const name = node.name as string;\n const newRoot = {\n type: 'root',\n children: getTitleValue(node),\n };\n const { children = [] } = toHast(newRoot as Root) as Parent;\n if (name !== 'weblink') {\n return children;\n }\n const { target } = node.attributes as Record;\n return [\n {\n type: 'element',\n tagName: 'a',\n properties: {\n href: target,\n target: '_blank',\n className: ['target'],\n },\n children,\n },\n ];\n}\n\nfunction getTitleValue(node: ContainerDirective): Node[] {\n const children = (node.children || []) as Node[];\n const parent = (children[0] || {}) as Parent;\n\n if (!parent.data?.directiveLabel) {\n if (node.name === 'weblink') {\n const attributes = node.attributes as Record;\n return [\n {\n type: 'text',\n value: attributes.target,\n } as Text,\n ];\n }\n return [];\n }\n\n return parent.children || [];\n}\n","import { Properties, Text } from 'hast';\nimport { Code } from 'mdast';\nimport { refractor } from 'refractor';\nimport { RefractorElement } from 'refractor/lib/core';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\n\nexport function codeBlocks(ctx: Context) {\n return async (tree: Node, file: VFile) => {\n // replace \\\\n with \\n in code samples\n // visit(tree, 'inlineCode', (node) => {\n // const old = node.value;\n // const transformed = old.replace(/\\\\\\\\n/g, '\\\\n');\n // // console.log({ old, transformed, same: old === transformed });\n // node.value = transformed;\n // });\n\n visit(tree, 'code', (node: Code) => {\n customCode(node, ctx, file);\n });\n };\n}\n\nfunction customCode(node: Code, ctx: Context, file: VFile) {\n // const { language, options, value } = parseCodeParams(node);\n const language = parseLanguage(node);\n const klass = parseClass(node);\n const meta = (node.meta || '') as string;\n\n const codeProps: Properties = {};\n if (meta !== '') {\n codeProps.className = meta;\n }\n\n const children: (RefractorElement | Text)[] = [];\n const trimmed = node.value.trim();\n if (ctx.options.noSyntaxHighlight || language === '') {\n children.push({\n type: 'text',\n value: trimmed,\n });\n } else {\n const highlighted = refractor.highlight(trimmed, language);\n children.push(...highlighted.children);\n }\n\n Object.assign(node, {\n type: 'custom-code',\n data: {\n hName: 'div',\n hProperties: {\n className: ['code-wrapper', klass],\n },\n hChildren: [\n addConsoleHeading(klass),\n {\n type: 'element',\n tagName: 'pre',\n children: [\n {\n type: 'element',\n tagName: 'code',\n properties: codeProps,\n children,\n },\n ],\n },\n ],\n },\n });\n}\n\nfunction addConsoleHeading(klass: string) {\n if (klass === 'r-output' || klass === 'r-error-output') {\n return {\n type: 'element',\n tagName: 'h6',\n properties: {\n className: 'console-heading',\n },\n children: [\n {\n type: 'text',\n value: 'R Console',\n },\n ],\n };\n }\n if (klass === 'python-output' || klass === 'python-error-output') {\n return {\n type: 'element',\n tagName: 'h6',\n properties: {\n className: 'console-heading',\n },\n children: [\n {\n type: 'text',\n value: 'Python Console',\n },\n ],\n };\n }\n return null;\n}\n\nfunction parseLanguage(node: Code) {\n const lang = (node.lang || '') as string;\n if (lang === 'plaintext' || lang.startsWith('{')) {\n return '';\n }\n return lang.toLowerCase();\n}\n\nfunction parseClass(node: Code) {\n const lang = (node.lang || '') as string;\n if (!lang.startsWith('{.')) {\n return '';\n }\n return lang.slice(2, -1);\n}\n","import { BlockContent, Text } from 'mdast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { Node, Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nexport function columns() {\n return (tree: Node) => {\n visit(tree, 'containerDirective', (node: ContainerDirective) => {\n if (node.name === 'columns') {\n node.data = {\n hProperties: {\n className: 'columns',\n },\n };\n } else if (node.name === 'column') {\n node.data = {\n hProperties: {\n className: 'column',\n },\n };\n\n if (node.attributes?.imgsrc) {\n const altText = getAltText(node);\n\n const img = {\n type: 'image',\n url: node.attributes.imgsrc,\n alt: altText,\n } as unknown as BlockContent;\n\n if (altText) {\n Object.assign(node.children[0], img);\n } else {\n node.children.unshift(img);\n }\n }\n }\n });\n };\n}\n\nfunction getAltText(column: ContainerDirective) {\n const firstChild = column.children[0] as Parent;\n if (!firstChild) {\n return false;\n }\n\n const firstChildChildren = firstChild.children as Node[];\n if (!Array.isArray(firstChildChildren)) {\n return false;\n }\n\n const firstChildFirstChild = firstChildChildren[0] as Text;\n if (!firstChildFirstChild) {\n return false;\n }\n\n return firstChildFirstChild.value;\n}\n","import { Root } from 'mdast';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { boxouts } from './boxouts';\nimport { environment } from './environment';\nimport { moveAnswersToEnd } from './move-answers-to-end';\n\nexport async function combinedMdastPhase(\n mdast: Root,\n ctx: Context,\n file: VFile,\n targetPdf?: boolean\n) {\n const processor = unified()\n .use(environment, ctx, targetPdf)\n .use(boxouts, ctx.refStore);\n\n if (targetPdf) {\n processor.use(moveAnswersToEnd);\n }\n\n return processor.run(mdast, file) as Promise;\n}\n","import path from 'path';\n\nimport { Literal, Root } from 'mdast';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\n\nexport function embedAssetUrl(ctx: Context) {\n return async (tree: Root) => {\n let activeDir = '';\n\n // nodes need to be visited in the correct order\n // to derive the document directory\n visit(tree, (node, index, parent) => {\n // to ensure relative paths to assets across multiple .Rmd files\n if (node.type === 'textDirective' && node.name === 'directory') {\n const firstChild = node.children[0] as Literal;\n activeDir = firstChild.value || '';\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n }\n\n if (node.type === 'image') {\n node.url = getPath(node.url, activeDir, ctx);\n }\n\n // also fix for raw html nodes sometimes output by knitr\n if (node.type === 'html') {\n const props = getProps(node.value);\n if (props !== null && props.src) {\n const { src, ...otherProps } = props;\n Object.assign(node, {\n type: 'image',\n url: getPath(src, activeDir, ctx),\n value: '',\n data: otherProps,\n });\n }\n }\n });\n };\n}\n\nfunction getPath(url: string, dirname: string, ctx: Context) {\n return path.isAbsolute(url) ||\n url.startsWith('http') ||\n ctx.options.noEmbedAssetUrl\n ? url\n : path.join(dirname, url);\n}\n\nfunction getProps(value: string) {\n const matchImg = value.match(/^$/);\n if (matchImg !== null) {\n return propsToObject(value.slice(5, -1));\n }\n const matchPdf = value.match(/^$/);\n if (matchPdf !== null) {\n return propsToObject(value.slice(7, -1));\n }\n return null;\n}\n\nfunction propsToObject(str: string) {\n return str\n .split(/(\\w+)=\"(.*?)\"/)\n .filter((s) => s.trim() !== '')\n .reduce((acc: Record, value, idx, arr) => {\n if (idx % 2 === 1) {\n const key = arr[idx - 1];\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n","import { Element, Literal } from 'hast';\nimport startCase from 'lodash/startCase.js';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { toHast } from 'mdast-util-to-hast';\nimport { Node, Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\n\nconst platforms = ['mac', 'windows', 'linux'];\nconst programs = ['cli', 'github-desktop'];\n\nexport function environment(ctx: Context, targetPdf?: boolean) {\n const platformFlag = ctx.options.envPlatform;\n if (platformFlag !== undefined && !platforms.includes(platformFlag)) {\n throw new Error(\n `[environment]: envPlatform ${platformFlag} should be one of ${platforms}`\n );\n }\n\n const programFlag = ctx.options.envProgram;\n if (programFlag !== undefined && !programs.includes(programFlag)) {\n throw new Error(\n `[environment]: envProgram ${programFlag} should be one of ${programs}`\n );\n }\n\n return async (tree: Node) => {\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (node.name === 'environment') {\n if (targetPdf || (platformFlag && programFlag)) {\n removeNode(parent, index);\n } else {\n createEnvironmentConfig(node, platformFlag, programFlag);\n }\n }\n }\n );\n\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (platforms.includes(node.name)) {\n node.data = {\n hProperties: {\n className: [\n 'platform',\n node.name,\n platformFlag === node.name ? 'show' : '',\n ],\n },\n };\n if (platformFlag && platformFlag !== node.name) {\n removeNode(parent, index);\n }\n }\n },\n true\n );\n\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (programs.includes(node.name)) {\n node.data = {\n hProperties: {\n className: [\n 'program',\n node.name,\n programFlag === node.name ? 'show' : '',\n ],\n },\n };\n if (programFlag && programFlag !== node.name) {\n removeNode(parent, index);\n }\n }\n },\n true\n );\n };\n}\n\nfunction removeNode(parent: Parent, index: number) {\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n}\n\ntype HastNode = Element | Literal;\n\nfunction createEnvironmentConfig(\n node: Parent,\n platformFlag?: string,\n programFlag?: string\n) {\n const hName = 'div';\n\n const hProperties = {\n id: 'environment',\n className: 'boxout',\n };\n\n const hChildren: HastNode[] = [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: ['type'],\n },\n children: [\n {\n type: 'text',\n value: 'Environment',\n },\n ],\n },\n ...node.children.map((node) => toHast(node as any) as HastNode),\n ];\n\n if (!platformFlag) {\n hChildren.push({\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'platforms',\n },\n children: [\n {\n type: 'element',\n tagName: 'h3',\n children: [\n {\n type: 'text',\n value: 'Platform',\n },\n ],\n },\n ...platforms.map((platform, idx) => {\n return createRadioInput('platform', platform, idx);\n }),\n ],\n });\n }\n\n if (!programFlag) {\n hChildren.push({\n type: 'element',\n tagName: 'div',\n properties: {\n id: 'programs',\n },\n children: [\n {\n type: 'element',\n tagName: 'h3',\n children: [\n {\n type: 'text',\n value: 'Program',\n },\n ],\n },\n ...programs.map((program, idx) => {\n return createRadioInput('program', program, idx);\n }),\n ],\n });\n }\n\n node.data = {\n hName,\n hProperties,\n hChildren,\n };\n}\n\nfunction createRadioInput(\n name: string,\n value: string,\n idx: number\n): Element {\n return {\n type: 'element',\n tagName: 'label',\n properties: {\n [`data-${name}`]: value,\n },\n children: [\n {\n type: 'element',\n tagName: 'input',\n properties: {\n type: 'radio',\n name,\n value,\n checked: idx === 0,\n },\n children: [],\n },\n {\n type: 'element',\n tagName: 'span',\n children: [\n {\n type: 'text',\n value: startCase(value),\n },\n ],\n },\n ],\n };\n}\n","import { Element, ElementContent } from 'hast';\nimport kebabCase from 'lodash/kebabCase.js';\nimport { Image } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nimport { Context } from '../context';\n\nexport function images(ctx: Context) {\n return (tree: Node) => {\n visit(tree, 'image', (node) => {\n template(node, ++ctx.figureCounter);\n });\n };\n}\n\nfunction template(node: Image, count: number) {\n const image: Element = {\n type: 'element',\n tagName: 'div',\n properties: {\n className: 'img-bg',\n },\n children: [\n {\n type: 'element',\n tagName: 'img',\n properties: {\n src: node.url,\n alt: node.alt,\n },\n children: [],\n },\n ],\n };\n\n if (node.data?.width && /^\\d+px/.test(String(node.data.width))) {\n image.properties = {\n ...image.properties,\n style: `width: ${node.data.width};`,\n };\n }\n\n const alt = getAltText(node);\n const slug = kebabCase(alt ? alt : `Figure ${count}`);\n\n const caption = {\n type: 'element',\n tagName: 'figcaption',\n children: [\n {\n type: 'element',\n tagName: 'a',\n properties: {\n href: `#${slug}`,\n },\n children: createLabel(alt, count),\n },\n ],\n };\n\n Object.assign(node, {\n type: 'custom-image',\n data: {\n hName: 'figure',\n hProperties: {\n className: ['img-wrapper'],\n id: slug,\n },\n hChildren: [image, caption],\n },\n });\n}\n\nfunction createLabel(alt: string, count: number): ElementContent[] {\n if (alt) {\n return [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'caption-count',\n },\n children: [\n {\n type: 'text',\n value: `Figure ${count}:`,\n },\n ],\n },\n {\n type: 'text',\n value: ` ${alt}`,\n },\n ];\n }\n return [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'caption-count',\n },\n children: [\n {\n type: 'text',\n value: `Figure ${count}`,\n },\n ],\n },\n ];\n}\n\nfunction getAltText(node: Image) {\n const altText = node.alt || '';\n if (altText.includes('unnamed-chunk')) {\n return '';\n }\n return altText;\n}\n","import headings from 'remark-autolink-headings';\nimport directive from 'remark-directive';\nimport footnotes from 'remark-footnotes';\nimport frontmatter from 'remark-frontmatter';\nimport gfm from 'remark-gfm';\nimport markdown from 'remark-parse';\nimport slug from 'remark-slug';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { aliasDirectiveToSvg } from '../latex/directive-to-svg';\n// import { aliasDirectiveToTex } from '../latex/directive-to-tex';\nimport { createSvg } from '../utils/icons';\nimport { codeBlocks } from './code-blocks';\nimport { columns } from './columns';\nimport { embedAssetUrl } from './embed-asset-url';\nimport { images } from './images';\nimport { pagebreaks } from './pagebreaks';\nimport { removeEmptyParagraphs } from './remove-empty-paragraphs';\nimport { youtubeVideos } from './youtube-videos';\n\nexport async function mdastPhase(file: VFile, ctx: Context) {\n // https://github.com/unifiedjs/unified\n // convert markdown to syntax tree: complex transforms\n // should be more robust and straightforward\n const processor = unified()\n // third-party plugins:\n .use(markdown)\n .use(directive)\n .use(frontmatter)\n .use(footnotes, { inlineNotes: true })\n .use(gfm)\n // .use(sectionize)\n .use(slug)\n .use(headings, {\n content: createSvg('link-icon'),\n linkProperties: { className: 'link' },\n })\n // custom plugins:\n .use(columns)\n .use(embedAssetUrl, ctx)\n .use(youtubeVideos)\n .use(aliasDirectiveToSvg, ctx)\n .use(removeEmptyParagraphs)\n // .use(aliasDirectiveToTex, ctx)\n .use(codeBlocks, ctx)\n .use(images, ctx)\n .use(pagebreaks);\n\n const parsed = processor.parse(file);\n return processor.run(parsed, file);\n}\n","import { Node, Parent } from 'hast';\nimport { ContainerDirective } from 'mdast-util-directive';\nimport { visit } from 'unist-util-visit';\n\nexport function moveAnswersToEnd() {\n return (tree: Node) => {\n visit(\n tree,\n 'containerDirective',\n (node: ContainerDirective, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n // remove answer from task rehype\n if (node.name === 'task' && node.data) {\n const children = (node.data.hChildren ||\n []) as ContainerDirective[];\n node.data.hChildren = children.filter(\n (o) => o.name !== 'answer'\n );\n }\n\n if (node.name === 'answer') {\n // these nodes have already been moved to the end\n if (node.attributes?.movedToEnd === 'yes') {\n return;\n }\n\n // remove answer block from task node\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n\n // add to root node\n const treeParent = tree as Parent;\n const treeChildren = (treeParent.children || []) as Node[];\n\n node.attributes = {\n ...(node.attributes || {}),\n movedToEnd: 'yes',\n };\n\n treeChildren.push(node);\n }\n }\n );\n };\n}\n","import { LeafDirective } from 'mdast-util-directive';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nexport function pagebreaks() {\n return async (tree: Node) => {\n visit(tree, 'leafDirective', (node: LeafDirective) => {\n if (node.name === 'pagebreak') {\n node.data = {\n hName: 'hr',\n hProperties: {\n className: 'pagebreak',\n },\n };\n }\n });\n };\n}\n","import { Paragraph, Parent } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\n\nexport function removeEmptyParagraphs() {\n return async (tree: Node) => {\n visit(tree, 'paragraph', (node: Paragraph, _index, _parent) => {\n const index = _index as number;\n const parent = _parent as Parent;\n\n if (node.children.length === 0) {\n const parentChildren = parent?.children || [];\n parentChildren.splice(index || 0, 1);\n }\n });\n };\n}\n","import { Literal } from 'mdast';\nimport { LeafDirective } from 'mdast-util-directive';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\nimport { failMessage } from '../utils/message';\n\nexport function youtubeVideos() {\n return async (tree: Node, file: VFile) => {\n visit(tree, 'leafDirective', (node: LeafDirective) => {\n if (node.name === 'video') {\n const attributes = node.attributes;\n const title = getTitle(node, file);\n node.data = {\n hName: 'a',\n hProperties: {\n className: ['boxout', 'video'],\n href: getYoutubeUrl(attributes?.id || ''),\n title: attributes?.title || null,\n target: '_blank',\n },\n hChildren: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'content',\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'type',\n },\n children: [\n {\n type: 'text',\n value: 'Video',\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'title',\n },\n children: [\n {\n type: 'text',\n value: title,\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'duration',\n },\n children: [\n {\n type: 'element',\n tagName: 'strong',\n children: [\n {\n type: 'text',\n value: 'Duration',\n },\n ],\n },\n {\n type: 'text',\n value: formatDuration(attributes?.duration || ''),\n },\n ],\n },\n ],\n },\n {\n type: 'element',\n tagName: 'span',\n properties: {\n className: 'thumbnail',\n },\n children: [\n {\n type: 'element',\n tagName: 'img',\n properties: {\n src: getYoutubeThumbnailUrl(attributes?.id || ''),\n alt: '',\n },\n children: [],\n },\n ],\n },\n ],\n };\n }\n });\n };\n}\n\nfunction getTitle(node: LeafDirective, file: VFile) {\n const children = node.children as Node[];\n const firstChild = children[0] as Literal;\n const title = firstChild?.value || '';\n if (title.trim() === '') {\n failMessage(file, 'Video has no title', node.position);\n }\n return title;\n}\n\nfunction getYoutubeUrl(id: string) {\n return `https://youtu.be/${id}`;\n}\n\nfunction getYoutubeThumbnailUrl(id: string) {\n return `http://img.youtube.com/vi/${id}/mqdefault.jpg`;\n}\n\nfunction formatDuration(duration: string = '') {\n const match = duration.match(/^(\\d+)m(\\d+)s$/);\n if (match === null) {\n return '';\n }\n return `${match[1]}:${match[2].padStart(2, '0')}`;\n}\n","import puppeteer from 'puppeteer';\n\n// const footerTemplate = `\n//
\n// Page of \n//
\n// `;\n\nexport async function convertToPdf(html: string) {\n const browser = await puppeteer.launch({\n headless: true,\n args: [\n // attempted fix for windows https://stackoverflow.com/questions/59979188#66549119\n '--disable-gpu',\n '--disable-dev-shm-usage',\n '--disable-setuid-sandbox',\n '--no-first-run',\n '--no-sandbox',\n '--no-zygote',\n ],\n });\n const page = await browser.newPage();\n page.setDefaultNavigationTimeout(0);\n await page.setContent(html);\n await page.evaluateHandle('document.fonts.ready');\n const pdf = await page.pdf({\n format: 'a4',\n printBackground: true,\n // displayHeaderFooter: true,\n // footerTemplate,\n margin: {\n top: '20px',\n left: '40px',\n right: '40px',\n bottom: '40px',\n },\n });\n await browser.close();\n return pdf;\n}\n","export function allowNoWhitespaceBeforeHeading(contents: string) {\n return contents\n .split('\\n')\n .map((line) => {\n const match = line.match(/^(#+)(\\w)(.*?)$/);\n if (match !== null) {\n return `${match[1]} ${match[2]}${match[3]}`;\n }\n return line;\n })\n .join('\\n');\n}\n","const blockList = ['\\\\newpage', '\\\\pagebreak'];\n\nexport function convertNewPageToDirective(contents: string) {\n return contents\n .split('\\n')\n .map((a) => (blockList.some((b) => a.includes(b)) ? '::pagebreak' : a))\n .join('\\n');\n}\n\nexport function convertEmptyMBoxToDirective(contents: string) {\n return contents\n .split('\\n')\n .map((line) => {\n if (\n line.includes('\\\\mbox') &&\n line.replace('{', '').replace('}', '').trim() === '\\\\mbox'\n ) {\n return '::pagebreak';\n }\n return line;\n })\n .join('\\n');\n}\n","export function convertTextBfToMd(contents: string) {\n const pattern = /\\\\textbf\\{(.*?)\\}/g;\n return contents.replace(pattern, (_, str) => `**${str}**`);\n}\n\nexport function convertUrlToMd(contents: string) {\n const pattern = /\\\\url\\{(.*?)\\}/g;\n return contents.replace(pattern, (_, str) => str);\n}\n","export function convertMacroToDirective(contents: string) {\n return contents\n .split('\\n')\n .map((line) => {\n const container = parseCustomContainer(line);\n if (container !== null) {\n return renderContainerDirective(container);\n }\n return line;\n })\n .join('\\n');\n}\n\ntype Container = {\n name: string;\n title: string;\n attributes: string;\n};\n\nfunction parseCustomContainer(line: string): Container | null {\n const match = line.match(/^#{1,6}\\s*\\[(\\D.+)](.*)/);\n if (!Array.isArray(match)) {\n return null;\n }\n const [, attributeStr = '', extra = ''] = match;\n const [name, ...attributesArr] = attributeStr\n .split(',')\n .map((s) => s.trim());\n const title = extra.trim();\n const attributes = transformAttributes(name, attributesArr);\n return { name, title, attributes };\n}\n\nfunction renderContainerDirective({ name, title, attributes }: Container) {\n const colons = getColons(name);\n if (name.startsWith('/')) {\n return colons;\n }\n const newTitle = title ? `[${title}]` : '';\n const newAttributes = attributes ? `{${attributes}}` : '';\n return colons + name + newTitle + newAttributes;\n}\n\nfunction getColons(name: string) {\n switch (name.replace('/', '')) {\n case 'task':\n case 'columns':\n return '::::';\n case 'video':\n return '::';\n default:\n return ':::';\n }\n}\n\nfunction transformAttributes(\n containerName: string,\n attributesArr: string[]\n) {\n return attributesArr\n .map((attribute) => {\n const [key, value] = attribute.split('=').map((s) => s.trim());\n if (containerName === 'video' && key === 'videoid') {\n return `id=${value}`;\n }\n return attribute;\n })\n .join(' ');\n}\n","import { VFile } from 'vfile';\n\nimport { allowNoWhitespaceBeforeHeading } from './allow-no-whitespace-before-heading';\nimport {\n convertEmptyMBoxToDirective,\n convertNewPageToDirective,\n} from './convert-block-tex';\nimport { convertTextBfToMd, convertUrlToMd } from './convert-inline-tex';\nimport { convertMacroToDirective } from './convert-macro-to-directive';\nimport { reformatPandocSimpleTables } from './reformat-pandoc-simple-tables';\n\n// Some of the original coursework syntax can't easily be parsed by\n// existing plugins for unified.js, so in a \"pre-parse\" phase\n// I transform some syntax using regex so it can be parsed.\n// A successful generic approach I found is to convert problem syntax to a\n// custom markdown directive: https://github.com/remarkjs/remark-directive\n\nexport function preParsePhase(file: VFile) {\n let result = file.value as string;\n result = removeCommentedSections(result);\n result = escapeDollarsInCodeBlocks(result);\n result = allowNoWhitespaceBeforeHeading(result);\n result = convertMacroToDirective(result);\n result = convertTextBfToMd(result);\n result = convertUrlToMd(result);\n result = convertNewPageToDirective(result);\n result = convertEmptyMBoxToDirective(result);\n result = reformatPandocSimpleTables(result);\n file.value = result;\n return file;\n}\n\nfunction removeCommentedSections(md: string) {\n return md.replace(//g, '').replace(/\\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n \\n \\n \\n \\n \\n\\n\";","export default \"\\n \\n \\n\\n\";","export default \"\\n \\n\\n\";","module.exports = import(\"@double-great/remark-lint-alt-text\");;","module.exports = import(\"@mapbox/remark-lint-link-text\");;","module.exports = import(\"base64-arraybuffer\");;","module.exports = import(\"chalk\");;","module.exports = import(\"dictionary-en-gb\");;","module.exports = import(\"figures\");;","module.exports = import(\"hash-sum\");;","module.exports = import(\"image-size\");;","module.exports = import(\"js-yaml\");;","module.exports = import(\"lodash/cloneDeep.js\");;","module.exports = import(\"lodash/kebabCase.js\");;","module.exports = import(\"lodash/startCase.js\");;","module.exports = import(\"markdown-table\");;","module.exports = import(\"mathjax-full/js/adaptors/liteAdaptor.js\");;","module.exports = import(\"mathjax-full/js/core/MathItem.js\");;","module.exports = import(\"mathjax-full/js/core/MmlTree/SerializedMmlVisitor.js\");;","module.exports = import(\"mathjax-full/js/handlers/html.js\");;","module.exports = import(\"mathjax-full/js/handlers/html/HTMLDocument.js\");;","module.exports = import(\"mathjax-full/js/input/mathml.js\");;","module.exports = import(\"mathjax-full/js/input/tex.js\");;","module.exports = import(\"mathjax-full/js/input/tex/AllPackages.js\");;","module.exports = import(\"mathjax-full/js/mathjax.js\");;","module.exports = import(\"mathjax-full/js/output/svg.js\");;","module.exports = import(\"mdast-util-toc\");;","module.exports = import(\"mime/lite.js\");;","module.exports = import(\"node-fetch\");;","module.exports = import(\"puppeteer\");;","module.exports = import(\"refractor\");;","module.exports = import(\"rehype-document\");;","module.exports = import(\"rehype-format\");;","module.exports = import(\"rehype-parse\");;","module.exports = import(\"rehype-raw\");;","module.exports = import(\"rehype-stringify\");;","module.exports = import(\"remark-autolink-headings\");;","module.exports = import(\"remark-directive\");;","module.exports = import(\"remark-footnotes\");;","module.exports = import(\"remark-frontmatter\");;","module.exports = import(\"remark-gfm\");;","module.exports = import(\"remark-parse\");;","module.exports = import(\"remark-rehype\");;","module.exports = import(\"remark-retext\");;","module.exports = import(\"remark-slug\");;","module.exports = import(\"retext-english\");;","module.exports = import(\"retext-spell\");;","module.exports = import(\"speech-rule-engine\");;","module.exports = import(\"to-vfile\");;","module.exports = import(\"unist-util-visit\");;","module.exports = import(\"yargs\");;","module.exports = import(\"yup\");;","module.exports = require(\"child_process\");","module.exports = require(\"fs\");","module.exports = require(\"os\");","module.exports = require(\"path\");","module.exports = require(\"url\");","/**\n * @typedef {import('mdast').Root|import('mdast').Content} Node\n * @typedef {import('mdast').Definition} Definition\n * @typedef {import('unist-util-visit').Visitor} DefinitionVisitor\n */\n\nimport {visit} from 'unist-util-visit'\n\nconst own = {}.hasOwnProperty\n\n/**\n *\n * @param {Node} node\n */\nexport function definitions(node) {\n /** @type {Object.} */\n const cache = Object.create(null)\n\n if (!node || !node.type) {\n throw new Error('mdast-util-definitions expected node')\n }\n\n visit(node, 'definition', ondefinition)\n\n return getDefinition\n\n /** @type {DefinitionVisitor} */\n function ondefinition(definition) {\n const id = clean(definition.identifier)\n if (id && !own.call(cache, id)) {\n cache[id] = definition\n }\n }\n\n /**\n * Get a node from the bound definition-cache.\n *\n * @param {string} identifier\n * @returns {Definition|null}\n */\n function getDefinition(identifier) {\n const id = clean(identifier)\n return id && own.call(cache, id) ? cache[id] : null\n }\n}\n\n/**\n * @param {string} [value]\n * @returns {string}\n */\nfunction clean(value) {\n return String(value || '').toUpperCase()\n}\n","/**\n * @typedef {import('mdast').BlockContent} BlockContent\n * @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').ElementContent} ElementContent\n * @typedef {import('./index.js').H} H\n */\n\nimport {sanitizeUri} from 'micromark-util-sanitize-uri'\nimport {u} from 'unist-builder'\nimport {all} from './traverse.js'\nimport {wrap} from './wrap.js'\n\n/**\n * @param {H} h\n */\nexport function footer(h) {\n let index = -1\n /** @type {Array} */\n const listItems = []\n\n while (++index < h.footnoteOrder.length) {\n const def = h.footnoteById[h.footnoteOrder[index].toUpperCase()]\n\n if (!def) {\n continue\n }\n\n const content = all(h, def)\n const id = String(def.identifier)\n const safeId = sanitizeUri(id.toLowerCase())\n let referenceIndex = 0\n /** @type {Array} */\n const backReferences = []\n\n while (++referenceIndex <= h.footnoteCounts[id]) {\n /** @type {Element} */\n const backReference = {\n type: 'element',\n tagName: 'a',\n properties: {\n href:\n '#' +\n h.clobberPrefix +\n 'fnref-' +\n safeId +\n (referenceIndex > 1 ? '-' + referenceIndex : ''),\n dataFootnoteBackref: true,\n className: ['data-footnote-backref'],\n ariaLabel: h.footnoteBackLabel\n },\n children: [{type: 'text', value: '↩'}]\n }\n\n if (referenceIndex > 1) {\n backReference.children.push({\n type: 'element',\n tagName: 'sup',\n children: [{type: 'text', value: String(referenceIndex)}]\n })\n }\n\n if (backReferences.length > 0) {\n backReferences.push({type: 'text', value: ' '})\n }\n\n backReferences.push(backReference)\n }\n\n const tail = content[content.length - 1]\n\n if (tail && tail.type === 'element' && tail.tagName === 'p') {\n const tailTail = tail.children[tail.children.length - 1]\n if (tailTail && tailTail.type === 'text') {\n tailTail.value += ' '\n } else {\n tail.children.push({type: 'text', value: ' '})\n }\n\n tail.children.push(...backReferences)\n } else {\n content.push(...backReferences)\n }\n\n /** @type {Element} */\n const listItem = {\n type: 'element',\n tagName: 'li',\n properties: {id: h.clobberPrefix + 'fn-' + safeId},\n children: wrap(content, true)\n }\n\n if (def.position) {\n listItem.position = def.position\n }\n\n listItems.push(listItem)\n }\n\n if (listItems.length === 0) {\n return null\n }\n\n return {\n type: 'element',\n tagName: 'section',\n properties: {dataFootnotes: true, className: ['footnotes']},\n children: [\n {\n type: 'element',\n tagName: 'h2',\n properties: {id: 'footnote-label', className: ['sr-only']},\n children: [u('text', h.footnoteLabel)]\n },\n {type: 'text', value: '\\n'},\n {\n type: 'element',\n tagName: 'ol',\n properties: {},\n children: wrap(listItems, true)\n },\n {type: 'text', value: '\\n'}\n ]\n }\n}\n","/**\n * @typedef {import('mdast').Blockquote} Blockquote\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {wrap} from '../wrap.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Blockquote} node\n */\nexport function blockquote(h, node) {\n return h(node, 'blockquote', wrap(all(h, node), true))\n}\n","/**\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Text} Text\n * @typedef {import('mdast').Break} Break\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {Break} node\n * @returns {Array}\n */\nexport function hardBreak(h, node) {\n return [h(node, 'br'), u('text', '\\n')]\n}\n","/**\n * @typedef {import('mdast').Code} Code\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {Code} node\n */\nexport function code(h, node) {\n const value = node.value ? node.value + '\\n' : ''\n // To do: next major, use `node.lang` w/o regex, the splitting’s been going\n // on for years in remark now.\n const lang = node.lang && node.lang.match(/^[^ \\t]+(?=[ \\t]|$)/)\n /** @type {Properties} */\n const props = {}\n\n if (lang) {\n props.className = ['language-' + lang]\n }\n\n const code = h(node, 'code', props, [u('text', value)])\n\n if (node.meta) {\n code.data = {meta: node.meta}\n }\n\n return h(node.position, 'pre', [code])\n}\n","/**\n * @typedef {import('mdast').Delete} Delete\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Delete} node\n */\nexport function strikethrough(h, node) {\n return h(node, 'del', all(h, node))\n}\n","/**\n * @typedef {import('mdast').Emphasis} Emphasis\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Emphasis} node\n */\nexport function emphasis(h, node) {\n return h(node, 'em', all(h, node))\n}\n","/**\n * @typedef {import('mdast').FootnoteReference} FootnoteReference\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {sanitizeUri} from 'micromark-util-sanitize-uri'\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {FootnoteReference} node\n */\nexport function footnoteReference(h, node) {\n const id = String(node.identifier)\n const safeId = sanitizeUri(id.toLowerCase())\n const index = h.footnoteOrder.indexOf(id)\n /** @type {number} */\n let counter\n\n if (index === -1) {\n h.footnoteOrder.push(id)\n h.footnoteCounts[id] = 1\n counter = h.footnoteOrder.length\n } else {\n h.footnoteCounts[id]++\n counter = index + 1\n }\n\n const reuseCounter = h.footnoteCounts[id]\n\n return h(node, 'sup', [\n h(\n node.position,\n 'a',\n {\n href: '#' + h.clobberPrefix + 'fn-' + safeId,\n id:\n h.clobberPrefix +\n 'fnref-' +\n safeId +\n (reuseCounter > 1 ? '-' + reuseCounter : ''),\n dataFootnoteRef: true,\n ariaDescribedBy: 'footnote-label'\n },\n [u('text', String(counter))]\n )\n ])\n}\n","/**\n * @typedef {import('mdast').Footnote} Footnote\n * @typedef {import('../index.js').Handler} Handler\n *\n * @todo\n * `footnote` (or “inline note”) are a pandoc footnotes feature (`^[a note]`)\n * that does not exist in GFM.\n * We still have support for it, so that things remain working with\n * `micromark-extension-footnote` and `mdast-util-footnote`, but in the future\n * we might be able to remove it?\n */\n\nimport {footnoteReference} from './footnote-reference.js'\n\n/**\n * @type {Handler}\n * @param {Footnote} node\n */\nexport function footnote(h, node) {\n const footnoteById = h.footnoteById\n let no = 1\n\n while (no in footnoteById) no++\n\n const identifier = String(no)\n\n footnoteById[identifier] = {\n type: 'footnoteDefinition',\n identifier,\n children: [{type: 'paragraph', children: node.children}],\n position: node.position\n }\n\n return footnoteReference(h, {\n type: 'footnoteReference',\n identifier,\n position: node.position\n })\n}\n","/**\n * @typedef {import('mdast').Heading} Heading\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Heading} node\n */\nexport function heading(h, node) {\n return h(node, 'h' + node.depth, all(h, node))\n}\n","/**\n * @typedef {import('mdast').HTML} HTML\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * Return either a `raw` node in dangerous mode, otherwise nothing.\n *\n * @type {Handler}\n * @param {HTML} node\n */\nexport function html(h, node) {\n return h.dangerous ? h.augment(node, u('raw', node.value)) : null\n}\n","/**\n * @typedef {import('mdast').LinkReference} LinkReference\n * @typedef {import('mdast').ImageReference} ImageReference\n * @typedef {import('./index.js').Handler} Handler\n * @typedef {import('./index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\nimport {all} from './traverse.js'\n\n/**\n * Return the content of a reference without definition as plain text.\n *\n * @type {Handler}\n * @param {ImageReference|LinkReference} node\n * @returns {Content|Array}\n */\nexport function revert(h, node) {\n const subtype = node.referenceType\n let suffix = ']'\n\n if (subtype === 'collapsed') {\n suffix += '[]'\n } else if (subtype === 'full') {\n suffix += '[' + (node.label || node.identifier) + ']'\n }\n\n if (node.type === 'imageReference') {\n return u('text', '![' + node.alt + suffix)\n }\n\n const contents = all(h, node)\n const head = contents[0]\n\n if (head && head.type === 'text') {\n head.value = '[' + head.value\n } else {\n contents.unshift(u('text', '['))\n }\n\n const tail = contents[contents.length - 1]\n\n if (tail && tail.type === 'text') {\n tail.value += suffix\n } else {\n contents.push(u('text', suffix))\n }\n\n return contents\n}\n","/**\n * @typedef {import('mdast').ImageReference} ImageReference\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\nimport {revert} from '../revert.js'\n\n/**\n * @type {Handler}\n * @param {ImageReference} node\n */\nexport function imageReference(h, node) {\n const def = h.definition(node.identifier)\n\n if (!def) {\n return revert(h, node)\n }\n\n /** @type {Properties} */\n const props = {src: normalize(def.url || ''), alt: node.alt}\n\n if (def.title !== null && def.title !== undefined) {\n props.title = def.title\n }\n\n return h(node, 'img', props)\n}\n","/**\n * @typedef {import('mdast').Image} Image\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\n\n/**\n * @type {Handler}\n * @param {Image} node\n */\nexport function image(h, node) {\n /** @type {Properties} */\n const props = {src: normalize(node.url), alt: node.alt}\n\n if (node.title !== null && node.title !== undefined) {\n props.title = node.title\n }\n\n return h(node, 'img', props)\n}\n","/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {InlineCode} node\n */\nexport function inlineCode(h, node) {\n return h(node, 'code', [u('text', node.value.replace(/\\r?\\n|\\r/g, ' '))])\n}\n","/**\n * @typedef {import('mdast').LinkReference} LinkReference\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\nimport {revert} from '../revert.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {LinkReference} node\n */\nexport function linkReference(h, node) {\n const def = h.definition(node.identifier)\n\n if (!def) {\n return revert(h, node)\n }\n\n /** @type {Properties} */\n const props = {href: normalize(def.url || '')}\n\n if (def.title !== null && def.title !== undefined) {\n props.title = def.title\n }\n\n return h(node, 'a', props, all(h, node))\n}\n","/**\n * @typedef {import('mdast').Link} Link\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport normalize from 'mdurl/encode.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Link} node\n */\nexport function link(h, node) {\n /** @type {Properties} */\n const props = {href: normalize(node.url)}\n\n if (node.title !== null && node.title !== undefined) {\n props.title = node.title\n }\n\n return h(node, 'a', props, all(h, node))\n}\n","/**\n * @typedef {import('mdast').ListItem} ListItem\n * @typedef {import('mdast').List} List\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('hast').Element} Element\n * @typedef {import('../index.js').Handler} Handler\n * @typedef {import('../index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {ListItem} node\n * @param {List} parent\n */\nexport function listItem(h, node, parent) {\n const result = all(h, node)\n const loose = parent ? listLoose(parent) : listItemLoose(node)\n /** @type {Properties} */\n const props = {}\n /** @type {Array} */\n const wrapped = []\n\n if (typeof node.checked === 'boolean') {\n /** @type {Element} */\n let paragraph\n\n if (\n result[0] &&\n result[0].type === 'element' &&\n result[0].tagName === 'p'\n ) {\n paragraph = result[0]\n } else {\n paragraph = h(null, 'p', [])\n result.unshift(paragraph)\n }\n\n if (paragraph.children.length > 0) {\n paragraph.children.unshift(u('text', ' '))\n }\n\n paragraph.children.unshift(\n h(null, 'input', {\n type: 'checkbox',\n checked: node.checked,\n disabled: true\n })\n )\n\n // According to github-markdown-css, this class hides bullet.\n // See: .\n props.className = ['task-list-item']\n }\n\n let index = -1\n\n while (++index < result.length) {\n const child = result[index]\n\n // Add eols before nodes, except if this is a loose, first paragraph.\n if (\n loose ||\n index !== 0 ||\n child.type !== 'element' ||\n child.tagName !== 'p'\n ) {\n wrapped.push(u('text', '\\n'))\n }\n\n if (child.type === 'element' && child.tagName === 'p' && !loose) {\n wrapped.push(...child.children)\n } else {\n wrapped.push(child)\n }\n }\n\n const tail = result[result.length - 1]\n\n // Add a final eol.\n if (tail && (loose || !('tagName' in tail) || tail.tagName !== 'p')) {\n wrapped.push(u('text', '\\n'))\n }\n\n return h(node, 'li', props, wrapped)\n}\n\n/**\n * @param {List} node\n * @return {Boolean}\n */\nfunction listLoose(node) {\n let loose = node.spread\n const children = node.children\n let index = -1\n\n while (!loose && ++index < children.length) {\n loose = listItemLoose(children[index])\n }\n\n return Boolean(loose)\n}\n\n/**\n * @param {ListItem} node\n * @return {Boolean}\n */\nfunction listItemLoose(node) {\n const spread = node.spread\n\n return spread === undefined || spread === null\n ? node.children.length > 1\n : spread\n}\n","/**\n * @typedef {import('mdast').List} List\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {wrap} from '../wrap.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {List} node\n * @returns {Element}\n */\nexport function list(h, node) {\n /** @type {Properties} */\n const props = {}\n const name = node.ordered ? 'ol' : 'ul'\n const items = all(h, node)\n let index = -1\n\n if (typeof node.start === 'number' && node.start !== 1) {\n props.start = node.start\n }\n\n // Like GitHub, add a class for custom styling.\n while (++index < items.length) {\n const item = items[index]\n\n if (\n item.type === 'element' &&\n item.tagName === 'li' &&\n item.properties &&\n Array.isArray(item.properties.className) &&\n item.properties.className.includes('task-list-item')\n ) {\n props.className = ['contains-task-list']\n break\n }\n }\n\n return h(node, name, props, wrap(items, true))\n}\n","/**\n * @typedef {import('mdast').Paragraph} Paragraph\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Paragraph} node\n */\nexport function paragraph(h, node) {\n return h(node, 'p', all(h, node))\n}\n","/**\n * @typedef {import('mdast').Root} Root\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\nimport {all} from '../traverse.js'\nimport {wrap} from '../wrap.js'\n\n/**\n * @type {Handler}\n * @param {Root} node\n */\nexport function root(h, node) {\n // @ts-expect-error `root`s are also fine.\n return h.augment(node, u('root', wrap(all(h, node))))\n}\n","/**\n * @typedef {import('mdast').Strong} Strong\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Strong} node\n */\nexport function strong(h, node) {\n return h(node, 'strong', all(h, node))\n}\n","/**\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('hast').Element} Element\n * @typedef {import('../index.js').Handler} Handler\n * @typedef {import('../index.js').Content} Content\n */\n\nimport {pointStart, pointEnd} from 'unist-util-position'\nimport {wrap} from '../wrap.js'\nimport {all} from '../traverse.js'\n\n/**\n * @type {Handler}\n * @param {Table} node\n */\nexport function table(h, node) {\n const rows = node.children\n let index = -1\n const align = node.align || []\n /** @type {Array} */\n const result = []\n\n while (++index < rows.length) {\n const row = rows[index].children\n const name = index === 0 ? 'th' : 'td'\n /** @type {Array} */\n const out = []\n let cellIndex = -1\n const length = node.align ? align.length : row.length\n\n while (++cellIndex < length) {\n const cell = row[cellIndex]\n out.push(\n h(cell, name, {align: align[cellIndex]}, cell ? all(h, cell) : [])\n )\n }\n\n result[index] = h(rows[index], 'tr', wrap(out, true))\n }\n\n return h(\n node,\n 'table',\n wrap(\n [h(result[0].position, 'thead', wrap([result[0]], true))].concat(\n result[1]\n ? h(\n {\n start: pointStart(result[1]),\n end: pointEnd(result[result.length - 1])\n },\n 'tbody',\n wrap(result.slice(1), true)\n )\n : []\n ),\n true\n )\n )\n}\n","/**\n * @typedef {import('mdast').Text} Text\n * @typedef {import('../index.js').Handler} Handler\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * @type {Handler}\n * @param {Text} node\n */\nexport function text(h, node) {\n return h.augment(\n node,\n u('text', String(node.value).replace(/[ \\t]*(\\r?\\n|\\r)[ \\t]*/g, '$1'))\n )\n}\n","/**\n * @typedef {import('mdast').ThematicBreak} ThematicBreak\n * @typedef {import('hast').Element} Element\n * @typedef {import('../index.js').Handler} Handler\n */\n\n/**\n * @type {Handler}\n * @param {ThematicBreak} [node]\n * @returns {Element}\n */\nexport function thematicBreak(h, node) {\n return h(node, 'hr')\n}\n","import {blockquote} from './blockquote.js'\nimport {hardBreak} from './break.js'\nimport {code} from './code.js'\nimport {strikethrough} from './delete.js'\nimport {emphasis} from './emphasis.js'\nimport {footnoteReference} from './footnote-reference.js'\nimport {footnote} from './footnote.js'\nimport {heading} from './heading.js'\nimport {html} from './html.js'\nimport {imageReference} from './image-reference.js'\nimport {image} from './image.js'\nimport {inlineCode} from './inline-code.js'\nimport {linkReference} from './link-reference.js'\nimport {link} from './link.js'\nimport {listItem} from './list-item.js'\nimport {list} from './list.js'\nimport {paragraph} from './paragraph.js'\nimport {root} from './root.js'\nimport {strong} from './strong.js'\nimport {table} from './table.js'\nimport {text} from './text.js'\nimport {thematicBreak} from './thematic-break.js'\n\nexport const handlers = {\n blockquote,\n break: hardBreak,\n code,\n delete: strikethrough,\n emphasis,\n footnoteReference,\n footnote,\n heading,\n html,\n imageReference,\n image,\n inlineCode,\n linkReference,\n link,\n listItem,\n list,\n paragraph,\n root,\n strong,\n table,\n text,\n thematicBreak,\n toml: ignore,\n yaml: ignore,\n definition: ignore,\n footnoteDefinition: ignore\n}\n\n// Return nothing for nodes that are ignored.\nfunction ignore() {\n return null\n}\n","/**\n * @typedef {import('mdast').Root|import('mdast').Parent['children'][number]} MdastNode\n * @typedef {import('hast').Root|import('hast').Parent['children'][number]} HastNode\n * @typedef {import('mdast').Parent} Parent\n * @typedef {import('mdast').Definition} Definition\n * @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition\n * @typedef {import('hast').Properties} Properties\n * @typedef {import('hast').Text} Text\n * @typedef {import('hast').Comment} Comment\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').Root} Root\n * @typedef {import('hast').ElementContent} Content\n * @typedef {import('unist-util-position').PositionLike} PositionLike\n *\n * @typedef EmbeddedHastFields\n * @property {string} [hName] Defines the tag name of an element\n * @property {Properties} [hProperties] Defines the properties of an element\n * @property {Array} [hChildren] Defines the (hast) children of an element\n *\n * @typedef {Record & EmbeddedHastFields} Data unist data with embedded hast fields\n *\n * @typedef {MdastNode & {data?: Data}} NodeWithData unist node with embedded hast data\n *\n * @callback Handler\n * @param {H} h Handle context\n * @param {any} node mdast node to handle\n * @param {Parent|null} parent Parent of `node`\n * @returns {Content|Array|null|undefined} hast node\n *\n * @callback HFunctionProps\n * @param {MdastNode|PositionLike|null|undefined} node mdast node or unist position\n * @param {string} tagName HTML tag name\n * @param {Properties} props Properties\n * @param {Array?} [children] hast content\n * @returns {Element}\n *\n * @callback HFunctionNoProps\n * @param {MdastNode|PositionLike|null|undefined} node mdast node or unist position\n * @param {string} tagName HTML tag name\n * @param {Array?} [children] hast content\n * @returns {Element}\n *\n * @typedef HFields\n * @property {boolean} dangerous Whether HTML is allowed\n * @property {string} clobberPrefix Prefix to use to prevent DOM clobbering\n * @property {string} footnoteLabel Label to use to introduce the footnote section\n * @property {string} footnoteBackLabel Label to use to go back to a footnote call from the footnote section\n * @property {(identifier: string) => Definition|null} definition Definition cache\n * @property {Record} footnoteById Footnote cache\n * @property {Array} footnoteOrder Order in which footnotes occur\n * @property {Record} footnoteCounts Counts the same footnote was used\n * @property {Handlers} handlers Applied handlers\n * @property {Handler} unknownHandler Handler for any none not in `passThrough` or otherwise handled\n * @property {(left: NodeWithData|PositionLike|null|undefined, right: Content) => Content} augment Like `h` but lower-level and usable on non-elements.\n * @property {Array} passThrough List of node types to pass through untouched (except for their children).\n *\n * @typedef Options\n * @property {boolean} [allowDangerousHtml=false]\n * Whether to allow `html` nodes and inject them as `raw` HTML\n * @property {string} [clobberPrefix='user-content-']\n * Prefix to use before the `id` attribute to prevent it from *clobbering*.\n * attributes.\n * DOM clobbering is this:\n *\n * ```html\n *

\n * \n * ```\n *\n * Elements by their ID are made available in browsers on the `window` object.\n * Using a prefix prevents this from being a problem.\n * @property {string} [footnoteLabel='Footnotes']\n * Label to use for the footnotes section.\n * Affects screen reader users.\n * Change it if you’re authoring in a different language.\n * @property {string} [footnoteBackLabel='Back to content']\n * Label to use from backreferences back to their footnote call.\n * Affects screen reader users.\n * Change it if you’re authoring in a different language.\n * @property {Handlers} [handlers]\n * Object mapping mdast nodes to functions handling them\n * @property {Array} [passThrough]\n * List of custom mdast node types to pass through (keep) in hast\n * @property {Handler} [unknownHandler]\n * Handler for all unknown nodes.\n *\n * @typedef {Record} Handlers\n * Map of node types to handlers\n * @typedef {HFunctionProps & HFunctionNoProps & HFields} H\n * Handle context\n */\n\nimport {u} from 'unist-builder'\nimport {visit} from 'unist-util-visit'\nimport {pointStart, pointEnd} from 'unist-util-position'\nimport {generated} from 'unist-util-generated'\nimport {definitions} from 'mdast-util-definitions'\nimport {one} from './traverse.js'\nimport {footer} from './footer.js'\nimport {handlers} from './handlers/index.js'\n\nconst own = {}.hasOwnProperty\n\n/**\n * Factory to transform.\n * @param {MdastNode} tree mdast node\n * @param {Options} [options] Configuration\n * @returns {H} `h` function\n */\nfunction factory(tree, options) {\n const settings = options || {}\n const dangerous = settings.allowDangerousHtml || false\n /** @type {Record} */\n const footnoteById = {}\n\n h.dangerous = dangerous\n h.clobberPrefix =\n settings.clobberPrefix === undefined || settings.clobberPrefix === null\n ? 'user-content-'\n : settings.clobberPrefix\n h.footnoteLabel = settings.footnoteLabel || 'Footnotes'\n h.footnoteBackLabel = settings.footnoteBackLabel || 'Back to content'\n h.definition = definitions(tree)\n h.footnoteById = footnoteById\n /** @type {Array} */\n h.footnoteOrder = []\n /** @type {Record} */\n h.footnoteCounts = {}\n h.augment = augment\n h.handlers = {...handlers, ...settings.handlers}\n h.unknownHandler = settings.unknownHandler\n h.passThrough = settings.passThrough\n\n visit(tree, 'footnoteDefinition', (definition) => {\n const id = String(definition.identifier).toUpperCase()\n\n // Mimick CM behavior of link definitions.\n // See: .\n if (!own.call(footnoteById, id)) {\n footnoteById[id] = definition\n }\n })\n\n // @ts-expect-error Hush, it’s fine!\n return h\n\n /**\n * Finalise the created `right`, a hast node, from `left`, an mdast node.\n * @param {(NodeWithData|PositionLike)?} left\n * @param {Content} right\n * @returns {Content}\n */\n function augment(left, right) {\n // Handle `data.hName`, `data.hProperties, `data.hChildren`.\n if (left && 'data' in left && left.data) {\n /** @type {Data} */\n const data = left.data\n\n if (data.hName) {\n if (right.type !== 'element') {\n right = {\n type: 'element',\n tagName: '',\n properties: {},\n children: []\n }\n }\n\n right.tagName = data.hName\n }\n\n if (right.type === 'element' && data.hProperties) {\n right.properties = {...right.properties, ...data.hProperties}\n }\n\n if ('children' in right && right.children && data.hChildren) {\n right.children = data.hChildren\n }\n }\n\n if (left) {\n const ctx = 'type' in left ? left : {position: left}\n\n if (!generated(ctx)) {\n right.position = {start: pointStart(ctx), end: pointEnd(ctx)}\n }\n }\n\n return right\n }\n\n /**\n * Create an element for `node`.\n *\n * @type {HFunctionProps}\n */\n function h(node, tagName, props, children) {\n if (Array.isArray(props)) {\n children = props\n props = {}\n }\n\n // @ts-expect-error augmenting an element yields an element.\n return augment(node, {\n type: 'element',\n tagName,\n properties: props || {},\n children: children || []\n })\n }\n}\n\n/**\n * Transform `tree` (an mdast node) to a hast node.\n *\n * @param {MdastNode} tree mdast node\n * @param {Options} [options] Configuration\n * @returns {HastNode|null|undefined} hast node\n */\nexport function toHast(tree, options) {\n const h = factory(tree, options)\n const node = one(h, tree, null)\n const foot = footer(h)\n\n if (foot) {\n // @ts-expect-error If there’s a footer, there were definitions, meaning block\n // content.\n // So assume `node` is a parent node.\n node.children.push(u('text', '\\n'), foot)\n }\n\n return Array.isArray(node) ? {type: 'root', children: node} : node\n}\n\nexport {handlers as defaultHandlers} from './handlers/index.js'\n","/**\n * @typedef {import('mdast').Root|import('mdast').Parent['children'][number]} MdastNode\n * @typedef {import('./index.js').H} H\n * @typedef {import('./index.js').Handler} Handler\n * @typedef {import('./index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\n\nconst own = {}.hasOwnProperty\n\n/**\n * Transform an unknown node.\n * @type {Handler}\n * @param {MdastNode} node\n */\nfunction unknown(h, node) {\n const data = node.data || {}\n\n if (\n 'value' in node &&\n !(\n own.call(data, 'hName') ||\n own.call(data, 'hProperties') ||\n own.call(data, 'hChildren')\n )\n ) {\n return h.augment(node, u('text', node.value))\n }\n\n return h(node, 'div', all(h, node))\n}\n\n/**\n * @type {Handler}\n * @param {MdastNode} node\n */\nexport function one(h, node, parent) {\n const type = node && node.type\n /** @type {Handler} */\n let fn\n\n // Fail on non-nodes.\n if (!type) {\n throw new Error('Expected node, got `' + node + '`')\n }\n\n if (own.call(h.handlers, type)) {\n fn = h.handlers[type]\n } else if (h.passThrough && h.passThrough.includes(type)) {\n fn = returnNode\n } else {\n fn = h.unknownHandler\n }\n\n return (typeof fn === 'function' ? fn : unknown)(h, node, parent)\n}\n\n/**\n * @type {Handler}\n * @param {MdastNode} node\n */\nfunction returnNode(h, node) {\n // @ts-expect-error: Pass through custom node.\n return 'children' in node ? {...node, children: all(h, node)} : node\n}\n\n/**\n * @param {H} h\n * @param {MdastNode} parent\n */\nexport function all(h, parent) {\n /** @type {Array} */\n const values = []\n\n if ('children' in parent) {\n const nodes = parent.children\n let index = -1\n\n while (++index < nodes.length) {\n const result = one(h, nodes[index], parent)\n\n if (result) {\n if (index && nodes[index - 1].type === 'break') {\n if (!Array.isArray(result) && result.type === 'text') {\n result.value = result.value.replace(/^\\s+/, '')\n }\n\n if (!Array.isArray(result) && result.type === 'element') {\n const head = result.children[0]\n\n if (head && head.type === 'text') {\n head.value = head.value.replace(/^\\s+/, '')\n }\n }\n }\n\n if (Array.isArray(result)) {\n values.push(...result)\n } else {\n values.push(result)\n }\n }\n }\n }\n\n return values\n}\n","/**\n * @typedef {import('./index.js').Content} Content\n */\n\nimport {u} from 'unist-builder'\n\n/**\n * Wrap `nodes` with line feeds between each entry.\n * Optionally adds line feeds at the start and end.\n *\n * @param {Array} nodes\n * @param {boolean} [loose=false]\n * @returns {Array}\n */\nexport function wrap(nodes, loose) {\n /** @type {Array} */\n const result = []\n let index = -1\n\n if (loose) {\n result.push(u('text', '\\n'))\n }\n\n while (++index < nodes.length) {\n if (index) result.push(u('text', '\\n'))\n result.push(nodes[index])\n }\n\n if (loose && nodes.length > 0) {\n result.push(u('text', '\\n'))\n }\n\n return result\n}\n","// This module is generated by `script/`.\n//\n// CommonMark handles attention (emphasis, strong) markers based on what comes\n// before or after them.\n// One such difference is if those characters are Unicode punctuation.\n// This script is generated from the Unicode data.\nexport const unicodePunctuationRegex =\n /[!-/:-@[-`{-~\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\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\\u1B5A-\\u1B60\\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\\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]/\n","/**\n * @typedef {import('micromark-util-types').Code} Code\n */\nimport {unicodePunctuationRegex} from './lib/unicode-punctuation-regex.js'\n/**\n * Check whether the character code represents an ASCII alpha (`a` through `z`,\n * case insensitive).\n *\n * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha.\n *\n * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`)\n * to U+005A (`Z`).\n *\n * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`)\n * to U+007A (`z`).\n */\n\nexport const asciiAlpha = regexCheck(/[A-Za-z]/)\n/**\n * Check whether the character code represents an ASCII digit (`0` through `9`).\n *\n * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to\n * U+0039 (`9`).\n */\n\nexport const asciiDigit = regexCheck(/\\d/)\n/**\n * Check whether the character code represents an ASCII hex digit (`a` through\n * `f`, case insensitive, or `0` through `9`).\n *\n * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex\n * digit, or an ASCII lower hex digit.\n *\n * An **ASCII upper hex digit** is a character in the inclusive range U+0041\n * (`A`) to U+0046 (`F`).\n *\n * An **ASCII lower hex digit** is a character in the inclusive range U+0061\n * (`a`) to U+0066 (`f`).\n */\n\nexport const asciiHexDigit = regexCheck(/[\\dA-Fa-f]/)\n/**\n * Check whether the character code represents an ASCII alphanumeric (`a`\n * through `z`, case insensitive, or `0` through `9`).\n *\n * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha\n * (see `asciiAlpha`).\n */\n\nexport const asciiAlphanumeric = regexCheck(/[\\dA-Za-z]/)\n/**\n * Check whether the character code represents ASCII punctuation.\n *\n * An **ASCII punctuation** is a character in the inclusive ranges U+0021\n * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT\n * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT\n * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`).\n */\n\nexport const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/)\n/**\n * Check whether the character code represents an ASCII atext.\n *\n * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in\n * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`),\n * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F\n * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E\n * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE\n * (`{`) to U+007E TILDE (`~`).\n *\n * See:\n * **\\[RFC5322]**:\n * [Internet Message Format](https://tools.ietf.org/html/rfc5322).\n * P. Resnick.\n * IETF.\n */\n\nexport const asciiAtext = regexCheck(/[#-'*+\\--9=?A-Z^-~]/)\n/**\n * Check whether a character code is an ASCII control character.\n *\n * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL)\n * to U+001F (US), or U+007F (DEL).\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function asciiControl(code) {\n return (\n // Special whitespace codes (which have negative values), C0 and Control\n // character DEL\n code !== null && (code < 32 || code === 127)\n )\n}\n/**\n * Check whether a character code is a markdown line ending (see\n * `markdownLineEnding`) or markdown space (see `markdownSpace`).\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function markdownLineEndingOrSpace(code) {\n return code !== null && (code < 0 || code === 32)\n}\n/**\n * Check whether a character code is a markdown line ending.\n *\n * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN\n * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR).\n *\n * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE\n * RETURN (CR) are replaced by these virtual characters depending on whether\n * they occurred together.\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function markdownLineEnding(code) {\n return code !== null && code < -2\n}\n/**\n * Check whether a character code is a markdown space.\n *\n * A **markdown space** is the concrete character U+0020 SPACE (SP) and the\n * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT).\n *\n * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is\n * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL\n * SPACE (VS) characters, depending on the column at which the tab occurred.\n *\n * @param {Code} code\n * @returns {code is number}\n */\n\nexport function markdownSpace(code) {\n return code === -2 || code === -1 || code === 32\n}\n/**\n * Check whether the character code represents Unicode whitespace.\n *\n * Note that this does handle micromark specific markdown whitespace characters.\n * See `markdownLineEndingOrSpace` to check that.\n *\n * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator,\n * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF),\n * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\\[UNICODE]**).\n *\n * See:\n * **\\[UNICODE]**:\n * [The Unicode Standard](https://www.unicode.org/versions/).\n * Unicode Consortium.\n */\n\nexport const unicodeWhitespace = regexCheck(/\\s/)\n/**\n * Check whether the character code represents Unicode punctuation.\n *\n * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation,\n * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf`\n * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po`\n * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII\n * punctuation (see `asciiPunctuation`).\n *\n * See:\n * **\\[UNICODE]**:\n * [The Unicode Standard](https://www.unicode.org/versions/).\n * Unicode Consortium.\n */\n// Size note: removing ASCII from the regex and using `asciiPunctuation` here\n// In fact adds to the bundle size.\n\nexport const unicodePunctuation = regexCheck(unicodePunctuationRegex)\n/**\n * Create a code check from a regex.\n *\n * @param {RegExp} regex\n * @returns {(code: Code) => code is number}\n */\n\nfunction regexCheck(regex) {\n return check\n /**\n * Check whether a code matches the bound regex.\n *\n * @param {Code} code Character code\n * @returns {code is number} Whether the character code matches the bound regex\n */\n\n function check(code) {\n return code !== null && regex.test(String.fromCharCode(code))\n }\n}\n","const characterReferences = {'\"': 'quot', '&': 'amp', '<': 'lt', '>': 'gt'}\n\n/**\n * Encode only the dangerous HTML characters.\n *\n * This ensures that certain characters which have special meaning in HTML are\n * dealt with.\n * Technically, we can skip `>` and `\"` in many cases, but CM includes them.\n *\n * @param {string} value\n * @returns {string}\n */\nexport function encode(value) {\n return value.replace(/[\"&<>]/g, replace)\n\n /**\n * @param {string} value\n * @returns {string}\n */\n function replace(value) {\n // @ts-expect-error Hush, it’s fine.\n return '&' + characterReferences[value] + ';'\n }\n}\n","import {asciiAlphanumeric} from 'micromark-util-character'\nimport {encode} from 'micromark-util-encode'\n\n/**\n * Make a value safe for injection as a URL.\n *\n * This encodes unsafe characters with percent-encoding and skips already\n * encoded sequences (see `normalizeUri` below).\n * Further unsafe characters are encoded as character references (see\n * `micromark-util-encode`).\n *\n * Then, a regex of allowed protocols can be given, in which case the URL is\n * sanitized.\n * For example, `/^(https?|ircs?|mailto|xmpp)$/i` can be used for `a[href]`,\n * or `/^https?$/i` for `img[src]`.\n * If the URL includes an unknown protocol (one not matched by `protocol`, such\n * as a dangerous example, `javascript:`), the value is ignored.\n *\n * @param {string|undefined} url\n * @param {RegExp} [protocol]\n * @returns {string}\n */\nexport function sanitizeUri(url, protocol) {\n const value = encode(normalizeUri(url || ''))\n\n if (!protocol) {\n return value\n }\n\n const colon = value.indexOf(':')\n const questionMark = value.indexOf('?')\n const numberSign = value.indexOf('#')\n const slash = value.indexOf('/')\n\n if (\n // If there is no protocol, it’s relative.\n colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol.\n (slash > -1 && colon > slash) ||\n (questionMark > -1 && colon > questionMark) ||\n (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed.\n protocol.test(value.slice(0, colon))\n ) {\n return value\n }\n\n return ''\n}\n/**\n * Normalize a URL (such as used in definitions).\n *\n * Encode unsafe characters with percent-encoding, skipping already encoded\n * sequences.\n *\n * @param {string} value\n * @returns {string}\n */\n\nfunction normalizeUri(value) {\n /** @type {string[]} */\n const result = []\n let index = -1\n let start = 0\n let skip = 0\n\n while (++index < value.length) {\n const code = value.charCodeAt(index)\n /** @type {string} */\n\n let replace = '' // A correct percent encoded value.\n\n if (\n code === 37 &&\n asciiAlphanumeric(value.charCodeAt(index + 1)) &&\n asciiAlphanumeric(value.charCodeAt(index + 2))\n ) {\n skip = 2\n } // ASCII.\n else if (code < 128) {\n if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) {\n replace = String.fromCharCode(code)\n }\n } // Astral.\n else if (code > 55295 && code < 57344) {\n const next = value.charCodeAt(index + 1) // A correct surrogate pair.\n\n if (code < 56320 && next > 56319 && next < 57344) {\n replace = String.fromCharCode(code, next)\n skip = 1\n } // Lone surrogate.\n else {\n replace = '\\uFFFD'\n }\n } // Unicode.\n else {\n replace = String.fromCharCode(code)\n }\n\n if (replace) {\n result.push(value.slice(start, index), encodeURIComponent(replace))\n start = index + skip + 1\n replace = ''\n }\n\n if (skip) {\n index += skip\n skip = 0\n }\n }\n\n return result.join('') + value.slice(start)\n}\n","/**\n * Throw a given error.\n *\n * @param {Error|null|undefined} [error]\n * Maybe error.\n * @returns {asserts error is null|undefined}\n */\nexport function bail(error) {\n if (error) {\n throw error\n }\n}\n","export default function isPlainObject(value) {\n\tif (Object.prototype.toString.call(value) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === null || prototype === Object.prototype;\n}\n","/**\n * @typedef {(error?: Error|null|undefined, ...output: Array) => void} Callback\n * @typedef {(...input: Array) => any} Middleware\n *\n * @typedef {(...input: Array) => void} Run\n * Call all middleware.\n * @typedef {(fn: Middleware) => Pipeline} Use\n * Add `fn` (middleware) to the list.\n * @typedef {{run: Run, use: Use}} Pipeline\n * Middleware.\n */\n\n/**\n * Create new middleware.\n *\n * @returns {Pipeline}\n */\nexport function trough() {\n /** @type {Array} */\n const fns = []\n /** @type {Pipeline} */\n const pipeline = {run, use}\n\n return pipeline\n\n /** @type {Run} */\n function run(...values) {\n let middlewareIndex = -1\n /** @type {Callback} */\n const callback = values.pop()\n\n if (typeof callback !== 'function') {\n throw new TypeError('Expected function as last argument, not ' + callback)\n }\n\n next(null, ...values)\n\n /**\n * Run the next `fn`, or we’re done.\n *\n * @param {Error|null|undefined} error\n * @param {Array} output\n */\n function next(error, ...output) {\n const fn = fns[++middlewareIndex]\n let index = -1\n\n if (error) {\n callback(error)\n return\n }\n\n // Copy non-nullish input into values.\n while (++index < values.length) {\n if (output[index] === null || output[index] === undefined) {\n output[index] = values[index]\n }\n }\n\n // Save the newly created `output` for the next call.\n values = output\n\n // Next or done.\n if (fn) {\n wrap(fn, next)(...output)\n } else {\n callback(null, ...output)\n }\n }\n }\n\n /** @type {Use} */\n function use(middelware) {\n if (typeof middelware !== 'function') {\n throw new TypeError(\n 'Expected `middelware` to be a function, not ' + middelware\n )\n }\n\n fns.push(middelware)\n return pipeline\n }\n}\n\n/**\n * Wrap `middleware`.\n * Can be sync or async; return a promise, receive a callback, or return new\n * values and errors.\n *\n * @param {Middleware} middleware\n * @param {Callback} callback\n */\nexport function wrap(middleware, callback) {\n /** @type {boolean} */\n let called\n\n return wrapped\n\n /**\n * Call `middleware`.\n * @this {any}\n * @param {Array} parameters\n * @returns {void}\n */\n function wrapped(...parameters) {\n const fnExpectsCallback = middleware.length > parameters.length\n /** @type {any} */\n let result\n\n if (fnExpectsCallback) {\n parameters.push(done)\n }\n\n try {\n result = middleware.apply(this, parameters)\n } catch (error) {\n const exception = /** @type {Error} */ (error)\n\n // Well, this is quite the pickle.\n // `middleware` received a callback and called it synchronously, but that\n // threw an error.\n // The only thing left to do is to throw the thing instead.\n if (fnExpectsCallback && called) {\n throw exception\n }\n\n return done(exception)\n }\n\n if (!fnExpectsCallback) {\n if (result instanceof Promise) {\n result.then(then, done)\n } else if (result instanceof Error) {\n done(result)\n } else {\n then(result)\n }\n }\n }\n\n /**\n * Call `callback`, only once.\n * @type {Callback}\n */\n function done(error, ...output) {\n if (!called) {\n called = true\n callback(error, ...output)\n }\n }\n\n /**\n * Call `done` with one value.\n *\n * @param {any} [value]\n */\n function then(value) {\n done(null, value)\n }\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('vfile').VFileCompatible} VFileCompatible\n * @typedef {import('vfile').VFileValue} VFileValue\n * @typedef {import('..').Processor} Processor\n * @typedef {import('..').Plugin} Plugin\n * @typedef {import('..').Preset} Preset\n * @typedef {import('..').Pluggable} Pluggable\n * @typedef {import('..').PluggableList} PluggableList\n * @typedef {import('..').Transformer} Transformer\n * @typedef {import('..').Parser} Parser\n * @typedef {import('..').Compiler} Compiler\n * @typedef {import('..').RunCallback} RunCallback\n * @typedef {import('..').ProcessCallback} ProcessCallback\n *\n * @typedef Context\n * @property {Node} tree\n * @property {VFile} file\n */\n\nimport {bail} from 'bail'\nimport isBuffer from 'is-buffer'\nimport extend from 'extend'\nimport isPlainObj from 'is-plain-obj'\nimport {trough} from 'trough'\nimport {VFile} from 'vfile'\n\n// Expose a frozen processor.\nexport const unified = base().freeze()\n\nconst own = {}.hasOwnProperty\n\n// Function to create the first processor.\n/**\n * @returns {Processor}\n */\nfunction base() {\n const transformers = trough()\n /** @type {Processor['attachers']} */\n const attachers = []\n /** @type {Record} */\n let namespace = {}\n /** @type {boolean|undefined} */\n let frozen\n let freezeIndex = -1\n\n // Data management.\n // @ts-expect-error: overloads are handled.\n processor.data = data\n processor.Parser = undefined\n processor.Compiler = undefined\n\n // Lock.\n processor.freeze = freeze\n\n // Plugins.\n processor.attachers = attachers\n // @ts-expect-error: overloads are handled.\n processor.use = use\n\n // API.\n processor.parse = parse\n processor.stringify = stringify\n // @ts-expect-error: overloads are handled.\n processor.run = run\n processor.runSync = runSync\n // @ts-expect-error: overloads are handled.\n processor.process = process\n processor.processSync = processSync\n\n // Expose.\n return processor\n\n // Create a new processor based on the processor in the current scope.\n /** @type {Processor} */\n function processor() {\n const destination = base()\n let index = -1\n\n while (++index < attachers.length) {\n destination.use(...attachers[index])\n }\n\n destination.data(extend(true, {}, namespace))\n\n return destination\n }\n\n /**\n * @param {string|Record} [key]\n * @param {unknown} [value]\n * @returns {unknown}\n */\n function data(key, value) {\n if (typeof key === 'string') {\n // Set `key`.\n if (arguments.length === 2) {\n assertUnfrozen('data', frozen)\n namespace[key] = value\n return processor\n }\n\n // Get `key`.\n return (own.call(namespace, key) && namespace[key]) || null\n }\n\n // Set space.\n if (key) {\n assertUnfrozen('data', frozen)\n namespace = key\n return processor\n }\n\n // Get space.\n return namespace\n }\n\n /** @type {Processor['freeze']} */\n function freeze() {\n if (frozen) {\n return processor\n }\n\n while (++freezeIndex < attachers.length) {\n const [attacher, ...options] = attachers[freezeIndex]\n\n if (options[0] === false) {\n continue\n }\n\n if (options[0] === true) {\n options[0] = undefined\n }\n\n /** @type {Transformer|void} */\n const transformer = attacher.call(processor, ...options)\n\n if (typeof transformer === 'function') {\n transformers.use(transformer)\n }\n }\n\n frozen = true\n freezeIndex = Number.POSITIVE_INFINITY\n\n return processor\n }\n\n /**\n * @param {Pluggable|null|undefined} [value]\n * @param {...unknown} options\n * @returns {Processor}\n */\n function use(value, ...options) {\n /** @type {Record|undefined} */\n let settings\n\n assertUnfrozen('use', frozen)\n\n if (value === null || value === undefined) {\n // Empty.\n } else if (typeof value === 'function') {\n addPlugin(value, ...options)\n } else if (typeof value === 'object') {\n if (Array.isArray(value)) {\n addList(value)\n } else {\n addPreset(value)\n }\n } else {\n throw new TypeError('Expected usable value, not `' + value + '`')\n }\n\n if (settings) {\n namespace.settings = Object.assign(namespace.settings || {}, settings)\n }\n\n return processor\n\n /**\n * @param {import('..').Pluggable} value\n * @returns {void}\n */\n function add(value) {\n if (typeof value === 'function') {\n addPlugin(value)\n } else if (typeof value === 'object') {\n if (Array.isArray(value)) {\n const [plugin, ...options] = value\n addPlugin(plugin, ...options)\n } else {\n addPreset(value)\n }\n } else {\n throw new TypeError('Expected usable value, not `' + value + '`')\n }\n }\n\n /**\n * @param {Preset} result\n * @returns {void}\n */\n function addPreset(result) {\n addList(result.plugins)\n\n if (result.settings) {\n settings = Object.assign(settings || {}, result.settings)\n }\n }\n\n /**\n * @param {PluggableList|null|undefined} [plugins]\n * @returns {void}\n */\n function addList(plugins) {\n let index = -1\n\n if (plugins === null || plugins === undefined) {\n // Empty.\n } else if (Array.isArray(plugins)) {\n while (++index < plugins.length) {\n const thing = plugins[index]\n add(thing)\n }\n } else {\n throw new TypeError('Expected a list of plugins, not `' + plugins + '`')\n }\n }\n\n /**\n * @param {Plugin} plugin\n * @param {...unknown} [value]\n * @returns {void}\n */\n function addPlugin(plugin, value) {\n let index = -1\n /** @type {Processor['attachers'][number]|undefined} */\n let entry\n\n while (++index < attachers.length) {\n if (attachers[index][0] === plugin) {\n entry = attachers[index]\n break\n }\n }\n\n if (entry) {\n if (isPlainObj(entry[1]) && isPlainObj(value)) {\n value = extend(true, entry[1], value)\n }\n\n entry[1] = value\n } else {\n // @ts-expect-error: fine.\n attachers.push([...arguments])\n }\n }\n }\n\n /** @type {Processor['parse']} */\n function parse(doc) {\n processor.freeze()\n const file = vfile(doc)\n const Parser = processor.Parser\n assertParser('parse', Parser)\n\n if (newable(Parser, 'parse')) {\n // @ts-expect-error: `newable` checks this.\n return new Parser(String(file), file).parse()\n }\n\n // @ts-expect-error: `newable` checks this.\n return Parser(String(file), file) // eslint-disable-line new-cap\n }\n\n /** @type {Processor['stringify']} */\n function stringify(node, doc) {\n processor.freeze()\n const file = vfile(doc)\n const Compiler = processor.Compiler\n assertCompiler('stringify', Compiler)\n assertNode(node)\n\n if (newable(Compiler, 'compile')) {\n // @ts-expect-error: `newable` checks this.\n return new Compiler(node, file).compile()\n }\n\n // @ts-expect-error: `newable` checks this.\n return Compiler(node, file) // eslint-disable-line new-cap\n }\n\n /**\n * @param {Node} node\n * @param {VFileCompatible|RunCallback} [doc]\n * @param {RunCallback} [callback]\n * @returns {Promise|void}\n */\n function run(node, doc, callback) {\n assertNode(node)\n processor.freeze()\n\n if (!callback && typeof doc === 'function') {\n callback = doc\n doc = undefined\n }\n\n if (!callback) {\n return new Promise(executor)\n }\n\n executor(null, callback)\n\n /**\n * @param {null|((node: Node) => void)} resolve\n * @param {(error: Error) => void} reject\n * @returns {void}\n */\n function executor(resolve, reject) {\n // @ts-expect-error: `doc` can’t be a callback anymore, we checked.\n transformers.run(node, vfile(doc), done)\n\n /**\n * @param {Error|null} error\n * @param {Node} tree\n * @param {VFile} file\n * @returns {void}\n */\n function done(error, tree, file) {\n tree = tree || node\n if (error) {\n reject(error)\n } else if (resolve) {\n resolve(tree)\n } else {\n // @ts-expect-error: `callback` is defined if `resolve` is not.\n callback(null, tree, file)\n }\n }\n }\n }\n\n /** @type {Processor['runSync']} */\n function runSync(node, file) {\n /** @type {Node|undefined} */\n let result\n /** @type {boolean|undefined} */\n let complete\n\n processor.run(node, file, done)\n\n assertDone('runSync', 'run', complete)\n\n // @ts-expect-error: we either bailed on an error or have a tree.\n return result\n\n /**\n * @param {Error|null} [error]\n * @param {Node} [tree]\n * @returns {void}\n */\n function done(error, tree) {\n bail(error)\n result = tree\n complete = true\n }\n }\n\n /**\n * @param {VFileCompatible} doc\n * @param {ProcessCallback} [callback]\n * @returns {Promise|undefined}\n */\n function process(doc, callback) {\n processor.freeze()\n assertParser('process', processor.Parser)\n assertCompiler('process', processor.Compiler)\n\n if (!callback) {\n return new Promise(executor)\n }\n\n executor(null, callback)\n\n /**\n * @param {null|((file: VFile) => void)} resolve\n * @param {(error?: Error|null|undefined) => void} reject\n * @returns {void}\n */\n function executor(resolve, reject) {\n const file = vfile(doc)\n\n processor.run(processor.parse(file), file, (error, tree, file) => {\n if (error || !tree || !file) {\n done(error)\n } else {\n /** @type {unknown} */\n const result = processor.stringify(tree, file)\n\n if (result === undefined || result === null) {\n // Empty.\n } else if (looksLikeAVFileValue(result)) {\n file.value = result\n } else {\n file.result = result\n }\n\n done(error, file)\n }\n })\n\n /**\n * @param {Error|null|undefined} [error]\n * @param {VFile|undefined} [file]\n * @returns {void}\n */\n function done(error, file) {\n if (error || !file) {\n reject(error)\n } else if (resolve) {\n resolve(file)\n } else {\n // @ts-expect-error: `callback` is defined if `resolve` is not.\n callback(null, file)\n }\n }\n }\n }\n\n /** @type {Processor['processSync']} */\n function processSync(doc) {\n /** @type {boolean|undefined} */\n let complete\n\n processor.freeze()\n assertParser('processSync', processor.Parser)\n assertCompiler('processSync', processor.Compiler)\n\n const file = vfile(doc)\n\n processor.process(file, done)\n\n assertDone('processSync', 'process', complete)\n\n return file\n\n /**\n * @param {Error|null|undefined} [error]\n * @returns {void}\n */\n function done(error) {\n complete = true\n bail(error)\n }\n }\n}\n\n/**\n * Check if `value` is a constructor.\n *\n * @param {unknown} value\n * @param {string} name\n * @returns {boolean}\n */\nfunction newable(value, name) {\n return (\n typeof value === 'function' &&\n // Prototypes do exist.\n // type-coverage:ignore-next-line\n value.prototype &&\n // A function with keys in its prototype is probably a constructor.\n // Classes’ prototype methods are not enumerable, so we check if some value\n // exists in the prototype.\n // type-coverage:ignore-next-line\n (keys(value.prototype) || name in value.prototype)\n )\n}\n\n/**\n * Check if `value` is an object with keys.\n *\n * @param {Record} value\n * @returns {boolean}\n */\nfunction keys(value) {\n /** @type {string} */\n let key\n\n for (key in value) {\n if (own.call(value, key)) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Assert a parser is available.\n *\n * @param {string} name\n * @param {unknown} value\n * @returns {asserts value is Parser}\n */\nfunction assertParser(name, value) {\n if (typeof value !== 'function') {\n throw new TypeError('Cannot `' + name + '` without `Parser`')\n }\n}\n\n/**\n * Assert a compiler is available.\n *\n * @param {string} name\n * @param {unknown} value\n * @returns {asserts value is Compiler}\n */\nfunction assertCompiler(name, value) {\n if (typeof value !== 'function') {\n throw new TypeError('Cannot `' + name + '` without `Compiler`')\n }\n}\n\n/**\n * Assert the processor is not frozen.\n *\n * @param {string} name\n * @param {unknown} frozen\n * @returns {asserts frozen is false}\n */\nfunction assertUnfrozen(name, frozen) {\n if (frozen) {\n throw new Error(\n 'Cannot call `' +\n name +\n '` on a frozen processor.\\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.'\n )\n }\n}\n\n/**\n * Assert `node` is a unist node.\n *\n * @param {unknown} node\n * @returns {asserts node is Node}\n */\nfunction assertNode(node) {\n // `isPlainObj` unfortunately uses `any` instead of `unknown`.\n // type-coverage:ignore-next-line\n if (!isPlainObj(node) || typeof node.type !== 'string') {\n throw new TypeError('Expected node, got `' + node + '`')\n // Fine.\n }\n}\n\n/**\n * Assert that `complete` is `true`.\n *\n * @param {string} name\n * @param {string} asyncName\n * @param {unknown} complete\n * @returns {asserts complete is true}\n */\nfunction assertDone(name, asyncName, complete) {\n if (!complete) {\n throw new Error(\n '`' + name + '` finished async. Use `' + asyncName + '` instead'\n )\n }\n}\n\n/**\n * @param {VFileCompatible} [value]\n * @returns {VFile}\n */\nfunction vfile(value) {\n return looksLikeAVFile(value) ? value : new VFile(value)\n}\n\n/**\n * @param {VFileCompatible} [value]\n * @returns {value is VFile}\n */\nfunction looksLikeAVFile(value) {\n return Boolean(\n value &&\n typeof value === 'object' &&\n 'message' in value &&\n 'messages' in value\n )\n}\n\n/**\n * @param {unknown} [value]\n * @returns {value is VFileValue}\n */\nfunction looksLikeAVFileValue(value) {\n return typeof value === 'string' || isBuffer(value)\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist').Literal} Literal\n * @typedef {Object.} Props\n * @typedef {Array.|string} ChildrenOrValue\n *\n * @typedef {(, C extends Node[]>(type: T, props: P, children: C) => {type: T, children: C} & P)} BuildParentWithProps\n * @typedef {(>(type: T, props: P, value: string) => {type: T, value: string} & P)} BuildLiteralWithProps\n * @typedef {(>(type: T, props: P) => {type: T} & P)} BuildVoidWithProps\n * @typedef {((type: T, children: C) => {type: T, children: C})} BuildParent\n * @typedef {((type: T, value: string) => {type: T, value: string})} BuildLiteral\n * @typedef {((type: T) => {type: T})} BuildVoid\n */\n\nexport var u = /**\n * @type {BuildVoid & BuildVoidWithProps & BuildLiteral & BuildLiteralWithProps & BuildParent & BuildParentWithProps}\n */ (\n /**\n * @param {string} type Type of node\n * @param {Props|ChildrenOrValue} [props] Additional properties for node (or `children` or `value`)\n * @param {ChildrenOrValue} [value] `children` or `value` of node\n * @returns {Node}\n */\n function (type, props, value) {\n /** @type {Node} */\n var node = {type: String(type)}\n\n if (\n (value === undefined || value === null) &&\n (typeof props === 'string' || Array.isArray(props))\n ) {\n value = props\n } else {\n Object.assign(node, props)\n }\n\n if (Array.isArray(value)) {\n node.children = value\n } else if (value !== undefined && value !== null) {\n node.value = String(value)\n }\n\n return node\n }\n)\n","/**\n * @typedef {Object} PointLike\n * @property {number} [line]\n * @property {number} [column]\n * @property {number} [offset]\n *\n * @typedef {Object} PositionLike\n * @property {PointLike} [start]\n * @property {PointLike} [end]\n *\n * @typedef {Object} NodeLike\n * @property {PositionLike} [position]\n */\n\n/**\n * Check if `node` is *generated*.\n *\n * @param {NodeLike} [node]\n * @returns {boolean}\n */\nexport function generated(node) {\n return (\n !node ||\n !node.position ||\n !node.position.start ||\n !node.position.start.line ||\n !node.position.start.column ||\n !node.position.end ||\n !node.position.end.line ||\n !node.position.end.column\n )\n}\n","/**\n * @typedef {import('unist').Position} Position\n * @typedef {import('unist').Node} Node\n * @typedef {Record & {type: string, position?: PositionLike|undefined}} NodeLike\n * @typedef {import('unist').Point} Point\n *\n * @typedef {Partial} PointLike\n *\n * @typedef PositionLike\n * @property {PointLike} [start]\n * @property {PointLike} [end]\n */\n\nexport const pointStart = point('start')\nexport const pointEnd = point('end')\n\n/**\n * Get the positional info of `node`.\n *\n * @param {NodeLike|Node} [node]\n * @returns {Position}\n */\nexport function position(node) {\n return {start: pointStart(node), end: pointEnd(node)}\n}\n\n/**\n * Get the positional info of `node`.\n *\n * @param {'start'|'end'} type\n */\nfunction point(type) {\n return point\n\n /**\n * Get the positional info of `node`.\n *\n * @param {NodeLike|Node} [node]\n * @returns {Point}\n */\n function point(node) {\n const point = (node && node.position && node.position[type]) || {}\n\n return {\n line: point.line || null,\n column: point.column || null,\n offset: point.offset > -1 ? point.offset : null\n }\n }\n}\n","/**\n * @typedef {import('unist').Point} Point\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Position} Position\n * @typedef {object & {type: string, position?: Position|undefined}} NodeLike\n */\n\n/**\n * Stringify one point, a position (start and end points), or a node’s\n * positional information.\n *\n * @param {Node|NodeLike|Position|Point|null} [value]\n * @returns {string}\n */\nexport function stringifyPosition(value) {\n // Nothing.\n if (!value || typeof value !== 'object') {\n return ''\n }\n\n // Node.\n if ('position' in value || 'type' in value) {\n return position(value.position)\n }\n\n // Position.\n if ('start' in value || 'end' in value) {\n return position(value)\n }\n\n // Point.\n if ('line' in value || 'column' in value) {\n return point(value)\n }\n\n // ?\n return ''\n}\n\n/**\n * @param {Point|undefined} point\n * @returns {string}\n */\nfunction point(point) {\n return index(point && point.line) + ':' + index(point && point.column)\n}\n\n/**\n * @param {Position|undefined} pos\n * @returns {string}\n */\nfunction position(pos) {\n return point(pos && pos.start) + '-' + point(pos && pos.end)\n}\n\n/**\n * @param {number|undefined} value\n * @returns {number}\n */\nfunction index(value) {\n return value && typeof value === 'number' ? value : 1\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Position} Position\n * @typedef {import('unist').Point} Point\n * @typedef {object & {type: string, position?: Position|undefined}} NodeLike\n */\n\nimport {stringifyPosition} from 'unist-util-stringify-position'\n\nexport class VFileMessage extends Error {\n /**\n * Constructor of a message for `reason` at `place` from `origin`.\n * When an error is passed in as `reason`, copies the `stack`.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n */\n constructor(reason, place, origin) {\n /** @type {[string|null, string|null]} */\n const parts = [null, null]\n /** @type {Position} */\n let position = {\n // @ts-expect-error: we always follows the structure of `position`.\n start: {line: null, column: null},\n // @ts-expect-error: \"\n end: {line: null, column: null}\n }\n\n super()\n\n if (typeof place === 'string') {\n origin = place\n place = undefined\n }\n\n if (typeof origin === 'string') {\n const index = origin.indexOf(':')\n\n if (index === -1) {\n parts[1] = origin\n } else {\n parts[0] = origin.slice(0, index)\n parts[1] = origin.slice(index + 1)\n }\n }\n\n if (place) {\n // Node.\n if ('type' in place || 'position' in place) {\n if (place.position) {\n position = place.position\n }\n }\n // Position.\n else if ('start' in place || 'end' in place) {\n position = place\n }\n // Point.\n else if ('line' in place || 'column' in place) {\n position.start = place\n }\n }\n\n // Fields from `Error`\n this.name = stringifyPosition(place) || '1:1'\n this.message = typeof reason === 'object' ? reason.message : reason\n this.stack = typeof reason === 'object' ? reason.stack : ''\n\n /**\n * Reason for message.\n * @type {string}\n */\n this.reason = this.message\n /**\n * If true, marks associated file as no longer processable.\n * @type {boolean?}\n */\n // eslint-disable-next-line no-unused-expressions\n this.fatal\n /**\n * Starting line of error.\n * @type {number?}\n */\n this.line = position.start.line\n /**\n * Starting column of error.\n * @type {number?}\n */\n this.column = position.start.column\n /**\n * Namespace of warning.\n * @type {string?}\n */\n this.source = parts[0]\n /**\n * Category of message.\n * @type {string?}\n */\n this.ruleId = parts[1]\n /**\n * Full range information, when available.\n * Has start and end properties, both set to an object with line and column, set to number?.\n * @type {Position?}\n */\n this.position = position\n\n // The following fields are “well known”.\n // Not standard.\n // Feel free to add other non-standard fields to your messages.\n\n /* eslint-disable no-unused-expressions */\n /**\n * You can use this to specify the source value that’s being reported, which\n * is deemed incorrect.\n * @type {string?}\n */\n this.actual\n /**\n * You can use this to suggest values that should be used instead of\n * `actual`, one or more values that are deemed as acceptable.\n * @type {Array?}\n */\n this.expected\n /**\n * You may add a file property with a path of a file (used throughout the VFile ecosystem).\n * @type {string?}\n */\n this.file\n /**\n * You may add a url property with a link to documentation for the message.\n * @type {string?}\n */\n this.url\n /**\n * You may add a note property with a long form description of the message (supported by vfile-reporter).\n * @type {string?}\n */\n this.note\n /* eslint-enable no-unused-expressions */\n }\n}\n\nVFileMessage.prototype.file = ''\nVFileMessage.prototype.name = ''\nVFileMessage.prototype.reason = ''\nVFileMessage.prototype.message = ''\nVFileMessage.prototype.stack = ''\nVFileMessage.prototype.fatal = null\nVFileMessage.prototype.column = null\nVFileMessage.prototype.line = null\nVFileMessage.prototype.source = null\nVFileMessage.prototype.ruleId = null\nVFileMessage.prototype.position = null\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"process\");","/**\n * @typedef URL\n * @property {string} hash\n * @property {string} host\n * @property {string} hostname\n * @property {string} href\n * @property {string} origin\n * @property {string} password\n * @property {string} pathname\n * @property {string} port\n * @property {string} protocol\n * @property {string} search\n * @property {any} searchParams\n * @property {string} username\n * @property {() => string} toString\n * @property {() => string} toJSON\n */\n\n/**\n * @param {unknown} fileURLOrPath\n * @returns {fileURLOrPath is URL}\n */\n// From: \nexport function isUrl(fileURLOrPath) {\n return (\n fileURLOrPath !== null &&\n typeof fileURLOrPath === 'object' &&\n // @ts-expect-error: indexable.\n fileURLOrPath.href &&\n // @ts-expect-error: indexable.\n fileURLOrPath.origin\n )\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Position} Position\n * @typedef {import('unist').Point} Point\n * @typedef {Record & {type: string, position?: Position|undefined}} NodeLike\n * @typedef {import('./minurl.shared.js').URL} URL\n * @typedef {import('..').VFileData} VFileData\n * @typedef {import('..').VFileValue} VFileValue\n *\n * @typedef {'ascii'|'utf8'|'utf-8'|'utf16le'|'ucs2'|'ucs-2'|'base64'|'base64url'|'latin1'|'binary'|'hex'} BufferEncoding\n * Encodings supported by the buffer class.\n * This is a copy of the typing from Node, copied to prevent Node globals from\n * being needed.\n * Copied from: \n *\n * @typedef {VFileValue|VFileOptions|VFile|URL} VFileCompatible\n * Things that can be passed to the constructor.\n *\n * @typedef VFileCoreOptions\n * @property {VFileValue} [value]\n * @property {string} [cwd]\n * @property {Array} [history]\n * @property {string|URL} [path]\n * @property {string} [basename]\n * @property {string} [stem]\n * @property {string} [extname]\n * @property {string} [dirname]\n * @property {VFileData} [data]\n *\n * @typedef Map\n * Raw source map, see:\n * .\n * @property {number} version\n * @property {Array} sources\n * @property {Array} names\n * @property {string|undefined} [sourceRoot]\n * @property {Array|undefined} [sourcesContent]\n * @property {string} mappings\n * @property {string} file\n *\n * @typedef {{[key: string]: unknown} & VFileCoreOptions} VFileOptions\n * Configuration: a bunch of keys that will be shallow copied over to the new\n * file.\n *\n * @typedef {Record} VFileReporterSettings\n * @typedef {(files: Array, options: T) => string} VFileReporter\n */\n\nimport buffer from 'is-buffer'\nimport {VFileMessage} from 'vfile-message'\nimport {path} from './minpath.js'\nimport {proc} from './minproc.js'\nimport {urlToPath, isUrl} from './minurl.js'\n\n// Order of setting (least specific to most), we need this because otherwise\n// `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a\n// stem can be set.\nconst order = ['history', 'path', 'basename', 'stem', 'extname', 'dirname']\n\nexport class VFile {\n /**\n * Create a new virtual file.\n *\n * If `options` is `string` or `Buffer`, treats it as `{value: options}`.\n * If `options` is a `VFile`, shallow copies its data over to the new file.\n * All other given fields are set on the newly created `VFile`.\n *\n * Path related properties are set in the following order (least specific to\n * most specific): `history`, `path`, `basename`, `stem`, `extname`,\n * `dirname`.\n *\n * It’s not possible to set either `dirname` or `extname` without setting\n * either `history`, `path`, `basename`, or `stem` as well.\n *\n * @param {VFileCompatible} [value]\n */\n constructor(value) {\n /** @type {VFileOptions} */\n let options\n\n if (!value) {\n options = {}\n } else if (typeof value === 'string' || buffer(value)) {\n // @ts-expect-error Looks like a buffer.\n options = {value}\n } else if (isUrl(value)) {\n options = {path: value}\n } else {\n // @ts-expect-error Looks like file or options.\n options = value\n }\n\n /**\n * Place to store custom information.\n * It’s OK to store custom data directly on the file, moving it to `data`\n * gives a little more privacy.\n * @type {VFileData}\n */\n this.data = {}\n\n /**\n * List of messages associated with the file.\n * @type {Array}\n */\n this.messages = []\n\n /**\n * List of file paths the file moved between.\n * @type {Array}\n */\n this.history = []\n\n /**\n * Base of `path`.\n * Defaults to `process.cwd()` (`/` in browsers).\n * @type {string}\n */\n this.cwd = proc.cwd()\n\n /* eslint-disable no-unused-expressions */\n /**\n * Raw value.\n * @type {VFileValue}\n */\n this.value\n\n // The below are non-standard, they are “well-known”.\n // As in, used in several tools.\n\n /**\n * Whether a file was saved to disk.\n * This is used by vfile reporters.\n * @type {boolean}\n */\n this.stored\n\n /**\n * Sometimes files have a non-string representation.\n * This can be stored in the `result` field.\n * One example is when turning markdown into React nodes.\n * This is used by unified to store non-string results.\n * @type {unknown}\n */\n this.result\n\n /**\n * Sometimes files have a source map associated with them.\n * This can be stored in the `map` field.\n * This should be a `RawSourceMap` type from the `source-map` module.\n * @type {Map|undefined}\n */\n this.map\n /* eslint-enable no-unused-expressions */\n\n // Set path related properties in the correct order.\n let index = -1\n\n while (++index < order.length) {\n const prop = order[index]\n\n // Note: we specifically use `in` instead of `hasOwnProperty` to accept\n // `vfile`s too.\n if (prop in options && options[prop] !== undefined) {\n // @ts-expect-error: TS is confused by the different types for `history`.\n this[prop] = prop === 'history' ? [...options[prop]] : options[prop]\n }\n }\n\n /** @type {string} */\n let prop\n\n // Set non-path related properties.\n for (prop in options) {\n // @ts-expect-error: fine to set other things.\n if (!order.includes(prop)) this[prop] = options[prop]\n }\n }\n\n /**\n * Access full path (`~/index.min.js`).\n *\n * @returns {string}\n */\n get path() {\n return this.history[this.history.length - 1]\n }\n\n /**\n * Set full path (`~/index.min.js`).\n * Cannot be nullified.\n *\n * @param {string|URL} path\n */\n set path(path) {\n if (isUrl(path)) {\n path = urlToPath(path)\n }\n\n assertNonEmpty(path, 'path')\n\n if (this.path !== path) {\n this.history.push(path)\n }\n }\n\n /**\n * Access parent path (`~`).\n */\n get dirname() {\n return typeof this.path === 'string' ? path.dirname(this.path) : undefined\n }\n\n /**\n * Set parent path (`~`).\n * Cannot be set if there's no `path` yet.\n */\n set dirname(dirname) {\n assertPath(this.basename, 'dirname')\n this.path = path.join(dirname || '', this.basename)\n }\n\n /**\n * Access basename (including extname) (`index.min.js`).\n */\n get basename() {\n return typeof this.path === 'string' ? path.basename(this.path) : undefined\n }\n\n /**\n * Set basename (`index.min.js`).\n * Cannot contain path separators.\n * Cannot be nullified either (use `file.path = file.dirname` instead).\n */\n set basename(basename) {\n assertNonEmpty(basename, 'basename')\n assertPart(basename, 'basename')\n this.path = path.join(this.dirname || '', basename)\n }\n\n /**\n * Access extname (including dot) (`.js`).\n */\n get extname() {\n return typeof this.path === 'string' ? path.extname(this.path) : undefined\n }\n\n /**\n * Set extname (including dot) (`.js`).\n * Cannot be set if there's no `path` yet and cannot contain path separators.\n */\n set extname(extname) {\n assertPart(extname, 'extname')\n assertPath(this.dirname, 'extname')\n\n if (extname) {\n if (extname.charCodeAt(0) !== 46 /* `.` */) {\n throw new Error('`extname` must start with `.`')\n }\n\n if (extname.includes('.', 1)) {\n throw new Error('`extname` cannot contain multiple dots')\n }\n }\n\n this.path = path.join(this.dirname, this.stem + (extname || ''))\n }\n\n /**\n * Access stem (w/o extname) (`index.min`).\n */\n get stem() {\n return typeof this.path === 'string'\n ? path.basename(this.path, this.extname)\n : undefined\n }\n\n /**\n * Set stem (w/o extname) (`index.min`).\n * Cannot be nullified, and cannot contain path separators.\n */\n set stem(stem) {\n assertNonEmpty(stem, 'stem')\n assertPart(stem, 'stem')\n this.path = path.join(this.dirname || '', stem + (this.extname || ''))\n }\n\n /**\n * Serialize the file.\n *\n * @param {BufferEncoding} [encoding='utf8'] If `file.value` is a buffer, `encoding` is used to serialize buffers.\n * @returns {string}\n */\n toString(encoding) {\n return (this.value || '').toString(encoding)\n }\n\n /**\n * Create a message and associates it w/ the file.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n * @returns {VFileMessage}\n */\n message(reason, place, origin) {\n const message = new VFileMessage(reason, place, origin)\n\n if (this.path) {\n message.name = this.path + ':' + message.name\n message.file = this.path\n }\n\n message.fatal = false\n\n this.messages.push(message)\n\n return message\n }\n\n /**\n * Info: create a message, associate it with the file, and mark the fatality\n * as `null`.\n * Calls `message()` internally.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n * @returns {VFileMessage}\n */\n info(reason, place, origin) {\n const message = this.message(reason, place, origin)\n\n message.fatal = null\n\n return message\n }\n\n /**\n * Fail: create a message, associate it with the file, mark the fatality as\n * `true`.\n * Note: fatal errors mean a file is no longer processable.\n * Calls `message()` internally.\n *\n * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given.\n * @param {Node|NodeLike|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional).\n * @param {string} [origin] Place in code the message originates from (`string`, optional).\n * @returns {never}\n */\n fail(reason, place, origin) {\n const message = this.message(reason, place, origin)\n\n message.fatal = true\n\n throw message\n }\n}\n\n/**\n * Assert that `part` is not a path (as in, does not contain `path.sep`).\n *\n * @param {string|undefined} part\n * @param {string} name\n * @returns {void}\n */\nfunction assertPart(part, name) {\n if (part && part.includes(path.sep)) {\n throw new Error(\n '`' + name + '` cannot be a path: did not expect `' + path.sep + '`'\n )\n }\n}\n\n/**\n * Assert that `part` is not empty.\n *\n * @param {string|undefined} part\n * @param {string} name\n * @returns {asserts part is string}\n */\nfunction assertNonEmpty(part, name) {\n if (!part) {\n throw new Error('`' + name + '` cannot be empty')\n }\n}\n\n/**\n * Assert `path` exists.\n *\n * @param {string|undefined} path\n * @param {string} name\n * @returns {asserts path is string}\n */\nfunction assertPath(path, name) {\n if (!path) {\n throw new Error('Setting `' + name + '` requires `path` to be set too')\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","var webpackThen = typeof Symbol === \"function\" ? Symbol(\"webpack then\") : \"__webpack_then__\";\nvar webpackExports = typeof Symbol === \"function\" ? Symbol(\"webpack exports\") : \"__webpack_exports__\";\nvar webpackError = typeof Symbol === \"function\" ? Symbol(\"webpack error\") : \"__webpack_error__\";\nvar completeQueue = (queue) => {\n\tif(queue) {\n\t\tqueue.forEach((fn) => (fn.r--));\n\t\tqueue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));\n\t}\n}\nvar completeFunction = (fn) => (!--fn.r && fn());\nvar queueFunction = (queue, fn) => (queue ? queue.push(fn) : completeFunction(fn));\nvar wrapDeps = (deps) => (deps.map((dep) => {\n\tif(dep !== null && typeof dep === \"object\") {\n\t\tif(dep[webpackThen]) return dep;\n\t\tif(dep.then) {\n\t\t\tvar queue = [];\n\t\t\tdep.then((r) => {\n\t\t\t\tobj[webpackExports] = r;\n\t\t\t\tcompleteQueue(queue);\n\t\t\t\tqueue = 0;\n\t\t\t}, (e) => {\n\t\t\t\tobj[webpackError] = e;\n\t\t\t\tcompleteQueue(queue);\n\t\t\t\tqueue = 0;\n\t\t\t});\n\t\t\tvar obj = {};\n\t\t\tobj[webpackThen] = (fn, reject) => (queueFunction(queue, fn), dep['catch'](reject));\n\t\t\treturn obj;\n\t\t}\n\t}\n\tvar ret = {};\n\tret[webpackThen] = (fn) => (completeFunction(fn));\n\tret[webpackExports] = dep;\n\treturn ret;\n}));\n__webpack_require__.a = (module, body, hasAwait) => {\n\tvar queue = hasAwait && [];\n\tvar exports = module.exports;\n\tvar currentDeps;\n\tvar outerResolve;\n\tvar reject;\n\tvar isEvaluating = true;\n\tvar nested = false;\n\tvar whenAll = (deps, onResolve, onReject) => {\n\t\tif (nested) return;\n\t\tnested = true;\n\t\tonResolve.r += deps.length;\n\t\tdeps.map((dep, i) => (dep[webpackThen](onResolve, onReject)));\n\t\tnested = false;\n\t};\n\tvar promise = new Promise((resolve, rej) => {\n\t\treject = rej;\n\t\touterResolve = () => (resolve(exports), completeQueue(queue), queue = 0);\n\t});\n\tpromise[webpackExports] = exports;\n\tpromise[webpackThen] = (fn, rejectFn) => {\n\t\tif (isEvaluating) { return completeFunction(fn); }\n\t\tif (currentDeps) whenAll(currentDeps, fn, rejectFn);\n\t\tqueueFunction(queue, fn);\n\t\tpromise['catch'](rejectFn);\n\t};\n\tmodule.exports = promise;\n\tbody((deps) => {\n\t\tcurrentDeps = wrapDeps(deps);\n\t\tvar fn;\n\t\tvar getResult = () => (currentDeps.map((d) => {\n\t\t\tif(d[webpackError]) throw d[webpackError];\n\t\t\treturn d[webpackExports];\n\t\t}))\n\t\tvar promise = new Promise((resolve, reject) => {\n\t\t\tfn = () => (resolve(getResult));\n\t\t\tfn.r = 0;\n\t\t\twhenAll(currentDeps, fn, reject);\n\t\t});\n\t\treturn fn.r ? promise : getResult();\n\t}, (err) => (err && reject(promise[webpackError] = err), outerResolve()));\n\tisEvaluating = false;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","","// startup\n// Load entry module and return exports\n// This entry module used 'module' so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(9877);\n",""],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/release/package.json b/release/package.json index f2a68635..6f0ed894 100644 --- a/release/package.json +++ b/release/package.json @@ -47,4 +47,4 @@ "yargs": "17.4.0", "yup": "0.32.11" } -} +} \ No newline at end of file diff --git a/release/template.css b/release/template.css index 9f98eaed..095f6a2b 100644 --- a/release/template.css +++ b/release/template.css @@ -1 +1 @@ -*{margin:0;border:0;padding:0}:root{--bg: white;--textColor: #333;--fadedTextColor: #888;--errorColor: #b30c00;--linkColor: #0075b0;--primaryColor: 0, 0, 0;--highlightColor: #003865;--boxoutBg: #f2f2f2;--boxoutHighlightColor: #e2e2e2;--boxoutFadedTextColor: #444;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}html.theme-dark{--bg: #111;--textColor: #ccc;--fadedTextColor: #666;--errorColor: #b30c00;--linkColor: #0075b0;--primaryColor: 255, 255, 255;--highlightColor: #7a6855;--boxoutBg: #222;--boxoutHighlightColor: #333;--boxoutFadedTextColor: #999;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}html.theme-yellow-on-black{--bg: #111;--textColor: #ebd90e;--fadedTextColor: #8b8008;--errorColor: #b30c00;--linkColor: #b06c96;--primaryColor: 235, 217, 14;--highlightColor: #ebd90e;--boxoutBg: #222;--boxoutHighlightColor: #333;--boxoutFadedTextColor: #8b8008;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}html.theme-black-on-yellow{--bg: #ebd90e;--textColor: #000;--fadedTextColor: #333333;--errorColor: #b30c00;--linkColor: #951272;--primaryColor: 0, 0, 0;--highlightColor: black;--boxoutBg: #ddcc0d;--boxoutHighlightColor: #c4b50c;--boxoutFadedTextColor: #4d4d4d;--taskBg: rgba(125, 34, 57, 0.2);--taskFg: #7d2239}html.theme-black-on-red{--bg: #de7777;--textColor: black;--fadedTextColor: #333333;--errorColor: #b30c00;--linkColor: #ffb948;--primaryColor: 0, 0, 0;--highlightColor: black;--boxoutBg: #db6b6b;--boxoutHighlightColor: #d44e4e;--boxoutFadedTextColor: #333333;--taskBg: rgba(0, 56, 101, 0.1);--taskFg: #003865}html.theme-black-on-blue{--bg: #64a8e1;--textColor: black;--fadedTextColor: #333333;--errorColor: #b30c00;--linkColor: #ffdc36;--primaryColor: 0, 0, 0;--highlightColor: black;--boxoutBg: #4f9cdd;--boxoutHighlightColor: #2884d0;--boxoutFadedTextColor: #333333;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}*::-webkit-scrollbar{width:15px}*{scrollbar-width:thin;scroll-behavior:smooth;scrollbar-color:var(--textColor) var(--bg)}*::-webkit-scrollbar-track{background:var(--bg)}*::-webkit-scrollbar-thumb{border-radius:7.5px;border:5px solid;background-color:var(--textColor);border-color:var(--bg)}html{background:var(--bg)}body{color:var(--textColor)}#root{overflow-x:hidden}.hamburger-icon{position:absolute;width:22px;height:19px;fill:var(--highlightColor);top:2.5rem;cursor:pointer;opacity:.75;transition:opacity .2s}.hamburger-icon:hover{opacity:1}.logo>.hamburger-icon{right:1rem}#root>.hamburger-icon{position:fixed;left:2rem}aside{position:fixed;top:0;height:100%;width:18rem;overflow-y:scroll;overflow-x:hidden;background:var(--boxoutBg);transition:margin-left .2s;scroll-behavior:smooth;scrollbar-color:var(--boxoutHighlightColor) var(--boxoutBg)}aside::-webkit-scrollbar-track{background:var(--boxoutBg)}aside::-webkit-scrollbar-thumb{background-color:var(--boxoutBg);border-color:var(--boxoutBg);transition:background-color .2s}aside:hover::-webkit-scrollbar-thumb{background-color:var(--boxoutHighlightColor)}#root.hide-sidebar aside{margin-left:-18rem}aside #toc{padding-top:2rem}main{flex:1;overflow:auto;transform:translateX(9rem);transition:transform .2s}#root.hide-sidebar main{transform:translateX(0)}main>.wrapper{margin-top:0;margin-right:auto;margin-bottom:5rem;margin-left:auto}html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:18px;font-weight:400;line-height:1.75;text-rendering:geometricPrecision;color:#222}main{font-size:calc(1rem*var(--fontSize, 1));line-height:calc(1.75*var(--lineSpacing, 1));letter-spacing:calc(var(--letterSpacing, 0)*1em)}main>.wrapper{width:calc(66%*var(--lineWidth, 1))}#root.pdf main{font-size:14px}#root.pdf main>.wrapper{width:90%}@media(max-width: 1000px){main>.wrapper{width:calc(85%*var(--lineWidth, 1))}}p{margin-bottom:1em}a{font-weight:600;text-decoration:none;color:var(--linkColor)}h1,h2,h3,h4,h5,h6,.boxout .title{font-weight:700;line-height:1.2;margin:1.5em 0 1em}h1{color:rgb(var(--primaryColor))}h2,h3,h4,h5,h6{color:var(--highlightColor)}h2{font-size:2.25em;margin:1em 0 .5em}h3{font-size:1.5em;margin:2em 0 .5em}h4{font-size:1.25em;margin-top:2em}h2+h3,h3+h4,h4+h5,h5+h6{margin-top:0}h2+.boxout,h3+.boxout,h4+.boxout,h5+.boxout{margin-top:0}h1 .link,h2 .link,h3 .link,h4 .link,h5 .link,h6 .link{display:inline-block;vertical-align:middle;width:1.1em;height:.6em;margin-top:-0.15em;margin-left:-1.1em;opacity:0;transition:opacity .2s}h1 .link .icon,h2 .link .icon,h3 .link .icon,h4 .link .icon,h5 .link .icon,h6 .link .icon{display:block;width:1.1em;height:.6em;fill:rgb(var(--primaryColor))}h1:hover .link,h2:hover .link,h3:hover .link,h4:hover .link,h5:hover .link,h6:hover .link{opacity:.5}ul,ol{padding:0rem 2rem 1rem}li:not(:last-child){padding-bottom:.5rem}#view-options-toggle,.boxout .type,.answer-trigger{display:inline-block;padding:.3rem .8rem .25rem;font-size:.8rem;line-height:1.5rem;font-weight:bold;color:rgba(var(--primaryColor), 1);background:rgba(var(--primaryColor), 0.1);border-radius:.2rem;user-select:none;transition:background .2s}#view-options-toggle:hover,.boxout .type:hover,.answer-trigger:hover{background:rgba(var(--primaryColor), 0.2)}h1{font-size:3.3em;margin:.5em 0 1.45em}h1 span{display:block;font-size:.4em;opacity:.4;margin-top:1em}.cover .logos{display:flex;flex-direction:row-reverse;align-items:baseline;justify-content:space-between}.cover .hexagons{display:block;width:30%;margin-bottom:2rem}.cover .hexagons .hex{stroke:rgb(var(--primaryColor))}.cover .hexagons .hex-logo{fill:rgb(var(--primaryColor))}.cover .hexagons .active .hex{fill:rgb(var(--primaryColor))}.cover .hexagons .active .hex-logo{fill:var(--bg)}.cover .dag-logo{display:block;width:20%;margin-bottom:5rem;position:relative;bottom:1rem}.cover .dag-logo .primary{fill:rgb(var(--primaryColor))}@media(max-width: 1000px){h1{font-size:3em;margin:2em 0 1em}.cover .logos{display:block}.cover .hexagons{width:100%}.cover .dag-logo{width:50%;bottom:0}}.logo{position:relative;padding:1.5rem 2rem 2rem}.logo .logo-wrapper{display:flex;align-items:center;width:70%}.logo .crest{width:25%;margin-right:10%}.logo .crest path.dark-only{opacity:0}html.theme-dark .logo .crest path.dark-only,html.theme-yellow-on-black .logo .crest path.dark-only{opacity:1}.logo .uofg{width:60%}html.theme-dark .logo .uofg path,html.theme-yellow-on-black .logo .uofg path{fill:#fff}aside nav li{list-style:none;padding:0}aside nav p{margin:0;line-height:1.4}aside nav>ul{padding:0 calc(2rem - 15px) 2rem 2rem}aside nav>ul>li{padding-bottom:1.5rem !important}aside nav ul ul{padding:.5rem}aside nav ul ul a{color:var(--boxoutFadedTextColor);font-weight:400}.table-wrapper{overflow:auto;margin:.5rem 0 2rem}.table-wrapper table{margin:0 auto}table{border-collapse:collapse;border-radius:.4rem;margin:.5rem 0 2rem;background:var(--boxoutBg)}.boxout table{background:var(--bg)}table th,table td{border:2px solid var(--boxoutHighlightColor);padding:.5rem 2rem .5rem 1rem;text-align:left;vertical-align:top}table td{color:var(--boxoutFadedTextColor)}table th{border-top-width:0}table th:first-child,table td:first-child{border-left-width:0}table tr:last-child td{border-bottom-width:0}table th:last-child,table td:last-child{border-right-width:0}table code{background:none;padding:0;margin:0;color:var(--boxoutFadedTextColor)}img{display:block;width:100%;height:auto}figure{text-align:center;margin:3rem auto}figure .img-bg{display:inline-block;background:#fff;width:75%;max-width:100%;height:auto}figure svg.pdftex,figure svg.knitr-svg{margin-bottom:0}figure figcaption{margin-bottom:3rem;padding-top:.5rem}figure figcaption a{font-style:italic;color:var(--fadedTextColor)}figure figcaption a .caption-count{color:var(--highlightColor)}svg.pdftex,svg.knitr-svg{display:block}.interactive-element{width:75%;max-width:100%;height:auto;margin-top:3rem;margin-right:auto;margin-bottom:1rem;margin-left:auto}.interactive-element svg{display:block;margin:0 auto}.math svg{max-width:100%}svg.block-math{display:block;width:100%;padding:1rem 0}svg.inline-math{vertical-align:middle;font-size:.9em}svg.inline-math svg{max-width:100%}code{vertical-align:baseline;padding:.1rem .3rem .2rem;font-family:monospace;background:var(--boxoutBg);border-radius:.2rem}.code-wrapper{margin-bottom:1rem;padding:1rem;border-radius:.3rem;background:#444;color:#ccc;overflow:auto}.code-wrapper>h6.console-heading{margin:0 0 .5rem;color:#b06c96}.code-wrapper pre{font-family:monospace;white-space:pre-wrap}.code-wrapper code{display:block;padding:0;margin:0;background:rgba(0,0,0,0)}.code-wrapper[class$=error-output]{background:var(--errorColor);color:#fff}.code-wrapper[class$=error-output]>h6.console-heading{color:#fff}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#998066}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol{color:#d1949e}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#bde052}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string,.token.variable{color:#f5b83d}.token.atrule,.token.attr-value,.token.keyword{color:#d1949e}.token.regex,.token.important{color:#e90}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}.boxout{padding:2rem;margin:1rem 0 1.5rem;border-radius:.4rem;overflow:hidden;background:var(--boxoutBg)}.boxout .type{margin-bottom:1rem;background:var(--bg);color:rgb(var(--primaryColor))}.boxout h3{font-size:1rem}.boxout .type+h3{margin-top:.5rem}.boxout>*:last-child{margin-bottom:0}.boxout.task{background:var(--taskBg)}.boxout.task .type{background:var(--taskFg);color:#fff}.boxout.task h3{color:var(--taskFg)}.boxout.task .answer-trigger{cursor:pointer}#root.pdf .boxout.task .answer-trigger{display:none}.boxout.task .answer-reveal{display:none;margin:2rem -2rem -2rem -2rem;padding:2rem;background:var(--boxoutBg)}.boxout.task .answer-reveal.show{display:block}.boxout.task .answer-reveal>*:last-child{margin-bottom:0}.boxout.video{display:flex;justify-content:space-between;align-items:flex-start;text-decoration:none;margin-bottom:1.5rem;font-weight:400}.boxout.video .content{flex:1}.boxout.video .title{display:block;margin:.2rem 0 .5rem;color:var(--highlightColor)}.boxout.video .duration{color:var(--fadedTextColor)}.boxout.video .duration strong{padding-right:.5em}.boxout.video .thumbnail{display:block;max-width:25%;margin-left:2rem;box-shadow:0 0 0 .3rem rgba(var(--primaryColor), 0.15);border-radius:.2rem;overflow:hidden}.boxout.video .thumbnail img{display:block}.boxout.video .desc{flex:1}.boxout.video .desc .title{font-weight:700;padding:0 0 1rem}.boxout .boxout.video{padding-left:0;padding-right:.3rem;background:rgba(0,0,0,0)}.boxout .boxout.video:last-child{padding-bottom:.3rem}.columns{display:flex}.columns .column{flex:1}.columns .column:nth-child(2n+1){padding-right:.5rem}.columns .column:nth-child(2n){padding-left:.5rem}@media(max-width: 800px){.columns{flex-direction:column}}#view-options-toggle{margin:0 2rem;cursor:pointer}#view-options{display:none;user-select:none}html.view-options-open #toc{display:none}html.view-options-open #view-options{display:block}#view-options{padding:0 calc(2rem - 15px) 2rem 2rem}#view-options h3{margin:2rem 0 0 0;font-size:1rem;font-weight:600;line-height:1.4;color:rgb(var(--primaryColor))}#view-options ul{padding:1rem 0}#view-options ul li{list-style:none}ul#themes{display:grid;grid-template-columns:1fr 1fr;gap:.8rem}ul#themes li{padding:.75rem .5rem .5rem;height:4.5rem;border-radius:.3rem;line-height:1.4;cursor:pointer}ul#themes li.selected{box-shadow:0 0 0 .2rem var(--boxoutBg),0 0 0 calc(.2rem + 2px) rgb(var(--primaryColor))}ul#themes li.light{background:#fff;color:#000}ul#themes li.dark{background:#111;color:#fff}ul#themes li.yellow-on-black{background:#000;color:#ebd90e}ul#themes li.black-on-yellow{background:#ebd90e;color:#000}ul#themes li.black-on-red{background:#de7777;color:#000}ul#themes li.black-on-blue{background:#64a8e1;color:#000}ul#fonts li{border:2px solid rgba(var(--primaryColor), 0.2);margin-bottom:.5rem;border-radius:.3rem;line-height:1;padding:.3rem .5rem;cursor:pointer}ul#fonts li.selected{border-color:rgba(var(--primaryColor), 1)}ul#readability li{display:flex;justify-content:space-between;align-items:center}ul#readability .label{flex:1}ul#readability .btn{display:inline-block;width:1.5rem;line-height:1.1rem;box-sizing:border-box;text-align:center;border:2px solid rgba(var(--primaryColor), 0.2);border-radius:.2rem;padding:0 .3rem .1rem;margin-left:.5rem;font-weight:500;font-size:.8rem;cursor:pointer}ul#readability .btn.reset{width:auto;border-color:rgba(0,0,0,0)}ul#readability .btn.reset:not(.disabled){background:var(--errorColor);color:#fff}ul#readability .btn.reset.disabled{background:rgba(var(--primaryColor), 0.1)}ul#readability .btn.disabled{opacity:.5;cursor:default}@media print{.hamburger-icon{display:none !important}.pagebreak{break-after:page}h1,h2,h3,h4,h5,h6{break-after:avoid}.cover{height:95vh;position:relative}.cover .logos{position:absolute;bottom:0;width:100%;display:flex;flex-direction:row-reverse;align-items:baseline;justify-content:space-between}.cover .hexagons{width:60%}.cover .dag-logo{width:25%;bottom:1rem}}#environment label span{padding:0 1em 0 .25em}.platform{display:none}html.platform-mac .platform.mac,html.platform-windows .platform.windows,html.platform-linux .platform.linux{display:block}.program{display:none}html.program-cli .program.cli,html.program-github-desktop .program.github-desktop{display:block} +*{margin:0;border:0;padding:0}:root{--bg: white;--textColor: #333;--fadedTextColor: #888;--errorColor: #b30c00;--linkColor: #0075b0;--primaryColor: 0, 0, 0;--highlightColor: #003865;--boxoutBg: #f2f2f2;--boxoutHighlightColor: #e2e2e2;--boxoutFadedTextColor: #444;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}html.theme-dark{--bg: #111;--textColor: #ccc;--fadedTextColor: #666;--errorColor: #b30c00;--linkColor: #0075b0;--primaryColor: 255, 255, 255;--highlightColor: #7a6855;--boxoutBg: #222;--boxoutHighlightColor: #333;--boxoutFadedTextColor: #999;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}html.theme-yellow-on-black{--bg: #111;--textColor: #ebd90e;--fadedTextColor: #8b8008;--errorColor: #b30c00;--linkColor: #b06c96;--primaryColor: 235, 217, 14;--highlightColor: #ebd90e;--boxoutBg: #222;--boxoutHighlightColor: #333;--boxoutFadedTextColor: #8b8008;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}html.theme-black-on-yellow{--bg: #ebd90e;--textColor: #000;--fadedTextColor: #333333;--errorColor: #b30c00;--linkColor: #951272;--primaryColor: 0, 0, 0;--highlightColor: black;--boxoutBg: #ddcc0d;--boxoutHighlightColor: #c4b50c;--boxoutFadedTextColor: #4d4d4d;--taskBg: rgba(125, 34, 57, 0.2);--taskFg: #7d2239}html.theme-black-on-red{--bg: #de7777;--textColor: black;--fadedTextColor: #333333;--errorColor: #b30c00;--linkColor: #ffb948;--primaryColor: 0, 0, 0;--highlightColor: black;--boxoutBg: #db6b6b;--boxoutHighlightColor: #d44e4e;--boxoutFadedTextColor: #333333;--taskBg: rgba(0, 56, 101, 0.1);--taskFg: #003865}html.theme-black-on-blue{--bg: #64a8e1;--textColor: black;--fadedTextColor: #333333;--errorColor: #b30c00;--linkColor: #ffdc36;--primaryColor: 0, 0, 0;--highlightColor: black;--boxoutBg: #4f9cdd;--boxoutHighlightColor: #2884d0;--boxoutFadedTextColor: #333333;--taskBg: rgba(149, 18, 114, 0.1);--taskFg: #951272}*::-webkit-scrollbar{width:15px}*{scrollbar-width:thin;scroll-behavior:smooth;scrollbar-color:var(--textColor) var(--bg)}*::-webkit-scrollbar-track{background:var(--bg)}*::-webkit-scrollbar-thumb{border-radius:7.5px;border:5px solid;background-color:var(--textColor);border-color:var(--bg)}html{background:var(--bg)}body{color:var(--textColor)}#root{overflow-x:hidden}.hamburger-icon{position:absolute;width:22px;height:19px;fill:var(--highlightColor);top:2.5rem;cursor:pointer;opacity:.75;transition:opacity .2s}.hamburger-icon:hover{opacity:1}.logo>.hamburger-icon{right:1rem}#root>.hamburger-icon{position:fixed;left:2rem}aside{position:fixed;top:0;height:100%;width:18rem;overflow-y:scroll;overflow-x:hidden;background:var(--boxoutBg);transition:margin-left .2s;scroll-behavior:smooth;scrollbar-color:var(--boxoutHighlightColor) var(--boxoutBg)}aside::-webkit-scrollbar-track{background:var(--boxoutBg)}aside::-webkit-scrollbar-thumb{background-color:var(--boxoutBg);border-color:var(--boxoutBg);transition:background-color .2s}aside:hover::-webkit-scrollbar-thumb{background-color:var(--boxoutHighlightColor)}#root.hide-sidebar aside{margin-left:-18rem}aside #toc{padding-top:2rem}main{flex:1;overflow:auto;transform:translateX(9rem);transition:transform .2s}#root.hide-sidebar main{transform:translateX(0)}main>.wrapper{margin-top:0;margin-right:auto;margin-bottom:5rem;margin-left:auto}html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-size:18px;font-weight:400;line-height:1.75;text-rendering:geometricPrecision;color:#222}main{font-size:calc(1rem*var(--fontSize, 1));line-height:calc(1.75*var(--lineSpacing, 1));letter-spacing:calc(var(--letterSpacing, 0)*1em)}main>.wrapper{width:calc(66%*var(--lineWidth, 1))}#root.pdf main{font-size:14px}#root.pdf main>.wrapper{width:90%}@media(max-width: 1000px){main>.wrapper{width:calc(85%*var(--lineWidth, 1))}}p{margin-bottom:1em}a{font-weight:600;text-decoration:none;color:var(--linkColor)}h1,h2,h3,h4,h5,h6,.boxout .title{font-weight:700;line-height:1.2;margin:1.5em 0 1em}h1{color:rgb(var(--primaryColor))}h2,h3,h4,h5,h6{color:var(--highlightColor)}h2{font-size:2.25em;margin:1em 0 .5em}h3{font-size:1.5em;margin:2em 0 .5em}h4{font-size:1.25em;margin-top:2em}h2+h3,h3+h4,h4+h5,h5+h6{margin-top:0}h2+.boxout,h3+.boxout,h4+.boxout,h5+.boxout{margin-top:0}h1 .link,h2 .link,h3 .link,h4 .link,h5 .link,h6 .link{display:inline-block;vertical-align:middle;width:1.1em;height:.6em;margin-top:-0.15em;margin-left:-1.1em;opacity:0;transition:opacity .2s}h1 .link .icon,h2 .link .icon,h3 .link .icon,h4 .link .icon,h5 .link .icon,h6 .link .icon{display:block;width:1.1em;height:.6em;fill:rgb(var(--primaryColor))}h1:hover .link,h2:hover .link,h3:hover .link,h4:hover .link,h5:hover .link,h6:hover .link{opacity:.5}ul,ol{padding:0rem 2rem 1rem}li:not(:last-child){padding-bottom:.5rem}#view-options-toggle,.boxout .type,.answer-trigger{display:inline-block;padding:.3rem .8rem .25rem;font-size:.8rem;line-height:1.5rem;font-weight:bold;color:rgba(var(--primaryColor), 1);background:rgba(var(--primaryColor), 0.1);border-radius:.2rem;user-select:none;transition:background .2s}#view-options-toggle:hover,.boxout .type:hover,.answer-trigger:hover{background:rgba(var(--primaryColor), 0.2)}h1{font-size:3.3em;margin:.5em 0 1.45em}h1 span{display:block;font-size:.4em;opacity:.4;margin-top:1em}.cover .logos{display:flex;flex-direction:row-reverse;align-items:baseline;justify-content:space-between}.cover .hexagons{display:block;width:30%;margin-bottom:2rem}.cover .hexagons .hex{stroke:rgb(var(--primaryColor))}.cover .hexagons .hex-logo{fill:rgb(var(--primaryColor))}.cover .hexagons .active .hex{fill:rgb(var(--primaryColor))}.cover .hexagons .active .hex-logo{fill:var(--bg)}.cover .dag-logo{display:block;width:20%;margin-bottom:5rem;position:relative;bottom:1rem}.cover .dag-logo .primary{fill:rgb(var(--primaryColor))}@media(max-width: 1000px){h1{font-size:3em;margin:2em 0 1em}.cover .logos{display:block}.cover .hexagons{width:100%}.cover .dag-logo{width:50%;bottom:0}}.logo{position:relative;padding:1.5rem 2rem 2rem}.logo .logo-wrapper{display:flex;align-items:center;width:70%}.logo .crest{width:25%;margin-right:10%}.logo .crest path.dark-only{opacity:0}html.theme-dark .logo .crest path.dark-only,html.theme-yellow-on-black .logo .crest path.dark-only{opacity:1}.logo .uofg{width:60%}html.theme-dark .logo .uofg path,html.theme-yellow-on-black .logo .uofg path{fill:#fff}aside nav li{list-style:none;padding:0}aside nav p{margin:0;line-height:1.4}aside nav>ul{padding:0 calc(2rem - 15px) 2rem 2rem}aside nav>ul>li{padding-bottom:1.5rem !important}aside nav ul ul{padding:.5rem}aside nav ul ul a{color:var(--boxoutFadedTextColor);font-weight:400}.table-wrapper{overflow:auto;margin:.5rem 0 2rem}.table-wrapper table{margin:0 auto}table{border-collapse:collapse;border-radius:.4rem;margin:.5rem 0 2rem;background:var(--boxoutBg)}.boxout table{background:var(--bg)}table th,table td{border:2px solid var(--boxoutHighlightColor);padding:.5rem 2rem .5rem 1rem;text-align:left;vertical-align:top}table td{color:var(--boxoutFadedTextColor)}table th{border-top-width:0}table th:first-child,table td:first-child{border-left-width:0}table tr:last-child td{border-bottom-width:0}table th:last-child,table td:last-child{border-right-width:0}table code{background:none;padding:0;margin:0;color:var(--boxoutFadedTextColor)}img{display:block;width:100%;height:auto}figure{text-align:center;margin:3rem auto}figure .img-bg{display:inline-block;background:#fff;width:75%;max-width:100%;height:auto}figure svg.pdftex,figure svg.knitr-svg{margin-bottom:0}figure figcaption{margin-bottom:3rem;padding-top:.5rem}figure figcaption a{font-style:italic;color:var(--fadedTextColor)}figure figcaption a .caption-count{color:var(--highlightColor)}svg.pdftex,svg.knitr-svg{display:block}.interactive-element{width:75%;max-width:100%;height:auto;margin-top:3rem;margin-right:auto;margin-bottom:1rem;margin-left:auto}.interactive-element svg{display:block;margin:0 auto}.math svg{max-width:100%}svg.block-math{display:block;width:100%;padding:1rem 0}svg.inline-math{vertical-align:middle;font-size:.9em}svg.inline-math svg{max-width:100%}code{vertical-align:baseline;padding:.1rem .3rem .2rem;font-family:monospace;background:var(--boxoutBg);border-radius:.2rem}.code-wrapper{margin-bottom:1rem;padding:1rem;border-radius:.3rem;background:#444;color:#ccc;overflow:auto}.code-wrapper>h6.console-heading{margin:0 0 .5rem;color:#b06c96}.code-wrapper pre{font-family:monospace;white-space:pre-wrap}.code-wrapper code{display:block;padding:0;margin:0;background:rgba(0,0,0,0)}.code-wrapper[class$=error-output]{background:var(--errorColor);color:#fff}.code-wrapper[class$=error-output]>h6.console-heading{color:#fff}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#998066}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol{color:#d1949e}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#bde052}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string,.token.variable{color:#f5b83d}.token.atrule,.token.attr-value,.token.keyword{color:#d1949e}.token.regex,.token.important{color:#e90}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}.boxout{padding:2rem;margin:1rem 0 1.5rem;border-radius:.4rem;overflow:hidden;background:var(--boxoutBg)}.boxout .type{margin-bottom:1rem;background:var(--bg);color:rgb(var(--primaryColor))}.boxout h3{font-size:1rem}.boxout .type+h3{margin-top:.5rem}.boxout>*:last-child{margin-bottom:0}.boxout.task{background:var(--taskBg)}.boxout.task .type{background:var(--taskFg);color:#fff}.boxout.task h3{color:var(--taskFg)}.boxout.task .answer-trigger{cursor:pointer}#root.pdf .boxout.task .answer-trigger{display:none}.boxout.task .answer-reveal{display:none;margin:2rem -2rem -2rem -2rem;padding:2rem;background:var(--boxoutBg)}.boxout.task .answer-reveal.show{display:block}.boxout.task .answer-reveal>*:last-child{margin-bottom:0}.boxout.video{display:flex;justify-content:space-between;align-items:flex-start;text-decoration:none;margin-bottom:1.5rem;font-weight:400}.boxout.video .content{flex:1}.boxout.video .title{display:block;margin:.2rem 0 .5rem;color:var(--highlightColor)}.boxout.video .duration{color:var(--fadedTextColor)}.boxout.video .duration strong{padding-right:.5em}.boxout.video .thumbnail{display:block;max-width:25%;margin-left:2rem;box-shadow:0 0 0 .3rem rgba(var(--primaryColor), 0.15);border-radius:.2rem;overflow:hidden}.boxout.video .thumbnail img{display:block}.boxout.video .desc{flex:1}.boxout.video .desc .title{font-weight:700;padding:0 0 1rem}.boxout .boxout.video{padding-left:0;padding-right:.3rem;background:rgba(0,0,0,0)}.boxout .boxout.video:last-child{padding-bottom:.3rem}.columns{display:flex}.columns .column{flex:1}.columns .column:nth-child(2n+1){padding-right:.5rem}.columns .column:nth-child(2n){padding-left:.5rem}@media(max-width: 800px){.columns{flex-direction:column}}#view-options-toggle{margin:0 2rem;cursor:pointer}#view-options{display:none;user-select:none}html.view-options-open #toc{display:none}html.view-options-open #view-options{display:block}#view-options{padding:0 calc(2rem - 15px) 2rem 2rem}#view-options h3{margin:2rem 0 0 0;font-size:1rem;font-weight:600;line-height:1.4;color:rgb(var(--primaryColor))}#view-options ul{padding:1rem 0}#view-options ul li{list-style:none}ul#themes{display:grid;grid-template-columns:1fr 1fr;gap:.8rem}ul#themes li{padding:.75rem .5rem .5rem;height:4.5rem;border-radius:.3rem;line-height:1.4;cursor:pointer}ul#themes li.selected{box-shadow:0 0 0 .2rem var(--boxoutBg),0 0 0 calc(.2rem + 2px) rgb(var(--primaryColor))}ul#themes li.light{background:#fff;color:#000}ul#themes li.dark{background:#111;color:#fff}ul#themes li.yellow-on-black{background:#000;color:#ebd90e}ul#themes li.black-on-yellow{background:#ebd90e;color:#000}ul#themes li.black-on-red{background:#de7777;color:#000}ul#themes li.black-on-blue{background:#64a8e1;color:#000}ul#fonts li{border:2px solid rgba(var(--primaryColor), 0.2);margin-bottom:.5rem;border-radius:.3rem;line-height:1;padding:.3rem .5rem;cursor:pointer}ul#fonts li.selected{border-color:rgba(var(--primaryColor), 1)}ul#readability li{display:flex;justify-content:space-between;align-items:center}ul#readability .label{flex:1}ul#readability .btn{display:inline-block;width:1.5rem;line-height:1.1rem;box-sizing:border-box;text-align:center;border:2px solid rgba(var(--primaryColor), 0.2);border-radius:.2rem;padding:0 .3rem .1rem;margin-left:.5rem;font-weight:500;font-size:.8rem;cursor:pointer}ul#readability .btn.reset{width:auto;border-color:rgba(0,0,0,0)}ul#readability .btn.reset:not(.disabled){background:var(--errorColor);color:#fff}ul#readability .btn.reset.disabled{background:rgba(var(--primaryColor), 0.1)}ul#readability .btn.disabled{opacity:.5;cursor:default}@media print{.hamburger-icon{display:none !important}.pagebreak{break-after:page}h1,h2,h3,h4,h5,h6{break-after:avoid}.cover{height:95vh;position:relative}.cover .logos{position:absolute;bottom:0;width:100%;display:flex;flex-direction:row-reverse;align-items:baseline;justify-content:space-between}.cover .hexagons{width:60%}.cover .dag-logo{width:25%;bottom:1rem}}#environment label span{padding:0 1em 0 .25em}.platform:not(.show){display:none}html.platform-mac .platform.mac,html.platform-windows .platform.windows,html.platform-linux .platform.linux{display:block}.program:not(.show){display:none}html.program-cli .program.cli,html.program-github-desktop .program.github-desktop{display:block}