ortoni-report 3.0.1 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,8 @@
1
1
  import {
2
+ __publicField,
2
3
  __require,
3
4
  startReportServer
4
- } from "./chunk-ZSIRUQUA.mjs";
5
+ } from "./chunk-A6HCKATU.mjs";
5
6
 
6
7
  // src/helpers/fileManager.ts
7
8
  import fs from "fs";
@@ -26,21 +27,41 @@ var FileManager = class {
26
27
  return outputPath;
27
28
  }
28
29
  readCssContent() {
29
- return fs.readFileSync(path.resolve(__dirname, "style", "main.css"), "utf-8");
30
+ return fs.readFileSync(
31
+ path.resolve(__dirname, "style", "main.css"),
32
+ "utf-8"
33
+ );
30
34
  }
31
- copyTraceViewerAssets() {
32
- const traceViewerFolder = path.join(__require.resolve("playwright-core"), "..", "lib", "vite", "traceViewer");
35
+ copyTraceViewerAssets(skip) {
36
+ if (skip) return;
37
+ const traceViewerFolder = path.join(
38
+ __require.resolve("playwright-core"),
39
+ "..",
40
+ "lib",
41
+ "vite",
42
+ "traceViewer"
43
+ );
33
44
  const traceViewerTargetFolder = path.join(this.folderPath, "trace");
34
- const traceViewerAssetsTargetFolder = path.join(traceViewerTargetFolder, "assets");
45
+ const traceViewerAssetsTargetFolder = path.join(
46
+ traceViewerTargetFolder,
47
+ "assets"
48
+ );
35
49
  fs.mkdirSync(traceViewerAssetsTargetFolder, { recursive: true });
36
50
  for (const file of fs.readdirSync(traceViewerFolder)) {
37
- if (file.endsWith(".map") || file.includes("watch") || file.includes("assets")) continue;
38
- fs.copyFileSync(path.join(traceViewerFolder, file), path.join(traceViewerTargetFolder, file));
51
+ if (file.endsWith(".map") || file.includes("watch") || file.includes("assets"))
52
+ continue;
53
+ fs.copyFileSync(
54
+ path.join(traceViewerFolder, file),
55
+ path.join(traceViewerTargetFolder, file)
56
+ );
39
57
  }
40
58
  const assetsFolder = path.join(traceViewerFolder, "assets");
41
59
  for (const file of fs.readdirSync(assetsFolder)) {
42
60
  if (file.endsWith(".map") || file.includes("xtermModule")) continue;
43
- fs.copyFileSync(path.join(assetsFolder, file), path.join(traceViewerAssetsTargetFolder, file));
61
+ fs.copyFileSync(
62
+ path.join(assetsFolder, file),
63
+ path.join(traceViewerAssetsTargetFolder, file)
64
+ );
44
65
  }
45
66
  }
46
67
  };
@@ -111,15 +132,19 @@ function formatDate(date) {
111
132
  }
112
133
  function safeStringify(obj, indent = 2) {
113
134
  const cache = /* @__PURE__ */ new Set();
114
- const json = JSON.stringify(obj, (key, value) => {
115
- if (typeof value === "object" && value !== null) {
116
- if (cache.has(value)) {
117
- return;
135
+ const json = JSON.stringify(
136
+ obj,
137
+ (key, value) => {
138
+ if (typeof value === "object" && value !== null) {
139
+ if (cache.has(value)) {
140
+ return;
141
+ }
142
+ cache.add(value);
118
143
  }
119
- cache.add(value);
120
- }
121
- return value;
122
- }, indent);
144
+ return value;
145
+ },
146
+ indent
147
+ );
123
148
  cache.clear();
124
149
  return json;
125
150
  }
@@ -156,12 +181,18 @@ function formatDateLocal(isoString) {
156
181
  day: "2-digit",
157
182
  hour: "2-digit",
158
183
  minute: "2-digit",
159
- // second: '2-digit',
160
184
  hour12: true,
161
185
  timeZoneName: "short"
162
186
  };
163
187
  return new Intl.DateTimeFormat(void 0, options).format(date);
164
188
  }
189
+ function formatDateNoTimezone(isoString) {
190
+ const date = new Date(isoString);
191
+ return date.toLocaleString("en-US", {
192
+ dateStyle: "medium",
193
+ timeStyle: "short"
194
+ });
195
+ }
165
196
 
166
197
  // src/helpers/HTMLGenerator.ts
167
198
  import fs2 from "fs";
@@ -187,6 +218,26 @@ var HTMLGenerator = class {
187
218
  const template = Handlebars.compile(templateSource);
188
219
  return template({ ...data, inlineCss: cssContent });
189
220
  }
221
+ async getReportData() {
222
+ return {
223
+ summary: await this.dbManager.getSummaryData(),
224
+ trends: await this.dbManager.getTrends(),
225
+ flakyTests: await this.dbManager.getFlakyTests(),
226
+ slowTests: await this.dbManager.getSlowTests()
227
+ };
228
+ }
229
+ async chartTrendData() {
230
+ return {
231
+ labels: (await this.getReportData()).trends.map(
232
+ (t) => formatDateNoTimezone(t.run_date)
233
+ ),
234
+ passed: (await this.getReportData()).trends.map((t) => t.passed),
235
+ failed: (await this.getReportData()).trends.map((t) => t.failed),
236
+ avgDuration: (await this.getReportData()).trends.map(
237
+ (t) => t.avg_duration
238
+ )
239
+ };
240
+ }
190
241
  async prepareReportData(filteredResults, totalDuration, results, projectSet) {
191
242
  const totalTests = filteredResults.length;
192
243
  const passedTests = results.filter((r) => r.status === "passed").length;
@@ -241,6 +292,9 @@ var HTMLGenerator = class {
241
292
  allTags: Array.from(allTags),
242
293
  showProject: this.ortoniConfig.showProject || false,
243
294
  title: this.ortoniConfig.title || "Ortoni Playwright Test Report",
295
+ chartType: this.ortoniConfig.chartType || "pie",
296
+ reportAnalyticsData: await this.getReportData(),
297
+ chartData: await this.chartTrendData(),
244
298
  ...this.extractProjectStats(projectResults)
245
299
  };
246
300
  }
@@ -288,8 +342,8 @@ var HTMLGenerator = class {
288
342
  (actualStatus, expectedStatus) => actualStatus.includes(expectedStatus)
289
343
  );
290
344
  Handlebars.registerHelper("gr", (count) => count > 0);
291
- Handlebars.registerHelper("or", function(a, b) {
292
- return a || b;
345
+ Handlebars.registerHelper("or", function(a3, b2) {
346
+ return a3 || b2;
293
347
  });
294
348
  Handlebars.registerHelper("concat", function(...args) {
295
349
  args.pop();
@@ -305,7 +359,8 @@ var HTMLGenerator = class {
305
359
  "userInfo",
306
360
  "project",
307
361
  "testStatus",
308
- "testIcons"
362
+ "testIcons",
363
+ "analytics"
309
364
  ].forEach((partialName) => {
310
365
  Handlebars.registerPartial(
311
366
  partialName,
@@ -324,12 +379,1190 @@ import path5 from "path";
324
379
 
325
380
  // src/utils/attachFiles.ts
326
381
  import path4 from "path";
382
+ import fs4 from "fs";
383
+
384
+ // src/helpers/markdownConverter.ts
327
385
  import fs3 from "fs";
328
- function attachFiles(subFolder, result, testResult, config) {
386
+
387
+ // node_modules/marked/lib/marked.esm.js
388
+ function M() {
389
+ return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
390
+ }
391
+ var w = M();
392
+ function H(a3) {
393
+ w = a3;
394
+ }
395
+ var C = { exec: () => null };
396
+ function h(a3, e = "") {
397
+ let t = typeof a3 == "string" ? a3 : a3.source, n = { replace: (s, i) => {
398
+ let r = typeof i == "string" ? i : i.source;
399
+ return r = r.replace(m.caret, "$1"), t = t.replace(s, r), n;
400
+ }, getRegex: () => new RegExp(t, e) };
401
+ return n;
402
+ }
403
+ var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceTabs: /^\t+/, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] /, listReplaceTask: /^\[[ xX]\] +/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (a3) => new RegExp(`^( {0,3}${a3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}#`), htmlBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}<(?:[a-z].*>|!--)`, "i") };
404
+ var xe = /^(?:[ \t]*(?:\n|$))+/;
405
+ var be = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
406
+ var Te = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
407
+ var I = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
408
+ var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
409
+ var j = /(?:[*+-]|\d{1,9}[.)])/;
410
+ var re = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
411
+ var ie = h(re).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
412
+ var ye = h(re).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
413
+ var F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
414
+ var Re = /^[^\n]+/;
415
+ var Q = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
416
+ var Se = h(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", Q).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
417
+ var $e = h(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, j).getRegex();
418
+ var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
419
+ var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
420
+ var _e = h("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", U).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
421
+ var oe = h(F).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
422
+ var Le = h(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", oe).getRegex();
423
+ var K = { blockquote: Le, code: be, def: Se, fences: Te, heading: we, hr: I, html: _e, lheading: ie, list: $e, newline: xe, paragraph: oe, table: C, text: Re };
424
+ var se = h("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
425
+ var ze = { ...K, lheading: ye, table: se, paragraph: h(F).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
426
+ var Me = { ...K, html: h(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", U).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: C, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: h(F).replace("hr", I).replace("heading", ` *#{1,6} *[^
427
+ ]`).replace("lheading", ie).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
428
+ var Pe = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
429
+ var Ae = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
430
+ var le = /^( {2,}|\\)\n(?!\s*$)/;
431
+ var Ee = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
432
+ var D = /[\p{P}\p{S}]/u;
433
+ var X = /[\s\p{P}\p{S}]/u;
434
+ var ae = /[^\s\p{P}\p{S}]/u;
435
+ var Ce = h(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, X).getRegex();
436
+ var ce = /(?!~)[\p{P}\p{S}]/u;
437
+ var Ie = /(?!~)[\s\p{P}\p{S}]/u;
438
+ var Oe = /(?:[^\s\p{P}\p{S}]|~)/u;
439
+ var Be = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
440
+ var pe = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
441
+ var qe = h(pe, "u").replace(/punct/g, D).getRegex();
442
+ var ve = h(pe, "u").replace(/punct/g, ce).getRegex();
443
+ var ue = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
444
+ var De = h(ue, "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, X).replace(/punct/g, D).getRegex();
445
+ var Ze = h(ue, "gu").replace(/notPunctSpace/g, Oe).replace(/punctSpace/g, Ie).replace(/punct/g, ce).getRegex();
446
+ var Ge = h("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, X).replace(/punct/g, D).getRegex();
447
+ var He = h(/\\(punct)/, "gu").replace(/punct/g, D).getRegex();
448
+ var Ne = h(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
449
+ var je = h(U).replace("(?:-->|$)", "-->").getRegex();
450
+ var Fe = h("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", je).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
451
+ var q = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
452
+ var Qe = h(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
453
+ var he = h(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", Q).getRegex();
454
+ var ke = h(/^!?\[(ref)\](?:\[\])?/).replace("ref", Q).getRegex();
455
+ var Ue = h("reflink|nolink(?!\\()", "g").replace("reflink", he).replace("nolink", ke).getRegex();
456
+ var W = { _backpedal: C, anyPunctuation: He, autolink: Ne, blockSkip: Be, br: le, code: Ae, del: C, emStrongLDelim: qe, emStrongRDelimAst: De, emStrongRDelimUnd: Ge, escape: Pe, link: Qe, nolink: ke, punctuation: Ce, reflink: he, reflinkSearch: Ue, tag: Fe, text: Ee, url: C };
457
+ var Ke = { ...W, link: h(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: h(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
458
+ var N = { ...W, emStrongRDelimAst: Ze, emStrongLDelim: ve, url: h(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, "i").replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/, text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/ };
459
+ var Xe = { ...N, br: h(le).replace("{2,}", "*").getRegex(), text: h(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
460
+ var O = { normal: K, gfm: ze, pedantic: Me };
461
+ var P = { normal: W, gfm: N, breaks: Xe, pedantic: Ke };
462
+ var We = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
463
+ var ge = (a3) => We[a3];
464
+ function R(a3, e) {
465
+ if (e) {
466
+ if (m.escapeTest.test(a3)) return a3.replace(m.escapeReplace, ge);
467
+ } else if (m.escapeTestNoEncode.test(a3)) return a3.replace(m.escapeReplaceNoEncode, ge);
468
+ return a3;
469
+ }
470
+ function J(a3) {
471
+ try {
472
+ a3 = encodeURI(a3).replace(m.percentDecode, "%");
473
+ } catch {
474
+ return null;
475
+ }
476
+ return a3;
477
+ }
478
+ function V(a3, e) {
479
+ let t = a3.replace(m.findPipe, (i, r, o) => {
480
+ let l = false, c = r;
481
+ for (; --c >= 0 && o[c] === "\\"; ) l = !l;
482
+ return l ? "|" : " |";
483
+ }), n = t.split(m.splitPipe), s = 0;
484
+ if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
485
+ else for (; n.length < e; ) n.push("");
486
+ for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|");
487
+ return n;
488
+ }
489
+ function A(a3, e, t) {
490
+ let n = a3.length;
491
+ if (n === 0) return "";
492
+ let s = 0;
493
+ for (; s < n; ) {
494
+ let i = a3.charAt(n - s - 1);
495
+ if (i === e && !t) s++;
496
+ else if (i !== e && t) s++;
497
+ else break;
498
+ }
499
+ return a3.slice(0, n - s);
500
+ }
501
+ function fe(a3, e) {
502
+ if (a3.indexOf(e[1]) === -1) return -1;
503
+ let t = 0;
504
+ for (let n = 0; n < a3.length; n++) if (a3[n] === "\\") n++;
505
+ else if (a3[n] === e[0]) t++;
506
+ else if (a3[n] === e[1] && (t--, t < 0)) return n;
507
+ return t > 0 ? -2 : -1;
508
+ }
509
+ function de(a3, e, t, n, s) {
510
+ let i = e.href, r = e.title || null, o = a3[1].replace(s.other.outputLinkReplace, "$1");
511
+ n.state.inLink = true;
512
+ let l = { type: a3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: r, text: o, tokens: n.inlineTokens(o) };
513
+ return n.state.inLink = false, l;
514
+ }
515
+ function Je(a3, e, t) {
516
+ let n = a3.match(t.other.indentCodeCompensation);
517
+ if (n === null) return e;
518
+ let s = n[1];
519
+ return e.split(`
520
+ `).map((i) => {
521
+ let r = i.match(t.other.beginningSpace);
522
+ if (r === null) return i;
523
+ let [o] = r;
524
+ return o.length >= s.length ? i.slice(s.length) : i;
525
+ }).join(`
526
+ `);
527
+ }
528
+ var S = class {
529
+ constructor(e) {
530
+ __publicField(this, "options");
531
+ __publicField(this, "rules");
532
+ __publicField(this, "lexer");
533
+ this.options = e || w;
534
+ }
535
+ space(e) {
536
+ let t = this.rules.block.newline.exec(e);
537
+ if (t && t[0].length > 0) return { type: "space", raw: t[0] };
538
+ }
539
+ code(e) {
540
+ let t = this.rules.block.code.exec(e);
541
+ if (t) {
542
+ let n = t[0].replace(this.rules.other.codeRemoveIndent, "");
543
+ return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : A(n, `
544
+ `) };
545
+ }
546
+ }
547
+ fences(e) {
548
+ let t = this.rules.block.fences.exec(e);
549
+ if (t) {
550
+ let n = t[0], s = Je(n, t[3] || "", this.rules);
551
+ return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s };
552
+ }
553
+ }
554
+ heading(e) {
555
+ let t = this.rules.block.heading.exec(e);
556
+ if (t) {
557
+ let n = t[2].trim();
558
+ if (this.rules.other.endingHash.test(n)) {
559
+ let s = A(n, "#");
560
+ (this.options.pedantic || !s || this.rules.other.endingSpaceChar.test(s)) && (n = s.trim());
561
+ }
562
+ return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
563
+ }
564
+ }
565
+ hr(e) {
566
+ let t = this.rules.block.hr.exec(e);
567
+ if (t) return { type: "hr", raw: A(t[0], `
568
+ `) };
569
+ }
570
+ blockquote(e) {
571
+ let t = this.rules.block.blockquote.exec(e);
572
+ if (t) {
573
+ let n = A(t[0], `
574
+ `).split(`
575
+ `), s = "", i = "", r = [];
576
+ for (; n.length > 0; ) {
577
+ let o = false, l = [], c;
578
+ for (c = 0; c < n.length; c++) if (this.rules.other.blockquoteStart.test(n[c])) l.push(n[c]), o = true;
579
+ else if (!o) l.push(n[c]);
580
+ else break;
581
+ n = n.slice(c);
582
+ let p = l.join(`
583
+ `), u = p.replace(this.rules.other.blockquoteSetextReplace, `
584
+ $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
585
+ s = s ? `${s}
586
+ ${p}` : p, i = i ? `${i}
587
+ ${u}` : u;
588
+ let d = this.lexer.state.top;
589
+ if (this.lexer.state.top = true, this.lexer.blockTokens(u, r, true), this.lexer.state.top = d, n.length === 0) break;
590
+ let g = r.at(-1);
591
+ if (g?.type === "code") break;
592
+ if (g?.type === "blockquote") {
593
+ let x = g, f = x.raw + `
594
+ ` + n.join(`
595
+ `), y = this.blockquote(f);
596
+ r[r.length - 1] = y, s = s.substring(0, s.length - x.raw.length) + y.raw, i = i.substring(0, i.length - x.text.length) + y.text;
597
+ break;
598
+ } else if (g?.type === "list") {
599
+ let x = g, f = x.raw + `
600
+ ` + n.join(`
601
+ `), y = this.list(f);
602
+ r[r.length - 1] = y, s = s.substring(0, s.length - g.raw.length) + y.raw, i = i.substring(0, i.length - x.raw.length) + y.raw, n = f.substring(r.at(-1).raw.length).split(`
603
+ `);
604
+ continue;
605
+ }
606
+ }
607
+ return { type: "blockquote", raw: s, tokens: r, text: i };
608
+ }
609
+ }
610
+ list(e) {
611
+ let t = this.rules.block.list.exec(e);
612
+ if (t) {
613
+ let n = t[1].trim(), s = n.length > 1, i = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] };
614
+ n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
615
+ let r = this.rules.other.listItemRegex(n), o = false;
616
+ for (; e; ) {
617
+ let c = false, p = "", u = "";
618
+ if (!(t = r.exec(e)) || this.rules.block.hr.test(e)) break;
619
+ p = t[0], e = e.substring(p.length);
620
+ let d = t[2].split(`
621
+ `, 1)[0].replace(this.rules.other.listReplaceTabs, (Z) => " ".repeat(3 * Z.length)), g = e.split(`
622
+ `, 1)[0], x = !d.trim(), f = 0;
623
+ if (this.options.pedantic ? (f = 2, u = d.trimStart()) : x ? f = t[1].length + 1 : (f = t[2].search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, u = d.slice(f), f += t[1].length), x && this.rules.other.blankLine.test(g) && (p += g + `
624
+ `, e = e.substring(g.length + 1), c = true), !c) {
625
+ let Z = this.rules.other.nextBulletRegex(f), ee = this.rules.other.hrRegex(f), te = this.rules.other.fencesBeginRegex(f), ne = this.rules.other.headingBeginRegex(f), me = this.rules.other.htmlBeginRegex(f);
626
+ for (; e; ) {
627
+ let G = e.split(`
628
+ `, 1)[0], E;
629
+ if (g = G, this.options.pedantic ? (g = g.replace(this.rules.other.listReplaceNesting, " "), E = g) : E = g.replace(this.rules.other.tabCharGlobal, " "), te.test(g) || ne.test(g) || me.test(g) || Z.test(g) || ee.test(g)) break;
630
+ if (E.search(this.rules.other.nonSpaceChar) >= f || !g.trim()) u += `
631
+ ` + E.slice(f);
632
+ else {
633
+ if (x || d.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || te.test(d) || ne.test(d) || ee.test(d)) break;
634
+ u += `
635
+ ` + g;
636
+ }
637
+ !x && !g.trim() && (x = true), p += G + `
638
+ `, e = e.substring(G.length + 1), d = E.slice(f);
639
+ }
640
+ }
641
+ i.loose || (o ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (o = true));
642
+ let y = null, Y;
643
+ this.options.gfm && (y = this.rules.other.listIsTask.exec(u), y && (Y = y[0] !== "[ ] ", u = u.replace(this.rules.other.listReplaceTask, ""))), i.items.push({ type: "list_item", raw: p, task: !!y, checked: Y, loose: false, text: u, tokens: [] }), i.raw += p;
644
+ }
645
+ let l = i.items.at(-1);
646
+ if (l) l.raw = l.raw.trimEnd(), l.text = l.text.trimEnd();
647
+ else return;
648
+ i.raw = i.raw.trimEnd();
649
+ for (let c = 0; c < i.items.length; c++) if (this.lexer.state.top = false, i.items[c].tokens = this.lexer.blockTokens(i.items[c].text, []), !i.loose) {
650
+ let p = i.items[c].tokens.filter((d) => d.type === "space"), u = p.length > 0 && p.some((d) => this.rules.other.anyLine.test(d.raw));
651
+ i.loose = u;
652
+ }
653
+ if (i.loose) for (let c = 0; c < i.items.length; c++) i.items[c].loose = true;
654
+ return i;
655
+ }
656
+ }
657
+ html(e) {
658
+ let t = this.rules.block.html.exec(e);
659
+ if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] };
660
+ }
661
+ def(e) {
662
+ let t = this.rules.block.def.exec(e);
663
+ if (t) {
664
+ let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
665
+ return { type: "def", tag: n, raw: t[0], href: s, title: i };
666
+ }
667
+ }
668
+ table(e) {
669
+ let t = this.rules.block.table.exec(e);
670
+ if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
671
+ let n = V(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
672
+ `) : [], r = { type: "table", raw: t[0], header: [], align: [], rows: [] };
673
+ if (n.length === s.length) {
674
+ for (let o of s) this.rules.other.tableAlignRight.test(o) ? r.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? r.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? r.align.push("left") : r.align.push(null);
675
+ for (let o = 0; o < n.length; o++) r.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: r.align[o] });
676
+ for (let o of i) r.rows.push(V(o, r.header.length).map((l, c) => ({ text: l, tokens: this.lexer.inline(l), header: false, align: r.align[c] })));
677
+ return r;
678
+ }
679
+ }
680
+ lheading(e) {
681
+ let t = this.rules.block.lheading.exec(e);
682
+ if (t) return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: t[1], tokens: this.lexer.inline(t[1]) };
683
+ }
684
+ paragraph(e) {
685
+ let t = this.rules.block.paragraph.exec(e);
686
+ if (t) {
687
+ let n = t[1].charAt(t[1].length - 1) === `
688
+ ` ? t[1].slice(0, -1) : t[1];
689
+ return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
690
+ }
691
+ }
692
+ text(e) {
693
+ let t = this.rules.block.text.exec(e);
694
+ if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
695
+ }
696
+ escape(e) {
697
+ let t = this.rules.inline.escape.exec(e);
698
+ if (t) return { type: "escape", raw: t[0], text: t[1] };
699
+ }
700
+ tag(e) {
701
+ let t = this.rules.inline.tag.exec(e);
702
+ if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] };
703
+ }
704
+ link(e) {
705
+ let t = this.rules.inline.link.exec(e);
706
+ if (t) {
707
+ let n = t[2].trim();
708
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
709
+ if (!this.rules.other.endAngleBracket.test(n)) return;
710
+ let r = A(n.slice(0, -1), "\\");
711
+ if ((n.length - r.length) % 2 === 0) return;
712
+ } else {
713
+ let r = fe(t[2], "()");
714
+ if (r === -2) return;
715
+ if (r > -1) {
716
+ let l = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + r;
717
+ t[2] = t[2].substring(0, r), t[0] = t[0].substring(0, l).trim(), t[3] = "";
718
+ }
719
+ }
720
+ let s = t[2], i = "";
721
+ if (this.options.pedantic) {
722
+ let r = this.rules.other.pedanticHrefTitle.exec(s);
723
+ r && (s = r[1], i = r[3]);
724
+ } else i = t[3] ? t[3].slice(1, -1) : "";
725
+ return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), de(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
726
+ }
727
+ }
728
+ reflink(e, t) {
729
+ let n;
730
+ if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
731
+ let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[s.toLowerCase()];
732
+ if (!i) {
733
+ let r = n[0].charAt(0);
734
+ return { type: "text", raw: r, text: r };
735
+ }
736
+ return de(n, i, n[0], this.lexer, this.rules);
737
+ }
738
+ }
739
+ emStrong(e, t, n = "") {
740
+ let s = this.rules.inline.emStrongLDelim.exec(e);
741
+ if (!s || s[3] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
742
+ if (!(s[1] || s[2] || "") || !n || this.rules.inline.punctuation.exec(n)) {
743
+ let r = [...s[0]].length - 1, o, l, c = r, p = 0, u = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
744
+ for (u.lastIndex = 0, t = t.slice(-1 * e.length + r); (s = u.exec(t)) != null; ) {
745
+ if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue;
746
+ if (l = [...o].length, s[3] || s[4]) {
747
+ c += l;
748
+ continue;
749
+ } else if ((s[5] || s[6]) && r % 3 && !((r + l) % 3)) {
750
+ p += l;
751
+ continue;
752
+ }
753
+ if (c -= l, c > 0) continue;
754
+ l = Math.min(l, l + c + p);
755
+ let d = [...s[0]][0].length, g = e.slice(0, r + s.index + d + l);
756
+ if (Math.min(r, l) % 2) {
757
+ let f = g.slice(1, -1);
758
+ return { type: "em", raw: g, text: f, tokens: this.lexer.inlineTokens(f) };
759
+ }
760
+ let x = g.slice(2, -2);
761
+ return { type: "strong", raw: g, text: x, tokens: this.lexer.inlineTokens(x) };
762
+ }
763
+ }
764
+ }
765
+ codespan(e) {
766
+ let t = this.rules.inline.code.exec(e);
767
+ if (t) {
768
+ let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), s = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
769
+ return s && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
770
+ }
771
+ }
772
+ br(e) {
773
+ let t = this.rules.inline.br.exec(e);
774
+ if (t) return { type: "br", raw: t[0] };
775
+ }
776
+ del(e) {
777
+ let t = this.rules.inline.del.exec(e);
778
+ if (t) return { type: "del", raw: t[0], text: t[2], tokens: this.lexer.inlineTokens(t[2]) };
779
+ }
780
+ autolink(e) {
781
+ let t = this.rules.inline.autolink.exec(e);
782
+ if (t) {
783
+ let n, s;
784
+ return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
785
+ }
786
+ }
787
+ url(e) {
788
+ let t;
789
+ if (t = this.rules.inline.url.exec(e)) {
790
+ let n, s;
791
+ if (t[2] === "@") n = t[0], s = "mailto:" + n;
792
+ else {
793
+ let i;
794
+ do
795
+ i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
796
+ while (i !== t[0]);
797
+ n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0];
798
+ }
799
+ return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
800
+ }
801
+ }
802
+ inlineText(e) {
803
+ let t = this.rules.inline.text.exec(e);
804
+ if (t) {
805
+ let n = this.lexer.state.inRawBlock;
806
+ return { type: "text", raw: t[0], text: t[0], escaped: n };
807
+ }
808
+ }
809
+ };
810
+ var b = class a {
811
+ constructor(e) {
812
+ __publicField(this, "tokens");
813
+ __publicField(this, "options");
814
+ __publicField(this, "state");
815
+ __publicField(this, "tokenizer");
816
+ __publicField(this, "inlineQueue");
817
+ this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || w, this.options.tokenizer = this.options.tokenizer || new S(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
818
+ let t = { other: m, block: O.normal, inline: P.normal };
819
+ this.options.pedantic ? (t.block = O.pedantic, t.inline = P.pedantic) : this.options.gfm && (t.block = O.gfm, this.options.breaks ? t.inline = P.breaks : t.inline = P.gfm), this.tokenizer.rules = t;
820
+ }
821
+ static get rules() {
822
+ return { block: O, inline: P };
823
+ }
824
+ static lex(e, t) {
825
+ return new a(t).lex(e);
826
+ }
827
+ static lexInline(e, t) {
828
+ return new a(t).inlineTokens(e);
829
+ }
830
+ lex(e) {
831
+ e = e.replace(m.carriageReturn, `
832
+ `), this.blockTokens(e, this.tokens);
833
+ for (let t = 0; t < this.inlineQueue.length; t++) {
834
+ let n = this.inlineQueue[t];
835
+ this.inlineTokens(n.src, n.tokens);
836
+ }
837
+ return this.inlineQueue = [], this.tokens;
838
+ }
839
+ blockTokens(e, t = [], n = false) {
840
+ for (this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) {
841
+ let s;
842
+ if (this.options.extensions?.block?.some((r) => (s = r.call({ lexer: this }, e, t)) ? (e = e.substring(s.raw.length), t.push(s), true) : false)) continue;
843
+ if (s = this.tokenizer.space(e)) {
844
+ e = e.substring(s.raw.length);
845
+ let r = t.at(-1);
846
+ s.raw.length === 1 && r !== void 0 ? r.raw += `
847
+ ` : t.push(s);
848
+ continue;
849
+ }
850
+ if (s = this.tokenizer.code(e)) {
851
+ e = e.substring(s.raw.length);
852
+ let r = t.at(-1);
853
+ r?.type === "paragraph" || r?.type === "text" ? (r.raw += `
854
+ ` + s.raw, r.text += `
855
+ ` + s.text, this.inlineQueue.at(-1).src = r.text) : t.push(s);
856
+ continue;
857
+ }
858
+ if (s = this.tokenizer.fences(e)) {
859
+ e = e.substring(s.raw.length), t.push(s);
860
+ continue;
861
+ }
862
+ if (s = this.tokenizer.heading(e)) {
863
+ e = e.substring(s.raw.length), t.push(s);
864
+ continue;
865
+ }
866
+ if (s = this.tokenizer.hr(e)) {
867
+ e = e.substring(s.raw.length), t.push(s);
868
+ continue;
869
+ }
870
+ if (s = this.tokenizer.blockquote(e)) {
871
+ e = e.substring(s.raw.length), t.push(s);
872
+ continue;
873
+ }
874
+ if (s = this.tokenizer.list(e)) {
875
+ e = e.substring(s.raw.length), t.push(s);
876
+ continue;
877
+ }
878
+ if (s = this.tokenizer.html(e)) {
879
+ e = e.substring(s.raw.length), t.push(s);
880
+ continue;
881
+ }
882
+ if (s = this.tokenizer.def(e)) {
883
+ e = e.substring(s.raw.length);
884
+ let r = t.at(-1);
885
+ r?.type === "paragraph" || r?.type === "text" ? (r.raw += `
886
+ ` + s.raw, r.text += `
887
+ ` + s.raw, this.inlineQueue.at(-1).src = r.text) : this.tokens.links[s.tag] || (this.tokens.links[s.tag] = { href: s.href, title: s.title });
888
+ continue;
889
+ }
890
+ if (s = this.tokenizer.table(e)) {
891
+ e = e.substring(s.raw.length), t.push(s);
892
+ continue;
893
+ }
894
+ if (s = this.tokenizer.lheading(e)) {
895
+ e = e.substring(s.raw.length), t.push(s);
896
+ continue;
897
+ }
898
+ let i = e;
899
+ if (this.options.extensions?.startBlock) {
900
+ let r = 1 / 0, o = e.slice(1), l;
901
+ this.options.extensions.startBlock.forEach((c) => {
902
+ l = c.call({ lexer: this }, o), typeof l == "number" && l >= 0 && (r = Math.min(r, l));
903
+ }), r < 1 / 0 && r >= 0 && (i = e.substring(0, r + 1));
904
+ }
905
+ if (this.state.top && (s = this.tokenizer.paragraph(i))) {
906
+ let r = t.at(-1);
907
+ n && r?.type === "paragraph" ? (r.raw += `
908
+ ` + s.raw, r.text += `
909
+ ` + s.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = r.text) : t.push(s), n = i.length !== e.length, e = e.substring(s.raw.length);
910
+ continue;
911
+ }
912
+ if (s = this.tokenizer.text(e)) {
913
+ e = e.substring(s.raw.length);
914
+ let r = t.at(-1);
915
+ r?.type === "text" ? (r.raw += `
916
+ ` + s.raw, r.text += `
917
+ ` + s.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = r.text) : t.push(s);
918
+ continue;
919
+ }
920
+ if (e) {
921
+ let r = "Infinite loop on byte: " + e.charCodeAt(0);
922
+ if (this.options.silent) {
923
+ console.error(r);
924
+ break;
925
+ } else throw new Error(r);
926
+ }
927
+ }
928
+ return this.state.top = true, t;
929
+ }
930
+ inline(e, t = []) {
931
+ return this.inlineQueue.push({ src: e, tokens: t }), t;
932
+ }
933
+ inlineTokens(e, t = []) {
934
+ let n = e, s = null;
935
+ if (this.tokens.links) {
936
+ let o = Object.keys(this.tokens.links);
937
+ if (o.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) o.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
938
+ }
939
+ for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) n = n.slice(0, s.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
940
+ for (; (s = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
941
+ let i = false, r = "";
942
+ for (; e; ) {
943
+ i || (r = ""), i = false;
944
+ let o;
945
+ if (this.options.extensions?.inline?.some((c) => (o = c.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
946
+ if (o = this.tokenizer.escape(e)) {
947
+ e = e.substring(o.raw.length), t.push(o);
948
+ continue;
949
+ }
950
+ if (o = this.tokenizer.tag(e)) {
951
+ e = e.substring(o.raw.length), t.push(o);
952
+ continue;
953
+ }
954
+ if (o = this.tokenizer.link(e)) {
955
+ e = e.substring(o.raw.length), t.push(o);
956
+ continue;
957
+ }
958
+ if (o = this.tokenizer.reflink(e, this.tokens.links)) {
959
+ e = e.substring(o.raw.length);
960
+ let c = t.at(-1);
961
+ o.type === "text" && c?.type === "text" ? (c.raw += o.raw, c.text += o.text) : t.push(o);
962
+ continue;
963
+ }
964
+ if (o = this.tokenizer.emStrong(e, n, r)) {
965
+ e = e.substring(o.raw.length), t.push(o);
966
+ continue;
967
+ }
968
+ if (o = this.tokenizer.codespan(e)) {
969
+ e = e.substring(o.raw.length), t.push(o);
970
+ continue;
971
+ }
972
+ if (o = this.tokenizer.br(e)) {
973
+ e = e.substring(o.raw.length), t.push(o);
974
+ continue;
975
+ }
976
+ if (o = this.tokenizer.del(e)) {
977
+ e = e.substring(o.raw.length), t.push(o);
978
+ continue;
979
+ }
980
+ if (o = this.tokenizer.autolink(e)) {
981
+ e = e.substring(o.raw.length), t.push(o);
982
+ continue;
983
+ }
984
+ if (!this.state.inLink && (o = this.tokenizer.url(e))) {
985
+ e = e.substring(o.raw.length), t.push(o);
986
+ continue;
987
+ }
988
+ let l = e;
989
+ if (this.options.extensions?.startInline) {
990
+ let c = 1 / 0, p = e.slice(1), u;
991
+ this.options.extensions.startInline.forEach((d) => {
992
+ u = d.call({ lexer: this }, p), typeof u == "number" && u >= 0 && (c = Math.min(c, u));
993
+ }), c < 1 / 0 && c >= 0 && (l = e.substring(0, c + 1));
994
+ }
995
+ if (o = this.tokenizer.inlineText(l)) {
996
+ e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (r = o.raw.slice(-1)), i = true;
997
+ let c = t.at(-1);
998
+ c?.type === "text" ? (c.raw += o.raw, c.text += o.text) : t.push(o);
999
+ continue;
1000
+ }
1001
+ if (e) {
1002
+ let c = "Infinite loop on byte: " + e.charCodeAt(0);
1003
+ if (this.options.silent) {
1004
+ console.error(c);
1005
+ break;
1006
+ } else throw new Error(c);
1007
+ }
1008
+ }
1009
+ return t;
1010
+ }
1011
+ };
1012
+ var $ = class {
1013
+ constructor(e) {
1014
+ __publicField(this, "options");
1015
+ __publicField(this, "parser");
1016
+ this.options = e || w;
1017
+ }
1018
+ space(e) {
1019
+ return "";
1020
+ }
1021
+ code({ text: e, lang: t, escaped: n }) {
1022
+ let s = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + `
1023
+ `;
1024
+ return s ? '<pre><code class="language-' + R(s) + '">' + (n ? i : R(i, true)) + `</code></pre>
1025
+ ` : "<pre><code>" + (n ? i : R(i, true)) + `</code></pre>
1026
+ `;
1027
+ }
1028
+ blockquote({ tokens: e }) {
1029
+ return `<blockquote>
1030
+ ${this.parser.parse(e)}</blockquote>
1031
+ `;
1032
+ }
1033
+ html({ text: e }) {
1034
+ return e;
1035
+ }
1036
+ heading({ tokens: e, depth: t }) {
1037
+ return `<h${t}>${this.parser.parseInline(e)}</h${t}>
1038
+ `;
1039
+ }
1040
+ hr(e) {
1041
+ return `<hr>
1042
+ `;
1043
+ }
1044
+ list(e) {
1045
+ let t = e.ordered, n = e.start, s = "";
1046
+ for (let o = 0; o < e.items.length; o++) {
1047
+ let l = e.items[o];
1048
+ s += this.listitem(l);
1049
+ }
1050
+ let i = t ? "ol" : "ul", r = t && n !== 1 ? ' start="' + n + '"' : "";
1051
+ return "<" + i + r + `>
1052
+ ` + s + "</" + i + `>
1053
+ `;
1054
+ }
1055
+ listitem(e) {
1056
+ let t = "";
1057
+ if (e.task) {
1058
+ let n = this.checkbox({ checked: !!e.checked });
1059
+ e.loose ? e.tokens[0]?.type === "paragraph" ? (e.tokens[0].text = n + " " + e.tokens[0].text, e.tokens[0].tokens && e.tokens[0].tokens.length > 0 && e.tokens[0].tokens[0].type === "text" && (e.tokens[0].tokens[0].text = n + " " + R(e.tokens[0].tokens[0].text), e.tokens[0].tokens[0].escaped = true)) : e.tokens.unshift({ type: "text", raw: n + " ", text: n + " ", escaped: true }) : t += n + " ";
1060
+ }
1061
+ return t += this.parser.parse(e.tokens, !!e.loose), `<li>${t}</li>
1062
+ `;
1063
+ }
1064
+ checkbox({ checked: e }) {
1065
+ return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
1066
+ }
1067
+ paragraph({ tokens: e }) {
1068
+ return `<p>${this.parser.parseInline(e)}</p>
1069
+ `;
1070
+ }
1071
+ table(e) {
1072
+ let t = "", n = "";
1073
+ for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]);
1074
+ t += this.tablerow({ text: n });
1075
+ let s = "";
1076
+ for (let i = 0; i < e.rows.length; i++) {
1077
+ let r = e.rows[i];
1078
+ n = "";
1079
+ for (let o = 0; o < r.length; o++) n += this.tablecell(r[o]);
1080
+ s += this.tablerow({ text: n });
1081
+ }
1082
+ return s && (s = `<tbody>${s}</tbody>`), `<table>
1083
+ <thead>
1084
+ ` + t + `</thead>
1085
+ ` + s + `</table>
1086
+ `;
1087
+ }
1088
+ tablerow({ text: e }) {
1089
+ return `<tr>
1090
+ ${e}</tr>
1091
+ `;
1092
+ }
1093
+ tablecell(e) {
1094
+ let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
1095
+ return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
1096
+ `;
1097
+ }
1098
+ strong({ tokens: e }) {
1099
+ return `<strong>${this.parser.parseInline(e)}</strong>`;
1100
+ }
1101
+ em({ tokens: e }) {
1102
+ return `<em>${this.parser.parseInline(e)}</em>`;
1103
+ }
1104
+ codespan({ text: e }) {
1105
+ return `<code>${R(e, true)}</code>`;
1106
+ }
1107
+ br(e) {
1108
+ return "<br>";
1109
+ }
1110
+ del({ tokens: e }) {
1111
+ return `<del>${this.parser.parseInline(e)}</del>`;
1112
+ }
1113
+ link({ href: e, title: t, tokens: n }) {
1114
+ let s = this.parser.parseInline(n), i = J(e);
1115
+ if (i === null) return s;
1116
+ e = i;
1117
+ let r = '<a href="' + e + '"';
1118
+ return t && (r += ' title="' + R(t) + '"'), r += ">" + s + "</a>", r;
1119
+ }
1120
+ image({ href: e, title: t, text: n, tokens: s }) {
1121
+ s && (n = this.parser.parseInline(s, this.parser.textRenderer));
1122
+ let i = J(e);
1123
+ if (i === null) return R(n);
1124
+ e = i;
1125
+ let r = `<img src="${e}" alt="${n}"`;
1126
+ return t && (r += ` title="${R(t)}"`), r += ">", r;
1127
+ }
1128
+ text(e) {
1129
+ return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : R(e.text);
1130
+ }
1131
+ };
1132
+ var _ = class {
1133
+ strong({ text: e }) {
1134
+ return e;
1135
+ }
1136
+ em({ text: e }) {
1137
+ return e;
1138
+ }
1139
+ codespan({ text: e }) {
1140
+ return e;
1141
+ }
1142
+ del({ text: e }) {
1143
+ return e;
1144
+ }
1145
+ html({ text: e }) {
1146
+ return e;
1147
+ }
1148
+ text({ text: e }) {
1149
+ return e;
1150
+ }
1151
+ link({ text: e }) {
1152
+ return "" + e;
1153
+ }
1154
+ image({ text: e }) {
1155
+ return "" + e;
1156
+ }
1157
+ br() {
1158
+ return "";
1159
+ }
1160
+ };
1161
+ var T = class a2 {
1162
+ constructor(e) {
1163
+ __publicField(this, "options");
1164
+ __publicField(this, "renderer");
1165
+ __publicField(this, "textRenderer");
1166
+ this.options = e || w, this.options.renderer = this.options.renderer || new $(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new _();
1167
+ }
1168
+ static parse(e, t) {
1169
+ return new a2(t).parse(e);
1170
+ }
1171
+ static parseInline(e, t) {
1172
+ return new a2(t).parseInline(e);
1173
+ }
1174
+ parse(e, t = true) {
1175
+ let n = "";
1176
+ for (let s = 0; s < e.length; s++) {
1177
+ let i = e[s];
1178
+ if (this.options.extensions?.renderers?.[i.type]) {
1179
+ let o = i, l = this.options.extensions.renderers[o.type].call({ parser: this }, o);
1180
+ if (l !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(o.type)) {
1181
+ n += l || "";
1182
+ continue;
1183
+ }
1184
+ }
1185
+ let r = i;
1186
+ switch (r.type) {
1187
+ case "space": {
1188
+ n += this.renderer.space(r);
1189
+ continue;
1190
+ }
1191
+ case "hr": {
1192
+ n += this.renderer.hr(r);
1193
+ continue;
1194
+ }
1195
+ case "heading": {
1196
+ n += this.renderer.heading(r);
1197
+ continue;
1198
+ }
1199
+ case "code": {
1200
+ n += this.renderer.code(r);
1201
+ continue;
1202
+ }
1203
+ case "table": {
1204
+ n += this.renderer.table(r);
1205
+ continue;
1206
+ }
1207
+ case "blockquote": {
1208
+ n += this.renderer.blockquote(r);
1209
+ continue;
1210
+ }
1211
+ case "list": {
1212
+ n += this.renderer.list(r);
1213
+ continue;
1214
+ }
1215
+ case "html": {
1216
+ n += this.renderer.html(r);
1217
+ continue;
1218
+ }
1219
+ case "paragraph": {
1220
+ n += this.renderer.paragraph(r);
1221
+ continue;
1222
+ }
1223
+ case "text": {
1224
+ let o = r, l = this.renderer.text(o);
1225
+ for (; s + 1 < e.length && e[s + 1].type === "text"; ) o = e[++s], l += `
1226
+ ` + this.renderer.text(o);
1227
+ t ? n += this.renderer.paragraph({ type: "paragraph", raw: l, text: l, tokens: [{ type: "text", raw: l, text: l, escaped: true }] }) : n += l;
1228
+ continue;
1229
+ }
1230
+ default: {
1231
+ let o = 'Token with "' + r.type + '" type was not found.';
1232
+ if (this.options.silent) return console.error(o), "";
1233
+ throw new Error(o);
1234
+ }
1235
+ }
1236
+ }
1237
+ return n;
1238
+ }
1239
+ parseInline(e, t = this.renderer) {
1240
+ let n = "";
1241
+ for (let s = 0; s < e.length; s++) {
1242
+ let i = e[s];
1243
+ if (this.options.extensions?.renderers?.[i.type]) {
1244
+ let o = this.options.extensions.renderers[i.type].call({ parser: this }, i);
1245
+ if (o !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) {
1246
+ n += o || "";
1247
+ continue;
1248
+ }
1249
+ }
1250
+ let r = i;
1251
+ switch (r.type) {
1252
+ case "escape": {
1253
+ n += t.text(r);
1254
+ break;
1255
+ }
1256
+ case "html": {
1257
+ n += t.html(r);
1258
+ break;
1259
+ }
1260
+ case "link": {
1261
+ n += t.link(r);
1262
+ break;
1263
+ }
1264
+ case "image": {
1265
+ n += t.image(r);
1266
+ break;
1267
+ }
1268
+ case "strong": {
1269
+ n += t.strong(r);
1270
+ break;
1271
+ }
1272
+ case "em": {
1273
+ n += t.em(r);
1274
+ break;
1275
+ }
1276
+ case "codespan": {
1277
+ n += t.codespan(r);
1278
+ break;
1279
+ }
1280
+ case "br": {
1281
+ n += t.br(r);
1282
+ break;
1283
+ }
1284
+ case "del": {
1285
+ n += t.del(r);
1286
+ break;
1287
+ }
1288
+ case "text": {
1289
+ n += t.text(r);
1290
+ break;
1291
+ }
1292
+ default: {
1293
+ let o = 'Token with "' + r.type + '" type was not found.';
1294
+ if (this.options.silent) return console.error(o), "";
1295
+ throw new Error(o);
1296
+ }
1297
+ }
1298
+ }
1299
+ return n;
1300
+ }
1301
+ };
1302
+ var _a;
1303
+ var L = (_a = class {
1304
+ constructor(e) {
1305
+ __publicField(this, "options");
1306
+ __publicField(this, "block");
1307
+ this.options = e || w;
1308
+ }
1309
+ preprocess(e) {
1310
+ return e;
1311
+ }
1312
+ postprocess(e) {
1313
+ return e;
1314
+ }
1315
+ processAllTokens(e) {
1316
+ return e;
1317
+ }
1318
+ provideLexer() {
1319
+ return this.block ? b.lex : b.lexInline;
1320
+ }
1321
+ provideParser() {
1322
+ return this.block ? T.parse : T.parseInline;
1323
+ }
1324
+ }, __publicField(_a, "passThroughHooks", /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"])), _a);
1325
+ var B = class {
1326
+ constructor(...e) {
1327
+ __publicField(this, "defaults", M());
1328
+ __publicField(this, "options", this.setOptions);
1329
+ __publicField(this, "parse", this.parseMarkdown(true));
1330
+ __publicField(this, "parseInline", this.parseMarkdown(false));
1331
+ __publicField(this, "Parser", T);
1332
+ __publicField(this, "Renderer", $);
1333
+ __publicField(this, "TextRenderer", _);
1334
+ __publicField(this, "Lexer", b);
1335
+ __publicField(this, "Tokenizer", S);
1336
+ __publicField(this, "Hooks", L);
1337
+ this.use(...e);
1338
+ }
1339
+ walkTokens(e, t) {
1340
+ let n = [];
1341
+ for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) {
1342
+ case "table": {
1343
+ let i = s;
1344
+ for (let r of i.header) n = n.concat(this.walkTokens(r.tokens, t));
1345
+ for (let r of i.rows) for (let o of r) n = n.concat(this.walkTokens(o.tokens, t));
1346
+ break;
1347
+ }
1348
+ case "list": {
1349
+ let i = s;
1350
+ n = n.concat(this.walkTokens(i.items, t));
1351
+ break;
1352
+ }
1353
+ default: {
1354
+ let i = s;
1355
+ this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((r) => {
1356
+ let o = i[r].flat(1 / 0);
1357
+ n = n.concat(this.walkTokens(o, t));
1358
+ }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t)));
1359
+ }
1360
+ }
1361
+ return n;
1362
+ }
1363
+ use(...e) {
1364
+ let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
1365
+ return e.forEach((n) => {
1366
+ let s = { ...n };
1367
+ if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((i) => {
1368
+ if (!i.name) throw new Error("extension name required");
1369
+ if ("renderer" in i) {
1370
+ let r = t.renderers[i.name];
1371
+ r ? t.renderers[i.name] = function(...o) {
1372
+ let l = i.renderer.apply(this, o);
1373
+ return l === false && (l = r.apply(this, o)), l;
1374
+ } : t.renderers[i.name] = i.renderer;
1375
+ }
1376
+ if ("tokenizer" in i) {
1377
+ if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
1378
+ let r = t[i.level];
1379
+ r ? r.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start]));
1380
+ }
1381
+ "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens);
1382
+ }), s.extensions = t), n.renderer) {
1383
+ let i = this.defaults.renderer || new $(this.defaults);
1384
+ for (let r in n.renderer) {
1385
+ if (!(r in i)) throw new Error(`renderer '${r}' does not exist`);
1386
+ if (["options", "parser"].includes(r)) continue;
1387
+ let o = r, l = n.renderer[o], c = i[o];
1388
+ i[o] = (...p) => {
1389
+ let u = l.apply(i, p);
1390
+ return u === false && (u = c.apply(i, p)), u || "";
1391
+ };
1392
+ }
1393
+ s.renderer = i;
1394
+ }
1395
+ if (n.tokenizer) {
1396
+ let i = this.defaults.tokenizer || new S(this.defaults);
1397
+ for (let r in n.tokenizer) {
1398
+ if (!(r in i)) throw new Error(`tokenizer '${r}' does not exist`);
1399
+ if (["options", "rules", "lexer"].includes(r)) continue;
1400
+ let o = r, l = n.tokenizer[o], c = i[o];
1401
+ i[o] = (...p) => {
1402
+ let u = l.apply(i, p);
1403
+ return u === false && (u = c.apply(i, p)), u;
1404
+ };
1405
+ }
1406
+ s.tokenizer = i;
1407
+ }
1408
+ if (n.hooks) {
1409
+ let i = this.defaults.hooks || new L();
1410
+ for (let r in n.hooks) {
1411
+ if (!(r in i)) throw new Error(`hook '${r}' does not exist`);
1412
+ if (["options", "block"].includes(r)) continue;
1413
+ let o = r, l = n.hooks[o], c = i[o];
1414
+ L.passThroughHooks.has(r) ? i[o] = (p) => {
1415
+ if (this.defaults.async) return Promise.resolve(l.call(i, p)).then((d) => c.call(i, d));
1416
+ let u = l.call(i, p);
1417
+ return c.call(i, u);
1418
+ } : i[o] = (...p) => {
1419
+ let u = l.apply(i, p);
1420
+ return u === false && (u = c.apply(i, p)), u;
1421
+ };
1422
+ }
1423
+ s.hooks = i;
1424
+ }
1425
+ if (n.walkTokens) {
1426
+ let i = this.defaults.walkTokens, r = n.walkTokens;
1427
+ s.walkTokens = function(o) {
1428
+ let l = [];
1429
+ return l.push(r.call(this, o)), i && (l = l.concat(i.call(this, o))), l;
1430
+ };
1431
+ }
1432
+ this.defaults = { ...this.defaults, ...s };
1433
+ }), this;
1434
+ }
1435
+ setOptions(e) {
1436
+ return this.defaults = { ...this.defaults, ...e }, this;
1437
+ }
1438
+ lexer(e, t) {
1439
+ return b.lex(e, t ?? this.defaults);
1440
+ }
1441
+ parser(e, t) {
1442
+ return T.parse(e, t ?? this.defaults);
1443
+ }
1444
+ parseMarkdown(e) {
1445
+ return (n, s) => {
1446
+ let i = { ...s }, r = { ...this.defaults, ...i }, o = this.onError(!!r.silent, !!r.async);
1447
+ if (this.defaults.async === true && i.async === false) return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
1448
+ if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null"));
1449
+ if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
1450
+ r.hooks && (r.hooks.options = r, r.hooks.block = e);
1451
+ let l = r.hooks ? r.hooks.provideLexer() : e ? b.lex : b.lexInline, c = r.hooks ? r.hooks.provideParser() : e ? T.parse : T.parseInline;
1452
+ if (r.async) return Promise.resolve(r.hooks ? r.hooks.preprocess(n) : n).then((p) => l(p, r)).then((p) => r.hooks ? r.hooks.processAllTokens(p) : p).then((p) => r.walkTokens ? Promise.all(this.walkTokens(p, r.walkTokens)).then(() => p) : p).then((p) => c(p, r)).then((p) => r.hooks ? r.hooks.postprocess(p) : p).catch(o);
1453
+ try {
1454
+ r.hooks && (n = r.hooks.preprocess(n));
1455
+ let p = l(n, r);
1456
+ r.hooks && (p = r.hooks.processAllTokens(p)), r.walkTokens && this.walkTokens(p, r.walkTokens);
1457
+ let u = c(p, r);
1458
+ return r.hooks && (u = r.hooks.postprocess(u)), u;
1459
+ } catch (p) {
1460
+ return o(p);
1461
+ }
1462
+ };
1463
+ }
1464
+ onError(e, t) {
1465
+ return (n) => {
1466
+ if (n.message += `
1467
+ Please report this to https://github.com/markedjs/marked.`, e) {
1468
+ let s = "<p>An error occurred:</p><pre>" + R(n.message + "", true) + "</pre>";
1469
+ return t ? Promise.resolve(s) : s;
1470
+ }
1471
+ if (t) return Promise.reject(n);
1472
+ throw n;
1473
+ };
1474
+ }
1475
+ };
1476
+ var z = new B();
1477
+ function k(a3, e) {
1478
+ return z.parse(a3, e);
1479
+ }
1480
+ k.options = k.setOptions = function(a3) {
1481
+ return z.setOptions(a3), k.defaults = z.defaults, H(k.defaults), k;
1482
+ };
1483
+ k.getDefaults = M;
1484
+ k.defaults = w;
1485
+ k.use = function(...a3) {
1486
+ return z.use(...a3), k.defaults = z.defaults, H(k.defaults), k;
1487
+ };
1488
+ k.walkTokens = function(a3, e) {
1489
+ return z.walkTokens(a3, e);
1490
+ };
1491
+ k.parseInline = z.parseInline;
1492
+ k.Parser = T;
1493
+ k.parser = T.parse;
1494
+ k.Renderer = $;
1495
+ k.TextRenderer = _;
1496
+ k.Lexer = b;
1497
+ k.lexer = b.lex;
1498
+ k.Tokenizer = S;
1499
+ k.Hooks = L;
1500
+ k.parse = k;
1501
+ var Dt = k.options;
1502
+ var Zt = k.setOptions;
1503
+ var Gt = k.use;
1504
+ var Ht = k.walkTokens;
1505
+ var Nt = k.parseInline;
1506
+ var Ft = T.parse;
1507
+ var Qt = b.lex;
1508
+
1509
+ // src/helpers/markdownConverter.ts
1510
+ function convertMarkdownToHtml(markdownPath, htmlOutputPath, stepsError, resultError) {
1511
+ const hasMarkdown = fs3.existsSync(markdownPath);
1512
+ const markdownContent = hasMarkdown ? fs3.readFileSync(markdownPath, "utf-8") : "";
1513
+ const markdownHtml = hasMarkdown ? k(markdownContent) : "";
1514
+ const stepsHtml = stepsError.filter((step) => step.snippet?.trim()).map(
1515
+ (step) => `
1516
+ <div>
1517
+ <pre><code>${step.snippet}</code></pre>
1518
+ ${step.location ? `<p><em>Location: ${escapeHtml(step.location)}</em></p>` : ""}
1519
+ </div>`
1520
+ ).join("\n");
1521
+ const errorHtml = resultError.map((error) => `<pre><code>${error}</code></pre>`).join("\n");
1522
+ const fullHtml = `
1523
+ <!DOCTYPE html>
1524
+ <html lang="en">
1525
+ <head>
1526
+ <meta charset="UTF-8" />
1527
+ <title>Ortoni Error Report</title>
1528
+ <style>
1529
+ body { font-family: sans-serif; padding: 2rem; line-height: 1.6; max-width: 900px; margin: auto; }
1530
+ code, pre { background: #f4f4f4; padding: 0.5rem; border-radius: 5px; display: block; overflow-x: auto; }
1531
+ h1, h2, h3 { color: #444; }
1532
+ hr { margin: 2em 0; }
1533
+ </style>
1534
+ </head>
1535
+ <body>
1536
+ <h1>Instructions</h1>
1537
+ <ul>
1538
+ <li>Following Playwright test failed.</li>
1539
+ <li>Explain why, be concise, respect Playwright best practices.</li>
1540
+ <li>Provide a snippet of code with the fix, if possible.</li>
1541
+ </ul>
1542
+ <h1>Error Details</h1>
1543
+ ${errorHtml || "<p>No errors found.</p>"}
1544
+ ${stepsHtml || "<p>No step data available.</p>"}
1545
+ ${markdownHtml ? `${markdownHtml}` : ""}
1546
+ </body>
1547
+ </html>
1548
+ `;
1549
+ fs3.writeFileSync(htmlOutputPath, fullHtml, "utf-8");
1550
+ if (hasMarkdown) {
1551
+ fs3.unlinkSync(markdownPath);
1552
+ }
1553
+ }
1554
+
1555
+ // src/utils/attachFiles.ts
1556
+ function attachFiles(subFolder, result, testResult, config, steps, errors) {
329
1557
  const folderPath = config.folderPath || "ortoni-report";
330
- const attachmentsFolder = path4.join(folderPath, "ortoni-data", "attachments", subFolder);
331
- if (!fs3.existsSync(attachmentsFolder)) {
332
- fs3.mkdirSync(attachmentsFolder, { recursive: true });
1558
+ const attachmentsFolder = path4.join(
1559
+ folderPath,
1560
+ "ortoni-data",
1561
+ "attachments",
1562
+ subFolder
1563
+ );
1564
+ if (!fs4.existsSync(attachmentsFolder)) {
1565
+ fs4.mkdirSync(attachmentsFolder, { recursive: true });
333
1566
  }
334
1567
  if (!result.attachments) return;
335
1568
  const { base64Image } = config;
@@ -338,14 +1571,48 @@ function attachFiles(subFolder, result, testResult, config) {
338
1571
  const { contentType, name, path: attachmentPath, body } = attachment;
339
1572
  if (!attachmentPath && !body) return;
340
1573
  const fileName = attachmentPath ? path4.basename(attachmentPath) : `${name}.${getFileExtension(contentType)}`;
341
- const relativePath = path4.join("ortoni-data", "attachments", subFolder, fileName);
1574
+ const relativePath = path4.join(
1575
+ "ortoni-data",
1576
+ "attachments",
1577
+ subFolder,
1578
+ fileName
1579
+ );
342
1580
  const fullPath = path4.join(attachmentsFolder, fileName);
343
1581
  if (contentType === "image/png") {
344
- handleImage(attachmentPath, body, base64Image, fullPath, relativePath, testResult);
1582
+ handleImage(
1583
+ attachmentPath,
1584
+ body,
1585
+ base64Image,
1586
+ fullPath,
1587
+ relativePath,
1588
+ testResult
1589
+ );
345
1590
  } else if (name === "video") {
346
- handleAttachment(attachmentPath, fullPath, relativePath, "videoPath", testResult);
1591
+ handleAttachment(
1592
+ attachmentPath,
1593
+ fullPath,
1594
+ relativePath,
1595
+ "videoPath",
1596
+ testResult
1597
+ );
347
1598
  } else if (name === "trace") {
348
- handleAttachment(attachmentPath, fullPath, relativePath, "tracePath", testResult);
1599
+ handleAttachment(
1600
+ attachmentPath,
1601
+ fullPath,
1602
+ relativePath,
1603
+ "tracePath",
1604
+ testResult
1605
+ );
1606
+ } else if (name === "error-context") {
1607
+ handleAttachment(
1608
+ attachmentPath,
1609
+ fullPath,
1610
+ relativePath,
1611
+ "markdownPath",
1612
+ testResult,
1613
+ steps,
1614
+ errors
1615
+ );
349
1616
  }
350
1617
  });
351
1618
  }
@@ -353,13 +1620,19 @@ function handleImage(attachmentPath, body, base64Image, fullPath, relativePath,
353
1620
  let screenshotPath = "";
354
1621
  if (attachmentPath) {
355
1622
  try {
356
- const screenshotContent = fs3.readFileSync(attachmentPath, base64Image ? "base64" : void 0);
1623
+ const screenshotContent = fs4.readFileSync(
1624
+ attachmentPath,
1625
+ base64Image ? "base64" : void 0
1626
+ );
357
1627
  screenshotPath = base64Image ? `data:image/png;base64,${screenshotContent}` : relativePath;
358
1628
  if (!base64Image) {
359
- fs3.copyFileSync(attachmentPath, fullPath);
1629
+ fs4.copyFileSync(attachmentPath, fullPath);
360
1630
  }
361
1631
  } catch (error) {
362
- console.error(`OrtoniReport: Failed to read screenshot file: ${attachmentPath}`, error);
1632
+ console.error(
1633
+ `OrtoniReport: Failed to read screenshot file: ${attachmentPath}`,
1634
+ error
1635
+ );
363
1636
  }
364
1637
  } else if (body) {
365
1638
  screenshotPath = `data:image/png;base64,${body.toString("base64")}`;
@@ -368,17 +1641,25 @@ function handleImage(attachmentPath, body, base64Image, fullPath, relativePath,
368
1641
  testResult.screenshots?.push(screenshotPath);
369
1642
  }
370
1643
  }
371
- function handleAttachment(attachmentPath, fullPath, relativePath, resultKey, testResult) {
1644
+ function handleAttachment(attachmentPath, fullPath, relativePath, resultKey, testResult, steps, errors) {
372
1645
  if (attachmentPath) {
373
- fs3.copyFileSync(attachmentPath, fullPath);
1646
+ fs4.copyFileSync(attachmentPath, fullPath);
374
1647
  testResult[resultKey] = relativePath;
375
1648
  }
1649
+ if (resultKey === "markdownPath" && errors) {
1650
+ const htmlPath = fullPath.replace(/\.md$/, ".html");
1651
+ const htmlRelativePath = relativePath.replace(/\.md$/, ".html");
1652
+ convertMarkdownToHtml(fullPath, htmlPath, steps || [], errors || []);
1653
+ testResult[resultKey] = htmlRelativePath;
1654
+ return;
1655
+ }
376
1656
  }
377
1657
  function getFileExtension(contentType) {
378
1658
  const extensions = {
379
1659
  "image/png": "png",
380
1660
  "video/webm": "webm",
381
- "application/zip": "zip"
1661
+ "application/zip": "zip",
1662
+ "text/markdown": "md"
382
1663
  };
383
1664
  return extensions[contentType] || "unknown";
384
1665
  }
@@ -411,14 +1692,27 @@ var TestResultProcessor = class {
411
1692
  status,
412
1693
  flaky: test.outcome(),
413
1694
  duration: msToTime(result.duration),
414
- errors: result.errors.map((e) => this.ansiToHtml.toHtml(escapeHtml(e.stack || e.toString()))),
1695
+ errors: result.errors.map(
1696
+ (e) => this.ansiToHtml.toHtml(escapeHtml(e.stack || e.toString()))
1697
+ ),
415
1698
  steps: this.processSteps(result.steps),
416
- logs: this.ansiToHtml.toHtml(escapeHtml(result.stdout.concat(result.stderr).map((log) => log).join("\n"))),
1699
+ logs: this.ansiToHtml.toHtml(
1700
+ escapeHtml(
1701
+ result.stdout.concat(result.stderr).map((log) => log).join("\n")
1702
+ )
1703
+ ),
417
1704
  filePath,
418
1705
  filters: projectSet,
419
1706
  base64Image: ortoniConfig.base64Image
420
1707
  };
421
- attachFiles(test.id, result, testResult, ortoniConfig);
1708
+ attachFiles(
1709
+ test.id,
1710
+ result,
1711
+ testResult,
1712
+ ortoniConfig,
1713
+ testResult.steps,
1714
+ testResult.errors
1715
+ );
422
1716
  return testResult;
423
1717
  }
424
1718
  processSteps(steps) {
@@ -517,7 +1811,7 @@ var DatabaseManager = class {
517
1811
  return null;
518
1812
  }
519
1813
  try {
520
- const runDate = formatDateUTC(/* @__PURE__ */ new Date());
1814
+ const runDate = (/* @__PURE__ */ new Date()).toISOString();
521
1815
  const { lastID } = await this.db.run(
522
1816
  `
523
1817
  INSERT INTO test_runs (run_date)
@@ -595,6 +1889,130 @@ var DatabaseManager = class {
595
1889
  }
596
1890
  }
597
1891
  }
1892
+ async getSummaryData() {
1893
+ if (!this.db) {
1894
+ console.error("OrtoniReport: Database not initialized");
1895
+ return {
1896
+ totalRuns: 0,
1897
+ totalTests: 0,
1898
+ passed: 0,
1899
+ failed: 0,
1900
+ passRate: 0,
1901
+ avgDuration: 0
1902
+ };
1903
+ }
1904
+ try {
1905
+ const summary = await this.db.get(`
1906
+ SELECT
1907
+ (SELECT COUNT(*) FROM test_runs) as totalRuns,
1908
+ (SELECT COUNT(*) FROM test_results) as totalTests,
1909
+ (SELECT COUNT(*) FROM test_results WHERE status = 'passed') as passed,
1910
+ (SELECT COUNT(*) FROM test_results WHERE status = 'failed') as failed,
1911
+ (SELECT AVG(CAST(duration AS FLOAT)) FROM test_results) as avgDuration
1912
+ `);
1913
+ const passRate = summary.totalTests ? (summary.passed / summary.totalTests * 100).toFixed(2) : 0;
1914
+ return {
1915
+ totalRuns: summary.totalRuns,
1916
+ totalTests: summary.totalTests,
1917
+ passed: summary.passed,
1918
+ failed: summary.failed,
1919
+ passRate: parseFloat(passRate.toString()),
1920
+ avgDuration: Math.round(summary.avgDuration || 0)
1921
+ };
1922
+ } catch (error) {
1923
+ console.error("OrtoniReport: Error getting summary data:", error);
1924
+ return {
1925
+ totalRuns: 0,
1926
+ totalTests: 0,
1927
+ passed: 0,
1928
+ failed: 0,
1929
+ passRate: 0,
1930
+ avgDuration: 0
1931
+ };
1932
+ }
1933
+ }
1934
+ async getTrends(limit = 30) {
1935
+ if (!this.db) {
1936
+ console.error("OrtoniReport: Database not initialized");
1937
+ return [];
1938
+ }
1939
+ try {
1940
+ const rows = await this.db.all(
1941
+ `
1942
+ SELECT trun.run_date,
1943
+ SUM(CASE WHEN tr.status = 'passed' THEN 1 ELSE 0 END) AS passed,
1944
+ SUM(CASE WHEN tr.status = 'failed' THEN 1 ELSE 0 END) AS failed,
1945
+ AVG(CAST(tr.duration AS FLOAT)) AS avg_duration
1946
+ FROM test_results tr
1947
+ JOIN test_runs trun ON tr.run_id = trun.id
1948
+ GROUP BY trun.run_date
1949
+ ORDER BY trun.run_date ASC
1950
+ LIMIT ?
1951
+ `,
1952
+ [limit]
1953
+ );
1954
+ return rows.map((row) => ({
1955
+ ...row,
1956
+ run_date: formatDateLocal(row.run_date),
1957
+ avg_duration: Math.round(row.avg_duration || 0)
1958
+ }));
1959
+ } catch (error) {
1960
+ console.error("OrtoniReport: Error getting trends data:", error);
1961
+ return [];
1962
+ }
1963
+ }
1964
+ async getFlakyTests(limit = 10) {
1965
+ if (!this.db) {
1966
+ console.error("OrtoniReport: Database not initialized");
1967
+ return [];
1968
+ }
1969
+ try {
1970
+ return await this.db.all(
1971
+ `
1972
+ SELECT
1973
+ test_id,
1974
+ COUNT(*) AS total,
1975
+ SUM(CASE WHEN status = 'flaky' THEN 1 ELSE 0 END) AS flaky
1976
+ FROM test_results
1977
+ GROUP BY test_id
1978
+ HAVING flaky > 0
1979
+ ORDER BY flaky DESC
1980
+ LIMIT ?
1981
+ `,
1982
+ [limit]
1983
+ );
1984
+ } catch (error) {
1985
+ console.error("OrtoniReport: Error getting flaky tests:", error);
1986
+ return [];
1987
+ }
1988
+ }
1989
+ async getSlowTests(limit = 10) {
1990
+ if (!this.db) {
1991
+ console.error("OrtoniReport: Database not initialized");
1992
+ return [];
1993
+ }
1994
+ try {
1995
+ const rows = await this.db.all(
1996
+ `
1997
+ SELECT
1998
+ test_id,
1999
+ AVG(CAST(duration AS FLOAT)) AS avg_duration
2000
+ FROM test_results
2001
+ GROUP BY test_id
2002
+ ORDER BY avg_duration DESC
2003
+ LIMIT ?
2004
+ `,
2005
+ [limit]
2006
+ );
2007
+ return rows.map((row) => ({
2008
+ test_id: row.test_id,
2009
+ avg_duration: Math.round(row.avg_duration || 0)
2010
+ }));
2011
+ } catch (error) {
2012
+ console.error("OrtoniReport: Error getting slow tests:", error);
2013
+ return [];
2014
+ }
2015
+ }
598
2016
  };
599
2017
 
600
2018
  // src/ortoni-report.ts
@@ -606,9 +2024,12 @@ var OrtoniReport = class {
606
2024
  this.projectSet = /* @__PURE__ */ new Set();
607
2025
  this.shouldGenerateReport = true;
608
2026
  this.showConsoleLogs = true;
2027
+ this.skipTraceViewer = false;
609
2028
  this.reportsCount = 0;
610
2029
  this.folderPath = ortoniConfig.folderPath || "ortoni-report";
611
- this.outputFilename = ensureHtmlExtension(ortoniConfig.filename || "ortoni-report.html");
2030
+ this.outputFilename = ensureHtmlExtension(
2031
+ ortoniConfig.filename || "ortoni-report.html"
2032
+ );
612
2033
  this.dbManager = new DatabaseManager();
613
2034
  this.htmlGenerator = new HTMLGenerator(ortoniConfig, this.dbManager);
614
2035
  this.fileManager = new FileManager(this.folderPath);
@@ -617,11 +2038,17 @@ var OrtoniReport = class {
617
2038
  this.showConsoleLogs = ortoniConfig.stdIO !== false;
618
2039
  }
619
2040
  async onBegin(config, _suite) {
2041
+ this.skipTraceViewer = config.projects.every((project) => {
2042
+ const trace = project.use?.trace;
2043
+ return trace === void 0 || trace === "off";
2044
+ });
620
2045
  this.reportsCount = config.reporter.length;
621
2046
  this.results = [];
622
2047
  this.testResultProcessor = new TestResultProcessor(config.rootDir);
623
2048
  this.fileManager.ensureReportDirectory();
624
- await this.dbManager.initialize(path6.join(this.folderPath, "ortoni-data-history.sqlite"));
2049
+ await this.dbManager.initialize(
2050
+ path6.join(this.folderPath, "ortoni-data-history.sqlite")
2051
+ );
625
2052
  }
626
2053
  onStdOut(chunk, _test, _result) {
627
2054
  if (this.reportsCount == 1 && this.showConsoleLogs) {
@@ -630,7 +2057,12 @@ var OrtoniReport = class {
630
2057
  }
631
2058
  onTestEnd(test, result) {
632
2059
  try {
633
- const testResult = this.testResultProcessor.processTestResult(test, result, this.projectSet, this.ortoniConfig);
2060
+ const testResult = this.testResultProcessor.processTestResult(
2061
+ test,
2062
+ result,
2063
+ this.projectSet,
2064
+ this.ortoniConfig
2065
+ );
634
2066
  this.results.push(testResult);
635
2067
  } catch (error) {
636
2068
  console.error("OrtoniReport: Error processing test end:", error);
@@ -648,19 +2080,32 @@ var OrtoniReport = class {
648
2080
  try {
649
2081
  this.overAllStatus = result.status;
650
2082
  if (this.shouldGenerateReport) {
651
- const filteredResults = this.results.filter((r) => r.status !== "skipped" && !r.isRetry);
2083
+ const filteredResults = this.results.filter(
2084
+ (r) => r.status !== "skipped" && !r.isRetry
2085
+ );
652
2086
  const totalDuration = msToTime(result.duration);
653
2087
  const cssContent = this.fileManager.readCssContent();
654
2088
  const runId = await this.dbManager.saveTestRun();
655
2089
  if (runId !== null) {
656
2090
  await this.dbManager.saveTestResults(runId, this.results);
657
- const html = await this.htmlGenerator.generateHTML(filteredResults, totalDuration, cssContent, this.results, this.projectSet);
658
- this.outputPath = this.fileManager.writeReportFile(this.outputFilename, html);
2091
+ const html = await this.htmlGenerator.generateHTML(
2092
+ filteredResults,
2093
+ totalDuration,
2094
+ cssContent,
2095
+ this.results,
2096
+ this.projectSet
2097
+ );
2098
+ this.outputPath = this.fileManager.writeReportFile(
2099
+ this.outputFilename,
2100
+ html
2101
+ );
659
2102
  } else {
660
2103
  console.error("OrtoniReport: Error saving test run to database");
661
2104
  }
662
2105
  } else {
663
- console.error("OrtoniReport: Report generation skipped due to error in Playwright worker!");
2106
+ console.error(
2107
+ "OrtoniReport: Report generation skipped due to error in Playwright worker!"
2108
+ );
664
2109
  }
665
2110
  } catch (error) {
666
2111
  this.shouldGenerateReport = false;
@@ -671,9 +2116,13 @@ var OrtoniReport = class {
671
2116
  try {
672
2117
  await this.dbManager.close();
673
2118
  if (this.shouldGenerateReport) {
674
- this.fileManager.copyTraceViewerAssets();
2119
+ this.fileManager.copyTraceViewerAssets(this.skipTraceViewer);
675
2120
  console.info(`Ortoni HTML report generated at ${this.outputPath}`);
676
- this.serverManager.startServer(this.folderPath, this.outputFilename, this.overAllStatus);
2121
+ this.serverManager.startServer(
2122
+ this.folderPath,
2123
+ this.outputFilename,
2124
+ this.overAllStatus
2125
+ );
677
2126
  await new Promise((_resolve) => {
678
2127
  });
679
2128
  }