diff --git a/compiler/webpack.config.js b/compiler/webpack.config.js index cc2d789b..6511d6f4 100644 --- a/compiler/webpack.config.js +++ b/compiler/webpack.config.js @@ -68,7 +68,7 @@ export default { }, path.join(__dirname, 'package.json') ), - new InlineEnvironmentVariablesPlugin({ VERSION: '1.1.29' }), + new InlineEnvironmentVariablesPlugin({ VERSION: '1.1.30' }), new CopyPlugin({ patterns: [ { from: './src/knitr/knitr.R', to: './' }, diff --git a/release/cli.js b/release/cli.js index 56213c44..48e8364e 100755 --- a/release/cli.js +++ b/release/cli.js @@ -363,17 +363,21 @@ __webpack_require__.a(module, async (__webpack_handle_async_dependencies__) => { /* harmony export */ }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1017); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var mime_lite_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(799); -/* harmony import */ var node_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6544); -/* harmony import */ var to_vfile__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1252); -/* harmony import */ var unist_util_visit__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6016); -/* harmony import */ var _pdf_pdf_to_svg__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(511); -/* harmony import */ var _utils_cache_to_file__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2303); -/* harmony import */ var _utils_get_asset_hast__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2430); -/* harmony import */ var _utils_message__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(153); -/* harmony import */ var _utils_utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(8061); -var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_utils_utils__WEBPACK_IMPORTED_MODULE_9__, to_vfile__WEBPACK_IMPORTED_MODULE_3__, _pdf_pdf_to_svg__WEBPACK_IMPORTED_MODULE_5__, node_fetch__WEBPACK_IMPORTED_MODULE_2__, _utils_cache_to_file__WEBPACK_IMPORTED_MODULE_6__, _utils_get_asset_hast__WEBPACK_IMPORTED_MODULE_7__, mime_lite_js__WEBPACK_IMPORTED_MODULE_1__, unist_util_visit__WEBPACK_IMPORTED_MODULE_4__]); -([_utils_utils__WEBPACK_IMPORTED_MODULE_9__, to_vfile__WEBPACK_IMPORTED_MODULE_3__, _pdf_pdf_to_svg__WEBPACK_IMPORTED_MODULE_5__, node_fetch__WEBPACK_IMPORTED_MODULE_2__, _utils_cache_to_file__WEBPACK_IMPORTED_MODULE_6__, _utils_get_asset_hast__WEBPACK_IMPORTED_MODULE_7__, mime_lite_js__WEBPACK_IMPORTED_MODULE_1__, unist_util_visit__WEBPACK_IMPORTED_MODULE_4__] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__); +/* harmony import */ var base64_arraybuffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2845); +/* harmony import */ var image_size__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7632); +/* harmony import */ var mime_lite_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(799); +/* harmony import */ var node_fetch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6544); +/* harmony import */ var to_vfile__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1252); +/* harmony import */ var unist_util_visit__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6016); +/* harmony import */ var _pdf_pdf_to_svg__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(511); +/* harmony import */ var _utils_cache_to_file__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2303); +/* harmony import */ var _utils_get_asset_hast__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2430); +/* harmony import */ var _utils_message__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(153); +/* harmony import */ var _utils_utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8061); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_utils_utils__WEBPACK_IMPORTED_MODULE_11__, to_vfile__WEBPACK_IMPORTED_MODULE_5__, _pdf_pdf_to_svg__WEBPACK_IMPORTED_MODULE_7__, base64_arraybuffer__WEBPACK_IMPORTED_MODULE_1__, node_fetch__WEBPACK_IMPORTED_MODULE_4__, _utils_cache_to_file__WEBPACK_IMPORTED_MODULE_8__, _utils_get_asset_hast__WEBPACK_IMPORTED_MODULE_9__, image_size__WEBPACK_IMPORTED_MODULE_2__, mime_lite_js__WEBPACK_IMPORTED_MODULE_3__, unist_util_visit__WEBPACK_IMPORTED_MODULE_6__]); +([_utils_utils__WEBPACK_IMPORTED_MODULE_11__, to_vfile__WEBPACK_IMPORTED_MODULE_5__, _pdf_pdf_to_svg__WEBPACK_IMPORTED_MODULE_7__, base64_arraybuffer__WEBPACK_IMPORTED_MODULE_1__, node_fetch__WEBPACK_IMPORTED_MODULE_4__, _utils_cache_to_file__WEBPACK_IMPORTED_MODULE_8__, _utils_get_asset_hast__WEBPACK_IMPORTED_MODULE_9__, image_size__WEBPACK_IMPORTED_MODULE_2__, mime_lite_js__WEBPACK_IMPORTED_MODULE_3__, unist_util_visit__WEBPACK_IMPORTED_MODULE_6__] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__); + + @@ -411,13 +415,13 @@ function embedAssets(ctx) { } } catch (_err) { const err = _err; - (0,_utils_message__WEBPACK_IMPORTED_MODULE_8__/* .failMessage */ .Ob)(file, err?.message || '', node.position); + (0,_utils_message__WEBPACK_IMPORTED_MODULE_10__/* .failMessage */ .Ob)(file, err?.message || '', node.position); } } return async (tree, file) => { const transformations = []; - (0,unist_util_visit__WEBPACK_IMPORTED_MODULE_4__.visit)(tree, 'element', node => { + (0,unist_util_visit__WEBPACK_IMPORTED_MODULE_6__.visit)(tree, 'element', node => { if (node.tagName === 'img') { transformations.push(embed(node, file)); } @@ -428,25 +432,30 @@ function embedAssets(ctx) { async function embedImage(node, ctx, file) { const src = getImageSrc(node); - const mime = mime_lite_js__WEBPACK_IMPORTED_MODULE_1__["default"].getType(path__WEBPACK_IMPORTED_MODULE_0___default().extname(src)); + const mime = mime_lite_js__WEBPACK_IMPORTED_MODULE_3__["default"].getType(path__WEBPACK_IMPORTED_MODULE_0___default().extname(src)); try { const image = await getImage(src, ctx); + const { + width + } = (0,image_size__WEBPACK_IMPORTED_MODULE_2__["default"])(Buffer.from(image, 'base64')); node.properties = { ...node.properties, - src: `data:${mime};base64,${image}` + src: `data:${mime};base64,${image}`, + style: [`max-width: ${width}px`] }; } catch (err) { - (0,_utils_message__WEBPACK_IMPORTED_MODULE_8__/* .failMessage */ .Ob)(file, `Image not found: ${src}`); + console.log(err); + (0,_utils_message__WEBPACK_IMPORTED_MODULE_10__/* .failMessage */ .Ob)(file, `Image not found: ${src}`); } } async function embedSvg(imgNode, ctx) { const src = getImageSrc(imgNode); - const contents = await (0,_utils_utils__WEBPACK_IMPORTED_MODULE_9__/* .readFile */ .pJ)(src); + const contents = await (0,_utils_utils__WEBPACK_IMPORTED_MODULE_11__/* .readFile */ .pJ)(src); const idx = contents.indexOf(' { /* harmony import */ var mathjax_full_js_mathjax_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2338); /* harmony import */ var _linter_assert_no_tex_tabular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5187); /* harmony import */ var _utils_message__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(153); -var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([mathjax_full_js_core_MathItem_js__WEBPACK_IMPORTED_MODULE_1__, mathjax_full_js_mathjax_js__WEBPACK_IMPORTED_MODULE_6__, mathjax_full_js_core_MmlTree_SerializedMmlVisitor_js__WEBPACK_IMPORTED_MODULE_2__, mathjax_full_js_handlers_html_js__WEBPACK_IMPORTED_MODULE_3__, mathjax_full_js_adaptors_liteAdaptor_js__WEBPACK_IMPORTED_MODULE_0__, mathjax_full_js_input_tex_AllPackages_js__WEBPACK_IMPORTED_MODULE_5__, mathjax_full_js_input_tex_js__WEBPACK_IMPORTED_MODULE_4__]); -([mathjax_full_js_core_MathItem_js__WEBPACK_IMPORTED_MODULE_1__, mathjax_full_js_mathjax_js__WEBPACK_IMPORTED_MODULE_6__, mathjax_full_js_core_MmlTree_SerializedMmlVisitor_js__WEBPACK_IMPORTED_MODULE_2__, mathjax_full_js_handlers_html_js__WEBPACK_IMPORTED_MODULE_3__, mathjax_full_js_adaptors_liteAdaptor_js__WEBPACK_IMPORTED_MODULE_0__, mathjax_full_js_input_tex_AllPackages_js__WEBPACK_IMPORTED_MODULE_5__, mathjax_full_js_input_tex_js__WEBPACK_IMPORTED_MODULE_4__] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([mathjax_full_js_core_MathItem_js__WEBPACK_IMPORTED_MODULE_1__, mathjax_full_js_input_tex_AllPackages_js__WEBPACK_IMPORTED_MODULE_5__, mathjax_full_js_input_tex_js__WEBPACK_IMPORTED_MODULE_4__, mathjax_full_js_mathjax_js__WEBPACK_IMPORTED_MODULE_6__, mathjax_full_js_handlers_html_js__WEBPACK_IMPORTED_MODULE_3__, mathjax_full_js_core_MmlTree_SerializedMmlVisitor_js__WEBPACK_IMPORTED_MODULE_2__, mathjax_full_js_adaptors_liteAdaptor_js__WEBPACK_IMPORTED_MODULE_0__]); +([mathjax_full_js_core_MathItem_js__WEBPACK_IMPORTED_MODULE_1__, mathjax_full_js_input_tex_AllPackages_js__WEBPACK_IMPORTED_MODULE_5__, mathjax_full_js_input_tex_js__WEBPACK_IMPORTED_MODULE_4__, mathjax_full_js_mathjax_js__WEBPACK_IMPORTED_MODULE_6__, mathjax_full_js_handlers_html_js__WEBPACK_IMPORTED_MODULE_3__, mathjax_full_js_core_MmlTree_SerializedMmlVisitor_js__WEBPACK_IMPORTED_MODULE_2__, mathjax_full_js_adaptors_liteAdaptor_js__WEBPACK_IMPORTED_MODULE_0__] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__); @@ -1570,7 +1579,6 @@ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([math - // import { assertNoTexTabular } from '../linter/assert-no-tex-tabular'; // This custom MathJax implementation has had to diverge from the provided demos found // here: https://github.com/mathjax/MathJax-demos-node, because they are all focused on @@ -1588,101 +1596,64 @@ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([math function texToAliasDirective(file, ctx) { // simple regex tests - // why? (0,_linter_assert_no_tex_tabular__WEBPACK_IMPORTED_MODULE_7__/* .assertNoTexTabular */ .d)(file); const md = file.value; - const tex = new mathjax_full_js_input_tex_js__WEBPACK_IMPORTED_MODULE_4__.TeX({ - // Bussproofs requires an output jax - packages: mathjax_full_js_input_tex_AllPackages_js__WEBPACK_IMPORTED_MODULE_5__.AllPackages.filter(name => name !== 'bussproofs'), - // Allow numbered references - tags: 'ams', - // Allow single $ delimiters - inlineMath: [['$', '$'], ['\\(', '\\)']], - displayMath: [['$$', '$$'], [`\\[`, `\\]`]] - }); - const store = buildMmlStore(md, tex); // console.log(store); - - const result = replaceTexWithPlaceholder(md, tex, store, file); // add store to ctx - - ctx.mmlStore = store; // replace md in VFile - - file.value = postParse(result); - return file; -} // This is based on https://github.com/mathjax/MathJax-demos-node/blob/f70342b69533dbc24b460f6d6ef341dfa7856414/direct/tex2mml-page -// except I don't return the HTML, instead I compile a list of the extracted LaTeX converted to MathML - -function buildMmlStore(md, tex) { const store = []; const adaptor = (0,mathjax_full_js_adaptors_liteAdaptor_js__WEBPACK_IMPORTED_MODULE_0__.liteAdaptor)(); - (0,mathjax_full_js_handlers_html_js__WEBPACK_IMPORTED_MODULE_3__.RegisterHTMLHandler)(adaptor); const visitor = new mathjax_full_js_core_MmlTree_SerializedMmlVisitor_js__WEBPACK_IMPORTED_MODULE_2__.SerializedMmlVisitor(); - - function storeMml({ - math - }) { - for (const item of Array.from(math)) { - // convert to MML - const mml = visitor.visitTree(item.root); - store.push(mml); - const tree = adaptor.parse('**unused**', 'text/html'); - item.typesetRoot = adaptor.firstChild(adaptor.body(tree)); - } - } - + (0,mathjax_full_js_handlers_html_js__WEBPACK_IMPORTED_MODULE_3__.RegisterHTMLHandler)(adaptor); const doc = mathjax_full_js_mathjax_js__WEBPACK_IMPORTED_MODULE_6__.mathjax.document(md, { - InputJax: tex, + InputJax: new mathjax_full_js_input_tex_js__WEBPACK_IMPORTED_MODULE_4__.TeX({ + // Bussproofs requires an output jax + packages: mathjax_full_js_input_tex_AllPackages_js__WEBPACK_IMPORTED_MODULE_5__.AllPackages.filter(name => name !== 'bussproofs'), + // Allow numbered references + tags: 'ams', + // Allow single $ delimiters + inlineMath: [['$', '$'], ['\\(', '\\)']], + displayMath: [['$$', '$$'], [`\\[`, `\\]`]] + }), + // wrap verbatim latex with
+ ignoreHtmlClass: 'mathjax-ignore', renderActions: { - typeset: [mathjax_full_js_core_MathItem_js__WEBPACK_IMPORTED_MODULE_1__.STATE.TYPESET, storeMml] - } - }); - doc.render(); - return store; -} - -function replaceTexWithPlaceholder(md, tex, store, file) { - // Extract the LaTeX from the document again - const extractedLatex = tex.findMath([md]); // Replace it with a placeholder for use later - - return extractedLatex.map((item, idx) => ({ ...item, - idx - })).reverse().reduce((acc, item) => { - const placeholder = createPlaceholder(item, store, file); - const prev = acc.slice(0, item.start.n); - const next = acc.slice(item.end.n); - return prev + placeholder + next; - }, md); -} - -function createPlaceholder(item, store, file) { - // escaped dollar sign... - if (item.math === '$') { - return '$'; - } // double backslash... - - - if (item.math === '\\') { - return '\\\\'; - } - - const mml = store[item.idx]; // why? - - if (!mml) { - return ''; - } - - assertNoMmlError(mml, file); // debug - // console.log(item.math, mml); - // reference link... + typeset: [mathjax_full_js_core_MathItem_js__WEBPACK_IMPORTED_MODULE_1__.STATE.TYPESET, ({ + math + }) => { + for (const item of Array.from(math)) { + let newMarkdown = ''; // convert to MathML + + const mml = visitor.visitTree(item.root); + assertNoMmlError(mml, file); // escaped dollar sign... + + if (item.math === '$') { + newMarkdown = '$'; + } // double backslash... + else if (item.math === '\\') { + newMarkdown = '\\\\'; + } // reference link... + else if (isReferenceLink(item.math)) { + const refNum = extractRefNumFromMml(mml, item.math, file); + const anchor = extractAnchorLinkFromMml(mml, item.math, file); + newMarkdown = `[${refNum}](${anchor})`; + } // normal use case (equation)... + else { + store.push(mml); + const type = item.display ? 'blockMath' : 'inlineMath'; + newMarkdown = `:${type}[${store.length - 1}]`; + } - if (isReferenceLink(item.math)) { - const refNum = extractRefNumFromMml(mml, item.math, file); - const anchor = extractAnchorLinkFromMml(mml, item.math, file); - return `[${refNum}](${anchor})`; - } // normal use case (equation)... + const tree = adaptor.parse(newMarkdown, 'text/html'); + item.typesetRoot = adaptor.firstChild(adaptor.body(tree)); + } + }] + } + }); // add store to ctx + ctx.mmlStore = store; + doc.render(); // replace md in VFile - const type = item.display ? 'blockMath' : 'inlineMath'; - return `:${type}[${item.idx}]`; + const result = adaptor.innerHTML(adaptor.body(doc.document)); + file.value = postParse(result); + return file; } function assertNoMmlError(mml, file) { @@ -1725,9 +1696,14 @@ function extractAnchorLinkFromMml(mml, tex, file) { function postParse(html) { let result = html; + result = unprotectHtml(result); result = removeUnresolvedLabels(result); - console.log(result); return result; +} // https://github.com/mathjax/MathJax-src/blob/41565a97529c8de57cb170e6a67baf311e61de13/ts/adaptors/lite/Parser.ts#L399-L403 + + +function unprotectHtml(html) { + return html.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); } function removeUnresolvedLabels(html) { @@ -2830,7 +2806,7 @@ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pag - // import { aliasDirectiveToText } from '../latex/directive-to-text'; + // import { aliasDirectiveToTex } from '../latex/directive-to-tex'; @@ -2852,7 +2828,7 @@ async function mdastPhase(file, ctx) { className: 'link' } }) // custom plugins: - .use(_embed_asset_url__WEBPACK_IMPORTED_MODULE_10__/* .embedAssetUrl */ .Z).use(_youtube_videos__WEBPACK_IMPORTED_MODULE_13__/* .youtubeVideos */ .b).use(_latex_directive_to_svg__WEBPACK_IMPORTED_MODULE_7__/* .aliasDirectiveToSvg */ .F, ctx) // .use(aliasDirectiveToText, ctx) + .use(_embed_asset_url__WEBPACK_IMPORTED_MODULE_10__/* .embedAssetUrl */ .Z).use(_youtube_videos__WEBPACK_IMPORTED_MODULE_13__/* .youtubeVideos */ .b).use(_latex_directive_to_svg__WEBPACK_IMPORTED_MODULE_7__/* .aliasDirectiveToSvg */ .F, ctx) // .use(aliasDirectiveToTex, ctx) .use(_code_blocks__WEBPACK_IMPORTED_MODULE_9__/* .codeBlocks */ .r, ctx).use(_images__WEBPACK_IMPORTED_MODULE_11__/* .images */ .W, ctx).use(_pagebreaks__WEBPACK_IMPORTED_MODULE_12__/* .pagebreaks */ .m); const parsed = processor.parse(file); return processor.run(parsed, file); @@ -3440,9 +3416,7 @@ function reformatPandocSimpleTables(contents) { // preserving index in loop for (var idx = lines.length - 1; idx >= 0; idx--) { - const line = lines[idx]; - - if (isValidPandocSimpleTableSeparator(line, idx)) { + if (isValidPandocSimpleTableSeparator(lines, idx)) { const { startIdx, count @@ -3456,21 +3430,26 @@ function reformatPandocSimpleTables(contents) { return lines.join(os__WEBPACK_IMPORTED_MODULE_0__.EOL); } -function isValidPandocSimpleTableSeparator(line, idx) { +function isValidPandocSimpleTableSeparator(lines, idx, isEnd) { + const line = lines[idx] || ''; + if (idx === 0 || !/-{2,}/g.test(line) || !/^[\s|-]+$/.test(line)) { return false; } - return getColumnIndexes(line).length > 1; -} + if (getColumnIndexes(line).length <= 1) { + return false; + } -function convertLines(lines) { - const table = parseTable(lines); - const align = getColumnAlignment(table[0]); - const result = (0,markdown_table__WEBPACK_IMPORTED_MODULE_1__.markdownTable)(table, { - align - }); - return [...result.split(os__WEBPACK_IMPORTED_MODULE_0__.EOL), '']; + if (!isEnd) { + const nextLine = lines[idx + 1] || ''; + + if (nextLine.trim() === '') { + return false; + } + } + + return true; } function getTableBounds(arr, idx) { @@ -3483,12 +3462,28 @@ function getTableBounds(arr, idx) { }; } -function parseTable(tableLines) { - const [titles, separator, ...body] = tableLines; +function convertLines(lines) { + const table = parseTable(lines); + const align = getColumnAlignment(table[0]); + const result = (0,markdown_table__WEBPACK_IMPORTED_MODULE_1__.markdownTable)(table, { + align + }); + return [...result.split(os__WEBPACK_IMPORTED_MODULE_0__.EOL), '']; +} + +function parseTable(lines) { + const [titles, separator, ...body] = lines; const columnIndexes = getColumnIndexes(separator); const titleCells = parseTitleRow(titles, columnIndexes); - const bodyCells = body.map(line => parseBodyRow(line, columnIndexes)).reduce(multilineReducer, []); - return [titleCells, ...bodyCells]; + const rows = body.map(line => parseBodyRow(line, columnIndexes)); + const hasEndSeparator = isValidPandocSimpleTableSeparator(body, body.length - 1, true); + + if (hasEndSeparator) { + return [titleCells, ...rows.slice(0, -1)]; + } + + const multilineRows = rows.reduce(multilineReducer, []); + return [titleCells, ...multilineRows]; } function getColumnIndexes(line) { @@ -3539,7 +3534,7 @@ function multilineReducer(acc, row) { } }); } else { - acc.push(row); + acc.push(row.slice()); } return acc; @@ -3642,7 +3637,7 @@ async function checkForLatestVersion() { const response = await (0,node_fetch__WEBPACK_IMPORTED_MODULE_1__["default"])(`https://api.github.com/repos/${repo}/releases/latest`); const json = await response.json(); const latestTag = json.tag_name.replace('v', ''); - const currentVersion = "1.1.29"; + const currentVersion = "1.1.30"; if (latestTag !== currentVersion) { console.log(chalk__WEBPACK_IMPORTED_MODULE_0__["default"].yellow.bold('New version available')); @@ -4265,6 +4260,14 @@ module.exports = import("@mapbox/remark-lint-link-text");; /***/ }), +/***/ 2845: +/***/ ((module) => { + +"use strict"; +module.exports = import("base64-arraybuffer");; + +/***/ }), + /***/ 7564: /***/ ((module) => { @@ -4297,6 +4300,14 @@ module.exports = import("hash-sum");; /***/ }), +/***/ 7632: +/***/ ((module) => { + +"use strict"; +module.exports = import("image-size");; + +/***/ }), + /***/ 626: /***/ ((module) => { diff --git a/release/cli.js.map b/release/cli.js.map index 742b3133..4436af9f 100644 --- a/release/cli.js.map +++ b/release/cli.js.map @@ -1 +1 @@ -{"version":3,"file":"cli.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAmBA;AACA;;AACA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;AACA;AACA;AAHA;AAMA;;AACA;AACA;AAMA;;AAEA;AACA;AAOA;AAEA;AAFA;AAIA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAFA;AAIA;;AAEA;AAOA;AACA;AAMA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;ACtHA;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;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAbA;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;;ACzFA;AAEA;AAiCA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AASA;;;;;;;;;;;;;;;;;;;;;;AChDA;AAEA;AACA;AAEA;AACA;AAUA;AACA;AACA;AAGA;AAAA;AAAA;AACA;;AAEA;AAKA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAHA;AAKA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;;;;;;;;;;;;;;;;;;;;ACzDA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AADA;AAHA;AASA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACrBA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AADA;AAJA;AAUA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACtBA;AAGA;AACA;AACA;;AAGA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;;AACA;AACA;;AACA;AACA;AAZA;AAcA;AACA;AACA;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AACA;AACA;AACA;AAEA;AAFA;AAIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;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;;AAEA;AACA;AACA;AAEA;AAEA;AAFA;AAKA;AAEA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AALA;AAOA;;;;;;;;;;;;;;;;;;;;AC1JA;AACA;AACA;AAIA;AACA;AAEA;AAMA;AACA;AAAA;;AAIA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;ACzBA;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;;;;;;;;;;;;;;;;;ACnEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAHA;AAcA;AACA;;;;;;;;;;;;;;;;;;ACvBA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;AAHA;AAcA;AACA;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AANA;AAJA;AAcA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAFA;AAKA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AARA;AAuBA;;;;;;;;;;;;;;;;;;;;;AC5CA;AACA;AAGA;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;;;;;;;;;;;;;;;;;AC3DA;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;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;AACA;AACA;AACA;;AAEA;AACA;AAGA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACpEA;AACA;AACA;AAEA;AACA;AAIA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAGA;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;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;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;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACzMA;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;;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAVA;AAgBA;;AAEA;;AAGA;;AAGA;AACA;AACA;AAGA;;AACA;AACA;AAEA;AACA;AACA;;AAEA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AADA;AAFA;AAOA;AAEA;AACA;;AAEA;AAMA;AACA;;AAGA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AASA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;;AAGA;AACA;AACA;;AACA;AAGA;AAEA;;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;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;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC3MA;AAGA;AACA;AAEA;AACA;AACA;;AACA;AACA;AACA;;AACA;AACA;;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AC5BA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACjBA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AALA;AAWA;AACA;AACA;;;;;;;;;;;;ACtBA;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;;AAEA;AACA;AACA;AACA;AACA;AAKA;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;;AAUA;AACA;AAEA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACpEA;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;;;;;;;;;;;;;;;;;;AC1HA;AAIA;AACA;AAEA;AAMA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACrBA;AAIA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAGA;AACA;;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;;AAEA;AACA;AAGA;;AAEA;AACA;;AACA;AACA;AACA;;AACA;;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AAIA;AACA;AACA;AACA;;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC/DA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAPA;;AAUA;AACA;AAEA;AAFA;AAIA;;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AALA;AAFA;AAUA;;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AADA;AAGA;AAEA;AACA;AAFA;AAPA;AAJA;AAoBA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAFA;AAIA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAKA;AAAA;AALA;AAUA;AACA;AAAA;AAAA;AAFA;AATA;AAAA;AAsBA;AACA;AACA;;;;;;;;;;;;;;;;AC9CA;AAEA;AACA;AACA;AAIA;AACA;AACA;AAEA;AAGA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAGA;AACA;AAEA;AAEA;AAFA;AAKA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;ACzCA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAFA;AAMA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACdA;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;AAGA;AACA;AACA;AACA;AACA;AAEA;;AAGA;;AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;;AAIA;AACA;AACA;AACA;AACA;AAEA;;AALA;AASA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;;AAEA;AACA;;AACA;AAAA;AAAA;;AACA;AACA;AACA;;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;;;;;;;;;;;;ACpFA;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;AANA;AAQA;;AAEA;AAIA;AAEA;;AACA;AACA;AACA;;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;ACjEA;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;;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AACA;AACA;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AAGA;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;AACA;;;;;;;;;;;;;;;;;;;;ACzGA;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;AACA;AAEA;AAMA;AACA;;AAGA;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AALA;AAOA;;;;;;;;;;;;;;;;ACfA;AAEA;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACZA;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;AAEA;AACA;AAGA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;;AACA;AACA;AACA;;;;;;;;;AC3EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC9SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;;ACzDA;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;;;;;AC5JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;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;;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC1JA;;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;;;;;ACrEA;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/embed-assets.ts","webpack://compiler/./src/hast/index.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/index.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-no-h1.ts","webpack://compiler/./src/linter/assert-no-kbl.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/combined.ts","webpack://compiler/./src/mdast/embed-asset-url.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/youtube-videos.ts","webpack://compiler/./src/pdf/index.ts","webpack://compiler/./src/pdf/pdf-to-svg.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/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/hamburger-icon.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 \"chalk\"","webpack://compiler/external module \"dictionary-en-gb\"","webpack://compiler/external module \"figures\"","webpack://compiler/external module \"hash-sum\"","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 \"sandboxed-module\"","webpack://compiler/external module \"speech-rule-engine\"","webpack://compiler/external module \"svgo\"","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 \"buffer\"","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/./src/pdf/domstubs.js","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/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 { 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';\nimport { texToAliasDirective } from './latex/tex-to-directive';\nimport { createReport, reportErrors } from './linter';\nimport { assertNoKbl } from './linter/assert-no-kbl';\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 mdasts: MdastParent[] = [];\n for (const file of unit.files) {\n const mdast = (await inSituTransforms(file, ctx)) as MdastParent;\n await createReport(file, mdast, ctx);\n mdasts.push(mdast);\n }\n\n const unifiedFile = new VFile();\n\n const result: BuiltUnit = {\n unit,\n md: combineMdFiles(unit),\n files: [...unit.files, unifiedFile],\n };\n\n const mdast = combineMdastTrees(mdasts);\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 // simple regex tests\n assertNoKbl(file);\n\n await knitr(file, ctx);\n preParsePhase(file);\n texToAliasDirective(file, ctx);\n return mdastPhase(file, ctx);\n}\n\nfunction combineMdFiles(unit: Unit) {\n return unit.files.map((o) => o.value).join('\\n\\n');\n}\n\nfunction combineMdastTrees(mdasts: MdastParent[]): Root {\n return {\n type: 'root',\n children: mdasts.flatMap((o) => o.children),\n };\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 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('noCache', {\n type: 'boolean',\n description: 'No cache',\n })\n .option('noTexSvg', {\n type: 'boolean',\n description: 'No Tex Svg',\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\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 noCache: argv.noCache,\n noTexSvg: argv.noTexSvg,\n spelling: argv.spelling,\n pythonBin: argv.pythonBin,\n force: argv.force,\n};\n\n// async function rMarkdown(dirPath: string, options: Options = {}) {\n// try {\n// return await run(dirPath, options);\n// } catch (err) {\n// console.error(err);\n// if (err instanceof Error) {\n// console.error(err.stack);\n// }\n// process.exit(1);\n// }\n// }\n\nrMarkdown(dirPath, options);\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 noCache?: boolean;\n noTexSvg?: 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};\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 { 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 units = await Promise.all(\n course.units.map((unit) => collectUnit(unit, course, dirPath))\n );\n return { ...course, units };\n}\n\nasync function collectUnit(\n unit: FileRef,\n course: CourseYaml,\n dirPath: string\n): Promise {\n const yaml = await loadUnitYaml(dirPath, unit.src);\n const parts = yaml.content;\n const files = await Promise.all(\n yaml.content.map((c) => {\n const filePath = path.join(dirPath, unit.src, '..', c.src);\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, parts, 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 { readFile } from '../utils/utils';\nimport { CourseYaml } from './types';\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});\n\nexport async function loadCourseYaml(dirPath: string) {\n const fileContents = await readFile(path.join(dirPath, 'course.yaml'));\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 { 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 fileContents = await readFile(path.join(dirPath, src));\n const unit = yaml.load(fileContents);\n return unitSchema.validateSync(unit) as UnitYaml;\n}\n","import path from 'path';\n\nimport { Element, Properties } from 'hast';\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';\nimport { pdfToSvg } from '../pdf/pdf-to-svg';\nimport { cacheToFile } from '../utils/cache-to-file';\nimport { getAssetHast } from '../utils/get-asset-hast';\nimport { failMessage } from '../utils/message';\nimport { readFile, rehypeParser } from '../utils/utils';\n\nexport function embedAssets(ctx: Context) {\n async function embed(node: Element, file: VFile) {\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 '.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 case '.html':\n return await embedHtml(node);\n default:\n throw new Error(`Unhandled file extension: ${parsed.ext}`);\n }\n } catch (_err) {\n const err = _err as Error;\n failMessage(file, err?.message || '', node.position);\n }\n }\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));\n }\n });\n await Promise.all(transformations);\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 node.properties = {\n ...node.properties,\n src: `data:${mime};base64,${image}`,\n };\n } catch (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.buffer();\n return buffer.toString('base64');\n}\n\nasync function embedPdfSvg(imgNode: Element) {\n const src = getImageSrc(imgNode);\n const svgNode = (await pdfToSvg(src)) as Element;\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 { 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 { embedAssets } from './embed-assets';\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(embedAssets, ctx);\n }\n\n return processor.run(mdast, file);\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 { getLibraryDir, 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(getLibraryDir(), '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(getLibraryDir(), 'template.js2');\n docOptions.script = `\\n${await readFile(jsPath)}\\n`;\n processor.use(htmlWrapper, unit, mdast);\n } else {\n processor.use(pdfWrapper, unit);\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 { 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) {\n return async (tree: Node) => {\n const main = await createMain(unit.titles, (tree as Parent).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', 'font-default', 'pdf'],\n },\n children: [iconDefs, main],\n },\n ],\n };\n };\n}\n","import { Node, Parent } from 'unist';\n\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: Node) {\n return async (tree: Node) => {\n const hamburgerIcon = createSvg('hamburger-icon');\n const sidebar = await createSidebar(mdast);\n const main = await createMain(unit.titles, (tree as Parent).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';\n\nimport { UnitTitles } from '../../course/types';\n\nexport async function createMain(titles: UnitTitles, content: Node[]) {\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: [createH1(titles), ...content],\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","import { Root } from 'mdast';\nimport { toHast } from 'mdast-util-to-hast';\nimport { toc as getToc } from 'mdast-util-toc';\nimport { Node } from 'unist';\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: Node) {\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 await checkForLatestVersion();\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 const status = chalk.green.bold(`Complete in ${timer.seconds()}s`);\n console.log(`✨ ${status} ${filePath}.html`);\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 const status = chalk.green.bold(`Complete in ${timer.seconds()}s`);\n console.log(`✨ ${status} ${filePath}.pdf`);\n }\n}\n","import { exec } from 'child_process';\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 { warnMessage } from '../utils/message';\nimport { mkdir, rmFile, writeFile } from '../utils/utils';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport async function knitr(file: VFile, ctx: Context) {\n const result = await execKnitr(file, ctx);\n file.value = result;\n return file;\n}\n\n// TODO: see what can be done with output when \"quiet\" in knitr.R is turned off\nasync function execKnitr(file: VFile, ctx: Context) {\n const md = file.value as string;\n const uniqueId = getUniqueId(md);\n const cachedFilePath = path.join(ctx.cacheDir, `${uniqueId}.Rmd`);\n const cacheDir = path.join(ctx.cacheDir, uniqueId);\n await mkdir(cacheDir);\n await writeFile(cachedFilePath, md);\n\n return new Promise((resolve, reject) => {\n const cmd = createKnitrCommand(file, ctx, uniqueId);\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);\n resolve(formatResponse(response));\n }\n await rmFile(cachedFilePath);\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(file: VFile, ctx: Context, uniqueId: string) {\n const filePath = file.path || '';\n const baseDir = file.dirname || '';\n const rFile = path.join(__dirname, 'knitr.R');\n const cacheDir = path.join(ctx.cacheDir, uniqueId);\n let cmd = `Rscript \"${rFile}\" \"${filePath}\" \"${baseDir}/\" \"${cacheDir}/\"`;\n\n if (ctx.options.pythonBin) {\n cmd += ` \"${ctx.options.pythonBin}\"`;\n }\n\n return cmd;\n}\n\nfunction reportErrors(response: string, file: VFile) {\n response.split('\\n').forEach((line, idx) => {\n const trimmed = line.trim();\n if (trimmed.startsWith('## Error')) {\n warnMessage(file, trimmed.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 = 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 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// attempt at changing knitr output. doesn't completely work\n// const hooks = `\n// knit_hooks$set(\n// source = function(x, options) {\n// paste(c(\"\\`\\`\\`r\", x, \"\\`\\`\\`\"), collapse = \"\\n\")\n// },\n// output = function(x, options) {\n// paste(c(\"\\`\\`\\`\", x, \"\\`\\`\\`\"), collapse = \"\\n\")\n// },\n// error = function(x, options) {\n// paste(\n// c(\n// \"\\`\\`\\`plaintext error\",\n// gsub(\"## Error\", \"\\#\\# Error\", x),\n// \"\\`\\`\\`\"\n// ),\n// collapse = \"\\n\"\n// )\n// }\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';\n// import { 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 // why?\n assertNoTexTabular(file);\n\n const md = file.value as string;\n const tex = 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\n const store = buildMmlStore(md, tex);\n // console.log(store);\n const result = replaceTexWithPlaceholder(md, tex, store, file);\n\n // add store to ctx\n ctx.mmlStore = store;\n\n // replace md in VFile\n file.value = postParse(result);\n return file;\n}\n\n// This is based on https://github.com/mathjax/MathJax-demos-node/blob/f70342b69533dbc24b460f6d6ef341dfa7856414/direct/tex2mml-page\n// except I don't return the HTML, instead I compile a list of the extracted LaTeX converted to MathML\nfunction buildMmlStore(md: string, tex: TeX) {\n const store: string[] = [];\n\n const adaptor = liteAdaptor();\n RegisterHTMLHandler(adaptor);\n const visitor = new SerializedMmlVisitor();\n\n function storeMml({ math }: MathDocument) {\n for (const item of Array.from(math)) {\n // convert to MML\n const mml = visitor.visitTree(item.root);\n store.push(mml);\n\n const tree = adaptor.parse('**unused**', 'text/html');\n item.typesetRoot = adaptor.firstChild(adaptor.body(tree));\n }\n }\n\n const doc = mathjax.document(md, {\n InputJax: tex,\n renderActions: {\n typeset: [MathItem.STATE.TYPESET, storeMml],\n },\n });\n\n doc.render();\n\n return store;\n}\n\nfunction replaceTexWithPlaceholder(\n md: string,\n tex: TeX,\n store: string[],\n file: VFile\n) {\n // Extract the LaTeX from the document again\n const extractedLatex = tex.findMath([md]);\n\n // Replace it with a placeholder for use later\n return extractedLatex\n .map((item, idx) => ({ ...item, idx }))\n .reverse()\n .reduce((acc, item) => {\n const placeholder = createPlaceholder(item, store, file);\n const prev = acc.slice(0, item.start.n);\n const next = acc.slice(item.end.n);\n return prev + placeholder + next;\n }, md);\n}\n\nfunction createPlaceholder(\n item: {\n idx: number;\n math: string;\n display: boolean;\n },\n store: string[],\n file: VFile\n) {\n // escaped dollar sign...\n if (item.math === '$') {\n return '$';\n }\n\n // double backslash...\n if (item.math === '\\\\') {\n return '\\\\\\\\';\n }\n\n const mml = store[item.idx];\n\n // why?\n if (!mml) {\n return '';\n }\n assertNoMmlError(mml, file);\n\n // debug\n // console.log(item.math, mml);\n\n // reference link...\n if (isReferenceLink(item.math)) {\n const refNum = extractRefNumFromMml(mml, item.math, file);\n const anchor = extractAnchorLinkFromMml(mml, item.math, file);\n return `[${refNum}](${anchor})`;\n }\n\n // normal use case (equation)...\n const type = item.display ? 'blockMath' : 'inlineMath';\n return `:${type}[${item.idx}]`;\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 = removeUnresolvedLabels(result);\n console.log(result);\n return result;\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 { 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 assertNoKbl(file: VFile) {\n const md = file.value as string;\n md.split('\\n').forEach((line, idx) => {\n if (line.includes('kbl()')) {\n warnMessage(\n file,\n 'kbl() was found. Please note: table styles may not look the same in HTML output',\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';\n// @ts-expect-error\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 { 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(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 { Root } from 'mdast';\nimport { unified } from 'unified';\nimport { VFile } from 'vfile';\n\nimport { Context } from '../context';\nimport { boxouts } from './boxouts';\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().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 { HTML, Image } from 'mdast';\nimport { Node } from 'unist';\nimport { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\n\n// import { failMessage } from '../utils/message';\n\nexport function embedAssetUrl() {\n return async (tree: Node, file: VFile) => {\n const dirname = file.dirname || '';\n // if (dirname === undefined) {\n // failMessage(file, `File dirname is undefined`);\n // return;\n // }\n\n visit(tree, 'image', (node: Image) => {\n node.url = getPath(node.url, dirname);\n });\n\n // also fix for raw html nodes sometimes output by knitr\n visit(tree, 'html', (node: 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, dirname),\n value: '',\n data: otherProps,\n });\n }\n });\n };\n}\n\nfunction getPath(url: string, dirname: string) {\n return path.isAbsolute(url) || url.startsWith('http')\n ? url\n : path.join(process.cwd(), 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 } from 'hast';\nimport { Image, Text } 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: 'img',\n properties: {\n src: node.url,\n alt: node.alt,\n },\n children: [],\n };\n\n if (node.data?.width) {\n image.properties = {\n ...image.properties,\n style: `width: ${node.data.width};`,\n };\n }\n\n const caption = createCaption(node, count);\n\n Object.assign(node, {\n type: 'custom-image',\n data: {\n hName: 'figure',\n hProperties: {\n className: ['img-wrapper'],\n },\n hChildren: [image, caption],\n },\n });\n}\n\nfunction createCaption(node: Image, count: number) {\n const result: Element = {\n type: 'element',\n tagName: 'figcaption',\n children: [\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\n const altText = node.alt || '';\n\n if (altText !== '' && !altText.includes('unnamed-chunk')) {\n const currentCaption = result.children[0] as Element;\n const currentValue = currentCaption.children[0] as Text;\n currentValue.value += ': ';\n\n result.children.push({\n type: 'text',\n value: `${node.alt}`,\n });\n }\n\n return result;\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 { aliasDirectiveToText } from '../latex/directive-to-text';\nimport { createSvg } from '../utils/icons';\nimport { codeBlocks } from './code-blocks';\nimport { embedAssetUrl } from './embed-asset-url';\nimport { images } from './images';\nimport { pagebreaks } from './pagebreaks';\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(embedAssetUrl)\n .use(youtubeVideos)\n .use(aliasDirectiveToSvg, ctx)\n // .use(aliasDirectiveToText, 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 // 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 { 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","import { Blob } from 'buffer';\n\nimport { Properties, Root } from 'hast';\nimport rehype from 'rehype-parse';\nimport stringify from 'rehype-stringify';\nimport SandboxedModule from 'sandboxed-module';\nimport { optimize } from 'svgo';\nimport { unified } from 'unified';\nimport { Parent } from 'unist';\nimport { visit } from 'unist-util-visit';\n\n// @ts-expect-error\nimport { Element, Image, document } from './domstubs';\n\n// inject globals into pdf.js in a non-leaky way\nconst pdfjsLib = SandboxedModule.require('pdfjs-dist/legacy/build/pdf', {\n globals: { document, Image, Element, Blob, console, process, URL },\n});\n\nexport async function pdfToSvg(filePath: string) {\n const doc = await pdfjsLib.getDocument({\n url: filePath,\n fontExtraProperties: true,\n verbosity: 0,\n // cMapUrl: '../node_modules/pdfjs-dist/cmaps/',\n // cMapPacked: true,\n }).promise;\n\n // may come in handy again...\n // const metadata = await doc.getMetadata();\n // if (!isPdfTexDocument(metadata.info)) {\n // throw new Error('Unhandled pdf file: was not produced by PdfTeX');\n // }\n\n const page = await doc.getPage(1);\n const opList = await page.getOperatorList();\n const viewport = page.getViewport({ scale: 1.0 });\n const svgGfx = new pdfjsLib.SVGGraphics(page.commonObjs, page.objs);\n svgGfx.embedFonts = true;\n const svg = await svgGfx.getSVG(opList, viewport);\n const result = await formatSvg(svg.toString());\n return result;\n}\n\n// function isPdfTexDocument(info: Record = {}) {\n// return info['Producer']?.startsWith('pdfTeX');\n// }\n\nasync function formatSvg(_str: string) {\n const str = _str.replace(/svg:/g, '');\n const optimised = optimize(str, { multipass: true });\n if (optimised.modernError) {\n throw optimised.modernError;\n }\n const processor = unified()\n .use(rehype, { fragment: true })\n .use(addWrapper)\n .use(stringify);\n const parsed = processor.parse(optimised.data);\n const transformed = (await processor.run(parsed)) as Parent;\n return transformed.children[0];\n}\n\nfunction addWrapper() {\n return (tree: Root) => {\n visit(tree, 'element', (node) => {\n if (node.tagName === 'svg') {\n const properties = node.properties || {};\n node.properties = {\n // width: properties.width,\n // height: properties.height,\n viewBox: getViewBox(properties),\n className: 'pdftex',\n };\n }\n });\n };\n}\n\nfunction getViewBox(properties: Properties) {\n if (properties.viewBox) {\n return properties.viewBox;\n }\n return `0 0 ${properties.width} ${properties.height}`;\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 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(//g, '').replace(/