@jxsuite/parser 2.0.0 → 3.0.0

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.
@@ -58,6 +58,77 @@ var __esm = (fn, res, err) => () => {
58
58
  };
59
59
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
60
60
 
61
+ // ../../packages/schema/src/guards.ts
62
+ function isString(value) {
63
+ return typeof value === "string";
64
+ }
65
+ function isNumber(value) {
66
+ return typeof value === "number";
67
+ }
68
+ function isBoolean(value) {
69
+ return typeof value === "boolean";
70
+ }
71
+ function isNonNullObject(value) {
72
+ return typeof value === "object" && value !== null;
73
+ }
74
+ function isJsonObject(value) {
75
+ return typeof value === "object" && value !== null && !Array.isArray(value);
76
+ }
77
+ function isRef(value) {
78
+ return isJsonObject(value) && typeof value.$ref === "string";
79
+ }
80
+ function isNodeObject(value) {
81
+ return isJsonObject(value);
82
+ }
83
+ function isPlainTagName(tagName) {
84
+ return typeof tagName === "string";
85
+ }
86
+ function isTagExpression(tagName) {
87
+ if (typeof tagName !== "object" || tagName === null || Array.isArray(tagName) || !isJsonObject(tagName.$expression)) {
88
+ return false;
89
+ }
90
+ const expression = tagName.$expression;
91
+ if (expression.operator === "?:") {
92
+ return typeof expression.value === "string" && typeof expression.initial === "string";
93
+ }
94
+ if (expression.operator === "switch") {
95
+ return isJsonObject(expression.cases) && Object.values(expression.cases).every((tag) => isString(tag)) && typeof expression.default === "string";
96
+ }
97
+ return false;
98
+ }
99
+ function tagNameCandidates(tagName) {
100
+ if (isPlainTagName(tagName)) {
101
+ return [tagName];
102
+ }
103
+ if (!isTagExpression(tagName)) {
104
+ return [];
105
+ }
106
+ const expression = tagName.$expression;
107
+ if (expression.operator === "?:") {
108
+ return [...new Set([expression.value, expression.initial])];
109
+ }
110
+ return [...new Set([...Object.values(expression.cases), expression.default])];
111
+ }
112
+ var SCHEMA_KEYWORDS;
113
+ var init_guards = __esm(() => {
114
+ SCHEMA_KEYWORDS = new Set([
115
+ "type",
116
+ "enum",
117
+ "minimum",
118
+ "maximum",
119
+ "minLength",
120
+ "maxLength",
121
+ "pattern",
122
+ "format",
123
+ "items",
124
+ "properties",
125
+ "required",
126
+ "description",
127
+ "title",
128
+ "$comment"
129
+ ]);
130
+ });
131
+
61
132
  // src/alerts.ts
62
133
  function normalizeAlerts(config, where = "alerts") {
63
134
  if (config === false) {
@@ -68,7 +139,7 @@ function normalizeAlerts(config, where = "alerts") {
68
139
  if (config === undefined || config === true) {
69
140
  return { disabled, types };
70
141
  }
71
- if (typeof config !== "object" || config === null || Array.isArray(config)) {
142
+ if (!isJsonObject(config)) {
72
143
  throw new TypeError(`${where}: expected an object mapping alert types to element names, or false`);
73
144
  }
74
145
  for (const [type, element] of Object.entries(config)) {
@@ -81,7 +152,7 @@ function normalizeAlerts(config, where = "alerts") {
81
152
  disabled.add(key);
82
153
  } else if (element === true) {
83
154
  types.set(key, null);
84
- } else if (typeof element === "string" && TAG_NAME.test(element)) {
155
+ } else if (isString(element) && TAG_NAME.test(element)) {
85
156
  types.set(key, element);
86
157
  } else {
87
158
  throw new TypeError(`${where}.${type}: expected an element name such as "doc-note", true or false, got ${JSON.stringify(element)}`);
@@ -92,7 +163,7 @@ function normalizeAlerts(config, where = "alerts") {
92
163
  function inlineText(nodes) {
93
164
  let out = "";
94
165
  for (const node of nodes) {
95
- if (typeof node.value === "string") {
166
+ if (node.value !== undefined) {
96
167
  out += node.value;
97
168
  } else if (node.children) {
98
169
  out += inlineText(node.children);
@@ -105,7 +176,7 @@ function textNode(value) {
105
176
  }
106
177
  function markerOf(paragraph) {
107
178
  const [first] = paragraph.children ?? [];
108
- if (first?.type !== "text" || typeof first.value !== "string") {
179
+ if (first?.type !== "text" || first.value === undefined) {
109
180
  return null;
110
181
  }
111
182
  const match = MARKER.exec(first.value);
@@ -131,7 +202,7 @@ function splitMarker(paragraph, settings) {
131
202
  const take = (node) => {
132
203
  if (inTitle && node.type === "break") {
133
204
  inTitle = false;
134
- } else if (inTitle && node.type === "text" && typeof node.value === "string") {
205
+ } else if (inTitle && node.type === "text" && node.value !== undefined) {
135
206
  const lineEnd = LINE_END.exec(node.value);
136
207
  if (lineEnd === null) {
137
208
  title.push(node);
@@ -188,6 +259,7 @@ function transformAlerts(tree, settings, onUnknown) {
188
259
  }
189
260
  var DEFAULT_ALERT_TITLES, ALERT_NODE = "jxAlert", TAG_NAME, MARKER, LINE_END;
190
261
  var init_alerts = __esm(() => {
262
+ init_guards();
191
263
  DEFAULT_ALERT_TITLES = {
192
264
  caution: "Caution",
193
265
  important: "Important",
@@ -334,7 +406,7 @@ function compileExclude(patterns) {
334
406
  const dirs = [];
335
407
  let everything = false;
336
408
  for (const pattern of patterns) {
337
- if (typeof pattern !== "string" || pattern.trim() === "") {
409
+ if (!isString(pattern) || pattern.trim() === "") {
338
410
  throw new TypeError(`"exclude" entries must be non-empty strings, got ${JSON.stringify(pattern)}`);
339
411
  }
340
412
  if (pattern.startsWith("!")) {
@@ -408,21 +480,21 @@ function readField(data, key) {
408
480
  if (!key.includes(".")) {
409
481
  return;
410
482
  }
411
- let current = data;
412
- for (const part of key.split(".")) {
413
- if (!isPlainObject(current) || !Object.hasOwn(current, part)) {
414
- return;
415
- }
416
- current = current[part];
483
+ return readPath(data, key.split("."));
484
+ }
485
+ function readPath(holder, [part, ...rest]) {
486
+ if (part === undefined || !isPlainObject(holder) || !Object.hasOwn(holder, part)) {
487
+ return;
417
488
  }
418
- return current;
489
+ const value = holder[part];
490
+ return rest.length === 0 ? value : readPath(value, rest);
419
491
  }
420
492
  function order(actual, operand) {
421
493
  const a = comparable(actual);
422
- if (typeof a === "number" && typeof operand === "number") {
494
+ if (isNumber(a) && isNumber(operand)) {
423
495
  return a - operand;
424
496
  }
425
- if (typeof a === "string" && typeof operand === "string") {
497
+ if (isString(a) && isString(operand)) {
426
498
  return a < operand ? -1 : a > operand ? 1 : 0;
427
499
  }
428
500
  return;
@@ -444,13 +516,13 @@ function operatorTest(where, op, operand) {
444
516
  return op === "$in" ? hit : (actual) => !hit(actual);
445
517
  }
446
518
  case "$exists": {
447
- if (typeof operand !== "boolean") {
519
+ if (!isBoolean(operand)) {
448
520
  throw new TypeError(`${where}.$exists: expected true or false, got ${JSON.stringify(operand)}`);
449
521
  }
450
522
  return (actual) => (actual !== undefined && actual !== null) === operand;
451
523
  }
452
524
  default: {
453
- if (typeof operand !== "string" && typeof operand !== "number") {
525
+ if (!isString(operand) && !isNumber(operand)) {
454
526
  throw new TypeError(`${where}.${op}: expected a string or number, got ${JSON.stringify(operand)}`);
455
527
  }
456
528
  const test = (diff) => op === "$gt" ? diff > 0 : op === "$gte" ? diff >= 0 : op === "$lt" ? diff < 0 : diff <= 0;
@@ -508,6 +580,7 @@ function compileWhere(where) {
508
580
  }
509
581
  var nothing = () => {}, REGEXP_SPECIAL, MAX_STAR_RUNS = 4, OPERATORS;
510
582
  var init_content_rules = __esm(() => {
583
+ init_guards();
511
584
  REGEXP_SPECIAL = /[$()*+.?[\\\]^{|}]/g;
512
585
  OPERATORS = new Set(["$eq", "$ne", "$in", "$nin", "$exists", "$gt", "$gte", "$lt", "$lte"]);
513
586
  });
@@ -4053,7 +4126,7 @@ var init_dev4 = __esm(() => {
4053
4126
 
4054
4127
  // ../../node_modules/micromark-factory-space/dev/index.js
4055
4128
  function factorySpace(effects, ok, type, max) {
4056
- const limit = max ? max - 1 : Number.POSITIVE_INFINITY;
4129
+ const limit = max ? max - 1 : Infinity;
4057
4130
  let size = 0;
4058
4131
  return start;
4059
4132
  function start(code) {
@@ -4072,6 +4145,29 @@ function factorySpace(effects, ok, type, max) {
4072
4145
  return ok(code);
4073
4146
  }
4074
4147
  }
4148
+ function factorySpaceMinMax(effects, ok, nok, type, min, max) {
4149
+ let size = 0;
4150
+ return start;
4151
+ function start(code) {
4152
+ if (max > 0 && markdownSpace(code)) {
4153
+ effects.enter(type);
4154
+ return prefix(code);
4155
+ }
4156
+ return after(code);
4157
+ }
4158
+ function prefix(code) {
4159
+ if (markdownSpace(code) && size < max) {
4160
+ effects.consume(code);
4161
+ size++;
4162
+ return prefix;
4163
+ }
4164
+ effects.exit(type);
4165
+ return after(code);
4166
+ }
4167
+ function after(code) {
4168
+ return size >= min ? ok(code) : nok(code);
4169
+ }
4170
+ }
4075
4171
  var init_dev5 = __esm(() => {
4076
4172
  init_dev4();
4077
4173
  });
@@ -4133,6 +4229,65 @@ var init_content = __esm(() => {
4133
4229
  content = { tokenize: initializeContent };
4134
4230
  });
4135
4231
 
4232
+ // ../../node_modules/micromark-util-edit-map/dev/index.js
4233
+ class EditMap {
4234
+ constructor() {
4235
+ this.index = new Map;
4236
+ this.map = [];
4237
+ }
4238
+ add(index, remove, add) {
4239
+ addImplementation(this, index, remove, add, false);
4240
+ }
4241
+ addBefore(index, remove, add) {
4242
+ addImplementation(this, index, remove, add, true);
4243
+ }
4244
+ consume(events) {
4245
+ this.map.sort(function(a, b) {
4246
+ return a[0] - b[0];
4247
+ });
4248
+ if (this.map.length === 0) {
4249
+ return;
4250
+ }
4251
+ let index = this.map.length;
4252
+ const vecs = [];
4253
+ while (index > 0) {
4254
+ index -= 1;
4255
+ vecs.push(events.slice(this.map[index][0] + this.map[index][1]), this.map[index][2]);
4256
+ events.length = this.map[index][0];
4257
+ }
4258
+ vecs.push(events.slice());
4259
+ events.length = 0;
4260
+ let slice = vecs.pop();
4261
+ while (slice) {
4262
+ for (const element of slice) {
4263
+ events.push(element);
4264
+ }
4265
+ slice = vecs.pop();
4266
+ }
4267
+ this.map.length = 0;
4268
+ this.index.clear();
4269
+ }
4270
+ }
4271
+ function addImplementation(editMap, at, remove, add, before) {
4272
+ if (remove === 0 && add.length === 0) {
4273
+ return;
4274
+ }
4275
+ const existing = editMap.index.get(at);
4276
+ if (existing) {
4277
+ existing[1] += remove;
4278
+ if (before) {
4279
+ add.push(...existing[2]);
4280
+ existing[2] = add;
4281
+ } else {
4282
+ existing[2].push(...add);
4283
+ }
4284
+ return;
4285
+ }
4286
+ const change = [at, remove, add];
4287
+ editMap.map.push(change);
4288
+ editMap.index.set(at, change);
4289
+ }
4290
+
4136
4291
  // ../../node_modules/micromark/dev/lib/initialize/document.js
4137
4292
  function initializeDocument(effects) {
4138
4293
  const self2 = this;
@@ -4175,8 +4330,10 @@ function initializeDocument(effects) {
4175
4330
  self2.events[index][1].end = { ...point };
4176
4331
  index++;
4177
4332
  }
4178
- splice(self2.events, indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
4179
- self2.events.length = index;
4333
+ const editMap = new EditMap;
4334
+ editMap.add(indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
4335
+ editMap.add(indexBeforeExits, index - indexBeforeExits, []);
4336
+ editMap.consume(self2.events);
4180
4337
  return checkNewContainers(code);
4181
4338
  }
4182
4339
  return start(code);
@@ -4195,8 +4352,9 @@ function initializeDocument(effects) {
4195
4352
  return effects.check(containerConstruct, thereIsANewContainer, thereIsNoNewContainer)(code);
4196
4353
  }
4197
4354
  function thereIsANewContainer(code) {
4198
- if (childFlow)
4355
+ if (childFlow) {
4199
4356
  closeFlow();
4357
+ }
4200
4358
  exitContainers(continued);
4201
4359
  return documentContinued(code);
4202
4360
  }
@@ -4218,8 +4376,9 @@ function initializeDocument(effects) {
4218
4376
  }
4219
4377
  function flowStart(code) {
4220
4378
  if (code === codes.eof) {
4221
- if (childFlow)
4379
+ if (childFlow) {
4222
4380
  closeFlow();
4381
+ }
4223
4382
  exitContainers(0);
4224
4383
  effects.consume(code);
4225
4384
  return;
@@ -4252,11 +4411,13 @@ function initializeDocument(effects) {
4252
4411
  function writeToChild(token, endOfFile) {
4253
4412
  ok(childFlow, "expected `childFlow` to be defined when continuing");
4254
4413
  const stream = self2.sliceStream(token);
4255
- if (endOfFile)
4414
+ if (endOfFile) {
4256
4415
  stream.push(null);
4416
+ }
4257
4417
  token.previous = childToken;
4258
- if (childToken)
4418
+ if (childToken) {
4259
4419
  childToken.next = token;
4420
+ }
4260
4421
  childToken = token;
4261
4422
  childFlow.defineSkip(token.start);
4262
4423
  childFlow.write(stream);
@@ -4287,8 +4448,10 @@ function initializeDocument(effects) {
4287
4448
  self2.events[index][1].end = { ...point };
4288
4449
  index++;
4289
4450
  }
4290
- splice(self2.events, indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
4291
- self2.events.length = index;
4451
+ const editMap = new EditMap;
4452
+ editMap.add(indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
4453
+ editMap.add(indexBeforeExits, index - indexBeforeExits, []);
4454
+ editMap.consume(self2.events);
4292
4455
  }
4293
4456
  }
4294
4457
  function exitContainers(size) {
@@ -4319,7 +4482,6 @@ var init_document = __esm(() => {
4319
4482
  init_development();
4320
4483
  init_dev5();
4321
4484
  init_dev4();
4322
- init_dev();
4323
4485
  init_default();
4324
4486
  document2 = { tokenize: initializeDocument };
4325
4487
  containerConstruct = { tokenize: tokenizeContainer };
@@ -4356,43 +4518,36 @@ function resolveAll(constructs, events, context) {
4356
4518
  // ../../node_modules/micromark-core-commonmark/dev/lib/attention.js
4357
4519
  function resolveAllAttention(events, context) {
4358
4520
  let index = -1;
4359
- let open;
4360
- let group;
4361
- let text;
4362
- let openingSequence;
4363
- let closingSequence;
4364
- let use;
4365
4521
  let nextEvents;
4366
- let offset;
4367
4522
  while (++index < events.length) {
4368
4523
  if (events[index][0] === "enter" && events[index][1].type === "attentionSequence" && events[index][1]._close) {
4369
- open = index;
4524
+ let open = index;
4370
4525
  while (open--) {
4371
4526
  if (events[open][0] === "exit" && events[open][1].type === "attentionSequence" && events[open][1]._open && context.sliceSerialize(events[open][1]).charCodeAt(0) === context.sliceSerialize(events[index][1]).charCodeAt(0)) {
4372
4527
  if ((events[open][1]._close || events[index][1]._open) && (events[index][1].end.offset - events[index][1].start.offset) % 3 && !((events[open][1].end.offset - events[open][1].start.offset + events[index][1].end.offset - events[index][1].start.offset) % 3)) {
4373
4528
  continue;
4374
4529
  }
4375
- use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index][1].end.offset - events[index][1].start.offset > 1 ? 2 : 1;
4530
+ const use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index][1].end.offset - events[index][1].start.offset > 1 ? 2 : 1;
4376
4531
  const start = { ...events[open][1].end };
4377
4532
  const end = { ...events[index][1].start };
4378
4533
  movePoint(start, -use);
4379
4534
  movePoint(end, use);
4380
- openingSequence = {
4535
+ const openingSequence = {
4381
4536
  type: use > 1 ? types.strongSequence : types.emphasisSequence,
4382
4537
  start,
4383
4538
  end: { ...events[open][1].end }
4384
4539
  };
4385
- closingSequence = {
4540
+ const closingSequence = {
4386
4541
  type: use > 1 ? types.strongSequence : types.emphasisSequence,
4387
4542
  start: { ...events[index][1].start },
4388
4543
  end
4389
4544
  };
4390
- text = {
4545
+ const text = {
4391
4546
  type: use > 1 ? types.strongText : types.emphasisText,
4392
4547
  start: { ...events[open][1].end },
4393
4548
  end: { ...events[index][1].start }
4394
4549
  };
4395
- group = {
4550
+ const group = {
4396
4551
  type: use > 1 ? types.strong : types.emphasis,
4397
4552
  start: { ...openingSequence.start },
4398
4553
  end: { ...closingSequence.end }
@@ -4420,14 +4575,13 @@ function resolveAllAttention(events, context) {
4420
4575
  ["exit", closingSequence, context],
4421
4576
  ["exit", group, context]
4422
4577
  ]);
4578
+ let offset = 0;
4423
4579
  if (events[index][1].end.offset - events[index][1].start.offset) {
4424
4580
  offset = 2;
4425
4581
  nextEvents = push(nextEvents, [
4426
4582
  ["enter", events[index][1], context],
4427
4583
  ["exit", events[index][1], context]
4428
4584
  ]);
4429
- } else {
4430
- offset = 0;
4431
4585
  }
4432
4586
  splice(events, open - 1, index - open + 3, nextEvents);
4433
4587
  index = open + nextEvents.length - offset - 2;
@@ -4464,8 +4618,8 @@ function tokenizeAttention(effects, ok2) {
4464
4618
  const token = effects.exit("attentionSequence");
4465
4619
  const after = classifyCharacter(code);
4466
4620
  ok(attentionMarkers, "expected `attentionMarkers` to be populated");
4467
- const open = !after || after === constants.characterGroupPunctuation && before || attentionMarkers.includes(code);
4468
- const close = !before || before === constants.characterGroupPunctuation && after || attentionMarkers.includes(previous);
4621
+ const open = !after || after === constants.characterGroupPunctuation && before || attentionMarkers.includes(code) && code !== codes.asterisk && code !== codes.underscore;
4622
+ const close = !before || before === constants.characterGroupPunctuation && after || attentionMarkers.includes(previous) && previous !== codes.asterisk && previous !== codes.underscore;
4469
4623
  token._open = Boolean(marker === codes.asterisk ? open : open && (before || !close));
4470
4624
  token._close = Boolean(marker === codes.asterisk ? close : close && (after || !open));
4471
4625
  return ok2(code);
@@ -4781,6 +4935,35 @@ var init_character_reference = __esm(() => {
4781
4935
  };
4782
4936
  });
4783
4937
 
4938
+ // ../../node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.js
4939
+ function tokenizeNonLazyContinuation(effects, ok2, nok) {
4940
+ const self2 = this;
4941
+ return start;
4942
+ function start(code) {
4943
+ if (code === codes.eof) {
4944
+ return nok(code);
4945
+ }
4946
+ ok(markdownLineEnding(code), "expected eol");
4947
+ effects.enter(types.lineEnding);
4948
+ effects.consume(code);
4949
+ effects.exit(types.lineEnding);
4950
+ return after;
4951
+ }
4952
+ function after(code) {
4953
+ return self2.parser.lazy[self2.now().line] ? nok(code) : ok2(code);
4954
+ }
4955
+ }
4956
+ var nonLazyContinuation;
4957
+ var init_partial_non_lazy_continuation = __esm(() => {
4958
+ init_development();
4959
+ init_dev4();
4960
+ init_default();
4961
+ nonLazyContinuation = {
4962
+ partial: true,
4963
+ tokenize: tokenizeNonLazyContinuation
4964
+ };
4965
+ });
4966
+
4784
4967
  // ../../node_modules/micromark-core-commonmark/dev/lib/code-fenced.js
4785
4968
  function tokenizeCodeFenced(effects, ok2, nok) {
4786
4969
  const self2 = this;
@@ -4936,33 +5119,13 @@ function tokenizeCodeFenced(effects, ok2, nok) {
4936
5119
  }
4937
5120
  }
4938
5121
  }
4939
- function tokenizeNonLazyContinuation(effects, ok2, nok) {
4940
- const self2 = this;
4941
- return start;
4942
- function start(code) {
4943
- if (code === codes.eof) {
4944
- return nok(code);
4945
- }
4946
- ok(markdownLineEnding(code), "expected eol");
4947
- effects.enter(types.lineEnding);
4948
- effects.consume(code);
4949
- effects.exit(types.lineEnding);
4950
- return lineStart;
4951
- }
4952
- function lineStart(code) {
4953
- return self2.parser.lazy[self2.now().line] ? nok(code) : ok2(code);
4954
- }
4955
- }
4956
- var nonLazyContinuation, codeFenced;
5122
+ var codeFenced;
4957
5123
  var init_code_fenced = __esm(() => {
4958
5124
  init_development();
4959
5125
  init_dev5();
4960
5126
  init_dev4();
4961
5127
  init_default();
4962
- nonLazyContinuation = {
4963
- partial: true,
4964
- tokenize: tokenizeNonLazyContinuation
4965
- };
5128
+ init_partial_non_lazy_continuation();
4966
5129
  codeFenced = {
4967
5130
  concrete: true,
4968
5131
  name: "codeFenced",
@@ -4972,16 +5135,11 @@ var init_code_fenced = __esm(() => {
4972
5135
 
4973
5136
  // ../../node_modules/micromark-core-commonmark/dev/lib/code-indented.js
4974
5137
  function tokenizeCodeIndented(effects, ok2, nok) {
4975
- const self2 = this;
4976
5138
  return start;
4977
5139
  function start(code) {
4978
5140
  ok(markdownSpace(code));
4979
5141
  effects.enter(types.codeIndented);
4980
- return factorySpace(effects, afterPrefix, types.linePrefix, constants.tabSize + 1)(code);
4981
- }
4982
- function afterPrefix(code) {
4983
- const tail = self2.events[self2.events.length - 1];
4984
- return tail && tail[1].type === types.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants.tabSize ? atBreak(code) : nok(code);
5142
+ return factorySpaceMinMax(effects, atBreak, nok, types.linePrefix, constants.tabSize, constants.tabSize)(code);
4985
5143
  }
4986
5144
  function atBreak(code) {
4987
5145
  if (code === codes.eof) {
@@ -5019,11 +5177,10 @@ function tokenizeFurtherStart(effects, ok, nok) {
5019
5177
  effects.exit(types.lineEnding);
5020
5178
  return furtherStart;
5021
5179
  }
5022
- return factorySpace(effects, afterPrefix, types.linePrefix, constants.tabSize + 1)(code);
5180
+ return factorySpaceMinMax(effects, ok, onNotEnoughPrefix, types.linePrefix, constants.tabSize, constants.tabSize)(code);
5023
5181
  }
5024
- function afterPrefix(code) {
5025
- const tail = self2.events[self2.events.length - 1];
5026
- return tail && tail[1].type === types.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants.tabSize ? ok(code) : markdownLineEnding(code) ? furtherStart(code) : nok(code);
5182
+ function onNotEnoughPrefix(code) {
5183
+ return markdownLineEnding(code) ? furtherStart(code) : nok(code);
5027
5184
  }
5028
5185
  }
5029
5186
  var codeIndented, furtherStart;
@@ -5833,8 +5990,6 @@ var init_hard_break_escape = __esm(() => {
5833
5990
  function resolveHeadingAtx(events, context) {
5834
5991
  let contentEnd = events.length - 2;
5835
5992
  let contentStart = 3;
5836
- let content;
5837
- let text;
5838
5993
  if (events[contentStart][1].type === types.whitespace) {
5839
5994
  contentStart += 2;
5840
5995
  }
@@ -5845,12 +6000,12 @@ function resolveHeadingAtx(events, context) {
5845
6000
  contentEnd -= contentStart + 1 === contentEnd ? 2 : 4;
5846
6001
  }
5847
6002
  if (contentEnd > contentStart) {
5848
- content = {
6003
+ const content = {
5849
6004
  type: types.atxHeadingText,
5850
6005
  start: events[contentStart][1].start,
5851
6006
  end: events[contentEnd][1].end
5852
6007
  };
5853
- text = {
6008
+ const text = {
5854
6009
  type: types.chunkText,
5855
6010
  start: events[contentStart][1].start,
5856
6011
  end: events[contentEnd][1].end,
@@ -6269,7 +6424,7 @@ function tokenizeHtmlFlow(effects, ok2, nok) {
6269
6424
  return continuation;
6270
6425
  }
6271
6426
  function continuationStart(code) {
6272
- return effects.check(nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
6427
+ return effects.check(nonLazyContinuation, continuationStartNonLazy, continuationAfter)(code);
6273
6428
  }
6274
6429
  function continuationStartNonLazy(code) {
6275
6430
  ok(markdownLineEnding(code));
@@ -6348,22 +6503,6 @@ function tokenizeHtmlFlow(effects, ok2, nok) {
6348
6503
  return ok2(code);
6349
6504
  }
6350
6505
  }
6351
- function tokenizeNonLazyContinuationStart(effects, ok, nok) {
6352
- const self2 = this;
6353
- return start;
6354
- function start(code) {
6355
- if (markdownLineEnding(code)) {
6356
- effects.enter(types.lineEnding);
6357
- effects.consume(code);
6358
- effects.exit(types.lineEnding);
6359
- return after;
6360
- }
6361
- return nok(code);
6362
- }
6363
- function after(code) {
6364
- return self2.parser.lazy[self2.now().line] ? nok(code) : ok(code);
6365
- }
6366
- }
6367
6506
  function tokenizeBlankLineBefore(effects, ok2, nok) {
6368
6507
  return start;
6369
6508
  function start(code) {
@@ -6374,13 +6513,14 @@ function tokenizeBlankLineBefore(effects, ok2, nok) {
6374
6513
  return effects.attempt(blankLine, ok2, nok);
6375
6514
  }
6376
6515
  }
6377
- var htmlFlow, blankLineBefore, nonLazyContinuationStart;
6516
+ var htmlFlow, blankLineBefore;
6378
6517
  var init_html_flow = __esm(() => {
6379
6518
  init_development();
6380
6519
  init_dev4();
6381
6520
  init_micromark_util_html_tag_name();
6382
6521
  init_default();
6383
6522
  init_blank_line();
6523
+ init_partial_non_lazy_continuation();
6384
6524
  htmlFlow = {
6385
6525
  concrete: true,
6386
6526
  name: "htmlFlow",
@@ -6388,10 +6528,6 @@ var init_html_flow = __esm(() => {
6388
6528
  tokenize: tokenizeHtmlFlow
6389
6529
  };
6390
6530
  blankLineBefore = { partial: true, tokenize: tokenizeBlankLineBefore };
6391
- nonLazyContinuationStart = {
6392
- partial: true,
6393
- tokenize: tokenizeNonLazyContinuationStart
6394
- };
6395
6531
  });
6396
6532
 
6397
6533
  // ../../node_modules/micromark-core-commonmark/dev/lib/html-text.js
@@ -6729,12 +6865,11 @@ function resolveAllLabelEnd(events) {
6729
6865
  function resolveToLabelEnd(events, context) {
6730
6866
  let index = events.length;
6731
6867
  let offset = 0;
6732
- let token;
6733
6868
  let open;
6734
6869
  let close;
6735
6870
  let media;
6736
6871
  while (index--) {
6737
- token = events[index][1];
6872
+ const token = events[index][1];
6738
6873
  if (open) {
6739
6874
  if (token.type === types.link || token.type === types.labelLink && token._inactive) {
6740
6875
  break;
@@ -6792,14 +6927,14 @@ function resolveToLabelEnd(events, context) {
6792
6927
  }
6793
6928
  function tokenizeLabelEnd(effects, ok2, nok) {
6794
6929
  const self2 = this;
6795
- let index = self2.events.length;
6930
+ const labelStarts = self2._labelStarts;
6796
6931
  let labelStart;
6797
6932
  let defined;
6798
- while (index--) {
6799
- if ((self2.events[index][1].type === types.labelImage || self2.events[index][1].type === types.labelLink) && !self2.events[index][1]._balanced) {
6800
- labelStart = self2.events[index][1];
6801
- break;
6933
+ if (labelStarts) {
6934
+ while (labelStarts.length > 0 && labelStarts[labelStarts.length - 1]._balanced) {
6935
+ labelStarts.pop();
6802
6936
  }
6937
+ labelStart = labelStarts[labelStarts.length - 1];
6803
6938
  }
6804
6939
  return start;
6805
6940
  function start(code) {
@@ -6831,6 +6966,8 @@ function tokenizeLabelEnd(effects, ok2, nok) {
6831
6966
  return effects.attempt(referenceCollapsedConstruct, labelEndOk, labelEndNok)(code);
6832
6967
  }
6833
6968
  function labelEndOk(code) {
6969
+ ok(labelStarts, "expected `labelStarts` to be populated");
6970
+ labelStarts.pop();
6834
6971
  return ok2(code);
6835
6972
  }
6836
6973
  function labelEndNok(code) {
@@ -6943,6 +7080,7 @@ var init_label_end = __esm(() => {
6943
7080
  // ../../node_modules/micromark-core-commonmark/dev/lib/label-start-image.js
6944
7081
  function tokenizeLabelStartImage(effects, ok2, nok) {
6945
7082
  const self2 = this;
7083
+ let labelImage;
6946
7084
  return start;
6947
7085
  function start(code) {
6948
7086
  ok(code === codes.exclamationMark, "expected `!`");
@@ -6957,13 +7095,18 @@ function tokenizeLabelStartImage(effects, ok2, nok) {
6957
7095
  effects.enter(types.labelMarker);
6958
7096
  effects.consume(code);
6959
7097
  effects.exit(types.labelMarker);
6960
- effects.exit(types.labelImage);
7098
+ labelImage = effects.exit(types.labelImage);
6961
7099
  return after;
6962
7100
  }
6963
7101
  return nok(code);
6964
7102
  }
6965
7103
  function after(code) {
6966
- return code === codes.caret && "_hiddenFootnoteSupport" in self2.parser.constructs ? nok(code) : ok2(code);
7104
+ if (code === codes.caret && "_hiddenFootnoteSupport" in self2.parser.constructs) {
7105
+ return nok(code);
7106
+ }
7107
+ self2._labelStarts = self2._labelStarts || [];
7108
+ self2._labelStarts.push(labelImage);
7109
+ return ok2(code);
6967
7110
  }
6968
7111
  }
6969
7112
  var labelStartImage;
@@ -6981,6 +7124,7 @@ var init_label_start_image = __esm(() => {
6981
7124
  // ../../node_modules/micromark-core-commonmark/dev/lib/label-start-link.js
6982
7125
  function tokenizeLabelStartLink(effects, ok2, nok) {
6983
7126
  const self2 = this;
7127
+ let labelLink;
6984
7128
  return start;
6985
7129
  function start(code) {
6986
7130
  ok(code === codes.leftSquareBracket, "expected `[`");
@@ -6988,11 +7132,16 @@ function tokenizeLabelStartLink(effects, ok2, nok) {
6988
7132
  effects.enter(types.labelMarker);
6989
7133
  effects.consume(code);
6990
7134
  effects.exit(types.labelMarker);
6991
- effects.exit(types.labelLink);
7135
+ labelLink = effects.exit(types.labelLink);
6992
7136
  return after;
6993
7137
  }
6994
7138
  function after(code) {
6995
- return code === codes.caret && "_hiddenFootnoteSupport" in self2.parser.constructs ? nok(code) : ok2(code);
7139
+ if (code === codes.caret && "_hiddenFootnoteSupport" in self2.parser.constructs) {
7140
+ return nok(code);
7141
+ }
7142
+ self2._labelStarts = self2._labelStarts || [];
7143
+ self2._labelStarts.push(labelLink);
7144
+ return ok2(code);
6996
7145
  }
6997
7146
  }
6998
7147
  var labelStartLink;
@@ -7221,6 +7370,7 @@ var init_list = __esm(() => {
7221
7370
 
7222
7371
  // ../../node_modules/micromark-core-commonmark/dev/lib/setext-underline.js
7223
7372
  function resolveToSetextUnderline(events, context) {
7373
+ const editMap = new EditMap;
7224
7374
  let index = events.length;
7225
7375
  let content;
7226
7376
  let text;
@@ -7236,7 +7386,7 @@ function resolveToSetextUnderline(events, context) {
7236
7386
  }
7237
7387
  } else {
7238
7388
  if (events[index][1].type === types.content) {
7239
- events.splice(index, 1);
7389
+ editMap.add(index, 1, []);
7240
7390
  }
7241
7391
  if (!definition && events[index][1].type === types.definition) {
7242
7392
  definition = index;
@@ -7254,13 +7404,14 @@ function resolveToSetextUnderline(events, context) {
7254
7404
  };
7255
7405
  events[text][1].type = types.setextHeadingText;
7256
7406
  if (definition) {
7257
- events.splice(text, 0, ["enter", heading, context]);
7258
- events.splice(definition + 1, 0, ["exit", events[content][1], context]);
7407
+ editMap.add(text, 0, [["enter", heading, context]]);
7408
+ editMap.add(definition + 1, 0, [["exit", events[content][1], context]]);
7259
7409
  events[content][1].end = { ...events[definition][1].end };
7260
7410
  } else {
7261
7411
  events[content][1] = heading;
7262
7412
  }
7263
- events.push(["exit", heading, context]);
7413
+ editMap.add(events.length, 0, [["exit", heading, context]]);
7414
+ editMap.consume(events);
7264
7415
  return events;
7265
7416
  }
7266
7417
  function tokenizeSetextUnderline(effects, ok2, nok) {
@@ -7457,6 +7608,7 @@ function createResolver(extraResolver) {
7457
7608
  }
7458
7609
  }
7459
7610
  function resolveAllLineSuffixes(events, context) {
7611
+ const editMap = new EditMap;
7460
7612
  let eventIndex = 0;
7461
7613
  while (++eventIndex <= events.length) {
7462
7614
  if ((eventIndex === events.length || events[eventIndex][1].type === types.lineEnding) && events[eventIndex - 1][1].type === types.data) {
@@ -7474,8 +7626,9 @@ function resolveAllLineSuffixes(events, context) {
7474
7626
  size++;
7475
7627
  bufferIndex--;
7476
7628
  }
7477
- if (bufferIndex)
7629
+ if (bufferIndex) {
7478
7630
  break;
7631
+ }
7479
7632
  bufferIndex = -1;
7480
7633
  } else if (chunk === codes.horizontalTab) {
7481
7634
  tabs = true;
@@ -7504,13 +7657,16 @@ function resolveAllLineSuffixes(events, context) {
7504
7657
  if (data.start.offset === data.end.offset) {
7505
7658
  Object.assign(data, token);
7506
7659
  } else {
7507
- events.splice(eventIndex, 0, ["enter", token, context], ["exit", token, context]);
7508
- eventIndex += 2;
7660
+ editMap.add(eventIndex, 0, [
7661
+ ["enter", token, context],
7662
+ ["exit", token, context]
7663
+ ]);
7509
7664
  }
7510
7665
  }
7511
7666
  eventIndex++;
7512
7667
  }
7513
7668
  }
7669
+ editMap.consume(events);
7514
7670
  return events;
7515
7671
  }
7516
7672
  var resolver, string, text;
@@ -8397,11 +8553,10 @@ function createTokenizer(parser, initialize, from) {
8397
8553
  debug("position: define skip: `%j`", point);
8398
8554
  }
8399
8555
  function main() {
8400
- let chunkIndex;
8401
8556
  while (point._index < chunks.length) {
8402
8557
  const chunk = chunks[point._index];
8403
8558
  if (typeof chunk === "string") {
8404
- chunkIndex = point._index;
8559
+ const chunkIndex = point._index;
8405
8560
  if (point._bufferIndex < 0) {
8406
8561
  point._bufferIndex = 0;
8407
8562
  }
@@ -8610,7 +8765,7 @@ function serializeChunks(chunks, expandTabs) {
8610
8765
  let value;
8611
8766
  if (typeof chunk === "string") {
8612
8767
  value = chunk;
8613
- } else
8768
+ } else {
8614
8769
  switch (chunk) {
8615
8770
  case codes.carriageReturn: {
8616
8771
  value = values.cr;
@@ -8629,8 +8784,9 @@ function serializeChunks(chunks, expandTabs) {
8629
8784
  break;
8630
8785
  }
8631
8786
  case codes.virtualSpace: {
8632
- if (!expandTabs && atTab)
8787
+ if (!expandTabs && atTab) {
8633
8788
  continue;
8789
+ }
8634
8790
  value = values.space;
8635
8791
  break;
8636
8792
  }
@@ -8639,6 +8795,7 @@ function serializeChunks(chunks, expandTabs) {
8639
8795
  value = String.fromCharCode(chunk);
8640
8796
  }
8641
8797
  }
8798
+ }
8642
8799
  atTab = chunk === codes.horizontalTab;
8643
8800
  result.push(value);
8644
8801
  }
@@ -8703,14 +8860,9 @@ function preprocess() {
8703
8860
  let atCarriageReturn;
8704
8861
  return preprocessor;
8705
8862
  function preprocessor(value, encoding, end) {
8706
- const chunks = [];
8707
- let match;
8708
- let next;
8709
- let startPosition;
8710
- let endPosition;
8711
- let code;
8712
8863
  value = buffer + (typeof value === "string" ? value.toString() : new TextDecoder(encoding || undefined).decode(value));
8713
- startPosition = 0;
8864
+ const chunks = [];
8865
+ let startPosition = 0;
8714
8866
  buffer = "";
8715
8867
  if (start) {
8716
8868
  if (value.charCodeAt(0) === codes.byteOrderMarker) {
@@ -8720,9 +8872,9 @@ function preprocess() {
8720
8872
  }
8721
8873
  while (startPosition < value.length) {
8722
8874
  search.lastIndex = startPosition;
8723
- match = search.exec(value);
8724
- endPosition = match && match.index !== undefined ? match.index : value.length;
8725
- code = value.charCodeAt(endPosition);
8875
+ const match = search.exec(value);
8876
+ const endPosition = match && match.index !== undefined ? match.index : value.length;
8877
+ const code = value.charCodeAt(endPosition);
8726
8878
  if (!match) {
8727
8879
  buffer = value.slice(startPosition);
8728
8880
  break;
@@ -8746,10 +8898,11 @@ function preprocess() {
8746
8898
  break;
8747
8899
  }
8748
8900
  case codes.ht: {
8749
- next = Math.ceil(column / constants.tabSize) * constants.tabSize;
8901
+ const next = Math.ceil(column / constants.tabSize) * constants.tabSize;
8750
8902
  chunks.push(codes.horizontalTab);
8751
- while (column++ < next)
8903
+ while (column++ < next) {
8752
8904
  chunks.push(codes.virtualSpace);
8905
+ }
8753
8906
  break;
8754
8907
  }
8755
8908
  case codes.lf: {
@@ -8766,10 +8919,12 @@ function preprocess() {
8766
8919
  startPosition = endPosition + 1;
8767
8920
  }
8768
8921
  if (end) {
8769
- if (atCarriageReturn)
8922
+ if (atCarriageReturn) {
8770
8923
  chunks.push(codes.carriageReturn);
8771
- if (buffer)
8924
+ }
8925
+ if (buffer) {
8772
8926
  chunks.push(buffer);
8927
+ }
8773
8928
  chunks.push(codes.eof);
8774
8929
  }
8775
8930
  return chunks;
@@ -8822,6 +8977,8 @@ function fromMarkdown(value, encoding, options) {
8822
8977
  }
8823
8978
  function compiler(options) {
8824
8979
  const config = {
8980
+ afterExit: [],
8981
+ beforeEnter: [],
8825
8982
  transforms: [],
8826
8983
  canContainEols: ["emphasis", "fragment", "heading", "paragraph", "strong"],
8827
8984
  enter: {
@@ -8923,7 +9080,7 @@ function compiler(options) {
8923
9080
  const data = {};
8924
9081
  return compile;
8925
9082
  function compile(events) {
8926
- let tree = { type: "root", children: [] };
9083
+ let tree = { type: "root", children: [], position: undefined };
8927
9084
  const context = {
8928
9085
  stack: [tree],
8929
9086
  tokenStack: [],
@@ -8935,23 +9092,32 @@ function compiler(options) {
8935
9092
  data
8936
9093
  };
8937
9094
  const listStack = [];
9095
+ const prepared = [];
8938
9096
  let index = -1;
8939
9097
  while (++index < events.length) {
9098
+ prepared.push(events[index]);
8940
9099
  if (events[index][1].type === types.listOrdered || events[index][1].type === types.listUnordered) {
8941
9100
  if (events[index][0] === "enter") {
8942
- listStack.push(index);
9101
+ listStack.push(prepared.length - 1);
8943
9102
  } else {
8944
9103
  const tail = listStack.pop();
8945
9104
  ok(typeof tail === "number", "expected list to be open");
8946
- index = prepareList(events, tail, index);
9105
+ prepareList(prepared, tail);
8947
9106
  }
8948
9107
  }
8949
9108
  }
9109
+ events = prepared;
8950
9110
  index = -1;
8951
9111
  while (++index < events.length) {
8952
9112
  const handler = config[events[index][0]];
9113
+ if (events[index][0] === "enter" && config.beforeEnter.length > 0) {
9114
+ callListeners(config.beforeEnter, { ...context, sliceSerialize: events[index][2].sliceSerialize }, events[index][1]);
9115
+ }
8953
9116
  if (own3.call(handler, events[index][1].type)) {
8954
- handler[events[index][1].type].call(Object.assign({ sliceSerialize: events[index][2].sliceSerialize }, context), events[index][1]);
9117
+ handler[events[index][1].type].call({ ...context, sliceSerialize: events[index][2].sliceSerialize }, events[index][1]);
9118
+ }
9119
+ if (events[index][0] === "exit" && config.afterExit.length > 0) {
9120
+ callListeners(config.afterExit, { ...context, sliceSerialize: events[index][2].sliceSerialize }, events[index][1]);
8955
9121
  }
8956
9122
  }
8957
9123
  if (context.tokenStack.length > 0) {
@@ -8969,7 +9135,14 @@ function compiler(options) {
8969
9135
  }
8970
9136
  return tree;
8971
9137
  }
8972
- function prepareList(events, start, length) {
9138
+ function callListeners(listeners, context, token) {
9139
+ let index = -1;
9140
+ while (++index < listeners.length) {
9141
+ listeners[index].call(context, token);
9142
+ }
9143
+ }
9144
+ function prepareList(events, start) {
9145
+ const end = events.length - 1;
8973
9146
  let index = start - 1;
8974
9147
  let containerBalance = -1;
8975
9148
  let listSpread = false;
@@ -8977,7 +9150,8 @@ function compiler(options) {
8977
9150
  let lineIndex;
8978
9151
  let firstBlankLineIndex;
8979
9152
  let atMarker;
8980
- while (++index <= length) {
9153
+ const insertions = [];
9154
+ while (++index <= end) {
8981
9155
  const event = events[index];
8982
9156
  switch (event[1].type) {
8983
9157
  case types.listUnordered:
@@ -9034,9 +9208,10 @@ function compiler(options) {
9034
9208
  listItem._spread = true;
9035
9209
  }
9036
9210
  listItem.end = Object.assign({}, lineIndex ? events[lineIndex][1].start : event[1].end);
9037
- events.splice(lineIndex || index, 0, ["exit", listItem, event[2]]);
9038
- index++;
9039
- length++;
9211
+ insertions.push({
9212
+ at: lineIndex || index,
9213
+ event: ["exit", listItem, event[2]]
9214
+ });
9040
9215
  }
9041
9216
  if (event[1].type === types.listItemPrefix) {
9042
9217
  const item = {
@@ -9046,16 +9221,23 @@ function compiler(options) {
9046
9221
  end: undefined
9047
9222
  };
9048
9223
  listItem = item;
9049
- events.splice(index, 0, ["enter", item, event[2]]);
9050
- index++;
9051
- length++;
9224
+ insertions.push({ at: index, event: ["enter", item, event[2]] });
9052
9225
  firstBlankLineIndex = undefined;
9053
9226
  atMarker = true;
9054
9227
  }
9055
9228
  }
9056
9229
  }
9230
+ const listEvents = events.splice(start);
9231
+ let insertion = 0;
9232
+ index = -1;
9233
+ while (++index < listEvents.length) {
9234
+ while (insertion < insertions.length && insertions[insertion].at === start + index) {
9235
+ events.push(insertions[insertion++].event);
9236
+ }
9237
+ events.push(listEvents[index]);
9238
+ }
9239
+ ok(insertion === insertions.length, "expected insertions to be merged");
9057
9240
  events[start][1]._spread = listSpread;
9058
- return length;
9059
9241
  }
9060
9242
  function opener(create, and) {
9061
9243
  return open;
@@ -9095,7 +9277,8 @@ function compiler(options) {
9095
9277
  const open = this.tokenStack.pop();
9096
9278
  if (!open) {
9097
9279
  throw new Error("Cannot close `" + token.type + "` (" + stringifyPosition({ start: token.start, end: token.end }) + "): it’s not open");
9098
- } else if (open[0].type !== token.type) {
9280
+ }
9281
+ if (open[0].type !== token.type) {
9099
9282
  if (onExitError) {
9100
9283
  onExitError.call(this, token, open[0]);
9101
9284
  } else {
@@ -9392,13 +9575,19 @@ function compiler(options) {
9392
9575
  node.url = "mailto:" + this.sliceSerialize(token);
9393
9576
  }
9394
9577
  function blockQuote() {
9395
- return { type: "blockquote", children: [] };
9578
+ return { type: "blockquote", children: [], position: undefined };
9396
9579
  }
9397
9580
  function codeFlow() {
9398
- return { type: "code", lang: null, meta: null, value: "" };
9581
+ return {
9582
+ type: "code",
9583
+ lang: null,
9584
+ meta: null,
9585
+ value: "",
9586
+ position: undefined
9587
+ };
9399
9588
  }
9400
9589
  function codeText() {
9401
- return { type: "inlineCode", value: "" };
9590
+ return { type: "inlineCode", value: "", position: undefined };
9402
9591
  }
9403
9592
  function definition() {
9404
9593
  return {
@@ -9406,30 +9595,44 @@ function compiler(options) {
9406
9595
  identifier: "",
9407
9596
  label: null,
9408
9597
  title: null,
9409
- url: ""
9598
+ url: "",
9599
+ position: undefined
9410
9600
  };
9411
9601
  }
9412
9602
  function emphasis() {
9413
- return { type: "emphasis", children: [] };
9603
+ return { type: "emphasis", children: [], position: undefined };
9414
9604
  }
9415
9605
  function heading() {
9416
9606
  return {
9417
9607
  type: "heading",
9418
9608
  depth: 0,
9419
- children: []
9609
+ children: [],
9610
+ position: undefined
9420
9611
  };
9421
9612
  }
9422
9613
  function hardBreak() {
9423
- return { type: "break" };
9614
+ return { type: "break", position: undefined };
9424
9615
  }
9425
9616
  function html() {
9426
- return { type: "html", value: "" };
9617
+ return { type: "html", value: "", position: undefined };
9427
9618
  }
9428
9619
  function image() {
9429
- return { type: "image", title: null, url: "", alt: null };
9620
+ return {
9621
+ type: "image",
9622
+ title: null,
9623
+ url: "",
9624
+ alt: null,
9625
+ position: undefined
9626
+ };
9430
9627
  }
9431
9628
  function link() {
9432
- return { type: "link", title: null, url: "", children: [] };
9629
+ return {
9630
+ type: "link",
9631
+ title: null,
9632
+ url: "",
9633
+ children: [],
9634
+ position: undefined
9635
+ };
9433
9636
  }
9434
9637
  function list(token) {
9435
9638
  return {
@@ -9437,7 +9640,8 @@ function compiler(options) {
9437
9640
  ordered: token.type === "listOrdered",
9438
9641
  start: null,
9439
9642
  spread: token._spread,
9440
- children: []
9643
+ children: [],
9644
+ position: undefined
9441
9645
  };
9442
9646
  }
9443
9647
  function listItem(token) {
@@ -9445,20 +9649,21 @@ function compiler(options) {
9445
9649
  type: "listItem",
9446
9650
  spread: token._spread,
9447
9651
  checked: null,
9448
- children: []
9652
+ children: [],
9653
+ position: undefined
9449
9654
  };
9450
9655
  }
9451
9656
  function paragraph() {
9452
- return { type: "paragraph", children: [] };
9657
+ return { type: "paragraph", children: [], position: undefined };
9453
9658
  }
9454
9659
  function strong() {
9455
- return { type: "strong", children: [] };
9660
+ return { type: "strong", children: [], position: undefined };
9456
9661
  }
9457
9662
  function text() {
9458
- return { type: "text", value: "" };
9663
+ return { type: "text", value: "", position: undefined };
9459
9664
  }
9460
9665
  function thematicBreak() {
9461
- return { type: "thematicBreak" };
9666
+ return { type: "thematicBreak", position: undefined };
9462
9667
  }
9463
9668
  }
9464
9669
  function point2(d) {
@@ -9494,6 +9699,14 @@ function extension(combined, extension) {
9494
9699
  }
9495
9700
  break;
9496
9701
  }
9702
+ case "afterExit":
9703
+ case "beforeEnter": {
9704
+ const right = extension[key];
9705
+ if (right) {
9706
+ combined[key].push(right);
9707
+ }
9708
+ break;
9709
+ }
9497
9710
  case "enter":
9498
9711
  case "exit": {
9499
9712
  const right = extension[key];
@@ -9509,9 +9722,8 @@ function extension(combined, extension) {
9509
9722
  function defaultOnError(left, right) {
9510
9723
  if (left) {
9511
9724
  throw new Error("Cannot close `" + left.type + "` (" + stringifyPosition({ start: left.start, end: left.end }) + "): a different token (`" + right.type + "`, " + stringifyPosition({ start: right.start, end: right.end }) + ") is open");
9512
- } else {
9513
- throw new Error("Cannot close document, a token (`" + right.type + "`, " + stringifyPosition({ start: right.start, end: right.end }) + ") is still open");
9514
9725
  }
9726
+ throw new Error("Cannot close document, a token (`" + right.type + "`, " + stringifyPosition({ start: right.start, end: right.end }) + ") is still open");
9515
9727
  }
9516
9728
  var own3;
9517
9729
  var init_lib5 = __esm(() => {
@@ -17568,15 +17780,13 @@ function findAndReplace(tree, list, options) {
17568
17780
  find.lastIndex = position + 1;
17569
17781
  } else {
17570
17782
  if (start !== position) {
17571
- nodes.push({
17572
- type: "text",
17573
- value: node.value.slice(start, position)
17574
- });
17783
+ add({ type: "text", value: node.value.slice(start, position) });
17575
17784
  }
17576
17785
  if (Array.isArray(value)) {
17577
- nodes.push(...value);
17786
+ for (const child of value)
17787
+ add(child);
17578
17788
  } else if (value) {
17579
- nodes.push(value);
17789
+ add(value);
17580
17790
  }
17581
17791
  start = position + match[0].length;
17582
17792
  change = true;
@@ -17588,20 +17798,28 @@ function findAndReplace(tree, list, options) {
17588
17798
  }
17589
17799
  if (change) {
17590
17800
  if (start < node.value.length) {
17591
- nodes.push({ type: "text", value: node.value.slice(start) });
17801
+ add({ type: "text", value: node.value.slice(start) });
17592
17802
  }
17593
17803
  parent.children.splice(index, 1, ...nodes);
17594
17804
  } else {
17595
17805
  nodes = [node];
17596
17806
  }
17597
17807
  return index + nodes.length;
17808
+ function add(child) {
17809
+ const previous = nodes[nodes.length - 1];
17810
+ if (previous && previous.type === "text" && child.type === "text") {
17811
+ previous.value += child.value;
17812
+ } else {
17813
+ nodes.push(child);
17814
+ }
17815
+ }
17598
17816
  }
17599
17817
  }
17600
17818
  function toPairs(tupleOrList) {
17601
- const result = [];
17602
17819
  if (!Array.isArray(tupleOrList)) {
17603
17820
  throw new TypeError("Expected find and replace tuple or list of tuples");
17604
17821
  }
17822
+ const result = [];
17605
17823
  const list = !tupleOrList[0] || Array.isArray(tupleOrList[0]) ? tupleOrList : [tupleOrList];
17606
17824
  let index = -1;
17607
17825
  while (++index < list.length) {
@@ -17896,35 +18114,39 @@ function gfmStrikethroughFromMarkdown() {
17896
18114
  }
17897
18115
  function gfmStrikethroughToMarkdown() {
17898
18116
  return {
18117
+ handlers: { delete: handleDelete },
17899
18118
  unsafe: [
17900
18119
  {
17901
18120
  character: "~",
17902
18121
  inConstruct: "phrasing",
17903
18122
  notInConstruct: constructsWithoutStrikethrough
17904
18123
  }
17905
- ],
17906
- handlers: { delete: handleDelete }
18124
+ ]
17907
18125
  };
17908
18126
  }
17909
18127
  function enterStrikethrough(token) {
17910
- this.enter({ type: "delete", children: [] }, token);
18128
+ this.enter({ type: "delete", children: [], position: undefined }, token);
17911
18129
  }
17912
18130
  function exitStrikethrough(token) {
17913
18131
  this.exit(token);
17914
18132
  }
17915
18133
  function handleDelete(node, _, state, info) {
17916
18134
  const tracker = state.createTracker(info);
18135
+ const sequence = state.stack.includes("strikethrough") ? "~" : "~~";
17917
18136
  const exit = state.enter("strikethrough");
17918
- let value = tracker.move("~~");
18137
+ let value = tracker.move(sequence);
17919
18138
  value += state.containerPhrasing(node, {
17920
18139
  ...tracker.current(),
17921
18140
  before: value,
17922
18141
  after: "~"
17923
18142
  });
17924
- value += tracker.move("~~");
18143
+ value += tracker.move(sequence);
17925
18144
  exit();
17926
18145
  return value;
17927
18146
  }
18147
+ function attentionDelete() {
18148
+ return { construct: "strikethrough", markers: ["~"], sizes: [2, 1] };
18149
+ }
17928
18150
  function peekDelete() {
17929
18151
  return "~";
17930
18152
  }
@@ -17938,6 +18160,7 @@ var init_lib13 = __esm(() => {
17938
18160
  "titleQuote",
17939
18161
  "titleApostrophe"
17940
18162
  ];
18163
+ handleDelete.attention = attentionDelete;
17941
18164
  handleDelete.peek = peekDelete;
17942
18165
  });
17943
18166
 
@@ -18081,6 +18304,35 @@ function toAlignment(value) {
18081
18304
  return code === 67 || code === 99 ? 99 : code === 76 || code === 108 ? 108 : code === 82 || code === 114 ? 114 : 0;
18082
18305
  }
18083
18306
 
18307
+ // ../../node_modules/mdast-util-phrasing/lib/index.js
18308
+ var phrasing;
18309
+ var init_lib14 = __esm(() => {
18310
+ init_unist_util_is();
18311
+ phrasing = convert([
18312
+ "break",
18313
+ "delete",
18314
+ "emphasis",
18315
+ "footnote",
18316
+ "footnoteReference",
18317
+ "image",
18318
+ "imageReference",
18319
+ "inlineCode",
18320
+ "inlineMath",
18321
+ "link",
18322
+ "linkReference",
18323
+ "mdxJsxTextElement",
18324
+ "mdxTextExpression",
18325
+ "strong",
18326
+ "text",
18327
+ "textDirective"
18328
+ ]);
18329
+ });
18330
+
18331
+ // ../../node_modules/mdast-util-phrasing/index.js
18332
+ var init_mdast_util_phrasing = __esm(() => {
18333
+ init_lib14();
18334
+ });
18335
+
18084
18336
  // ../../node_modules/zwitch/index.js
18085
18337
  function zwitch(key, options) {
18086
18338
  const settings = options || {};
@@ -18193,9 +18445,10 @@ function listInScope(stack, list, none) {
18193
18445
  function hardBreak(_, _1, state, info) {
18194
18446
  let index = -1;
18195
18447
  while (++index < state.unsafe.length) {
18196
- if (state.unsafe[index].character === `
18197
- ` && patternInScope(state.stack, state.unsafe[index])) {
18198
- return /[ \t]/.test(info.before) ? "" : " ";
18448
+ const pattern = state.unsafe[index];
18449
+ if (pattern.character === `
18450
+ ` && !pattern.before && !pattern.after && patternInScope(state.stack, pattern)) {
18451
+ return /[\t ]/.test(info.before) ? "" : " ";
18199
18452
  }
18200
18453
  }
18201
18454
  return "\\\n";
@@ -18228,7 +18481,7 @@ function longestStreak(value, substring) {
18228
18481
 
18229
18482
  // ../../node_modules/mdast-util-to-markdown/lib/util/format-code-as-indented.js
18230
18483
  function formatCodeAsIndented(node, state) {
18231
- return Boolean(state.options.fences === false && node.value && !node.lang && /[^ \r\n]/.test(node.value) && !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node.value));
18484
+ return Boolean(state.options.fences === false && node.value && !node.lang && /[^\n\r ]/.test(node.value) && !/^[\t ]*(?:[\n\r]|$)|(?:^|[\n\r])[\t ]*$/.test(node.value));
18232
18485
  }
18233
18486
 
18234
18487
  // ../../node_modules/mdast-util-to-markdown/lib/util/check-fence.js
@@ -18244,7 +18497,6 @@ function checkFence(state) {
18244
18497
  function code(node, _, state, info) {
18245
18498
  const marker = checkFence(state);
18246
18499
  const raw = node.value || "";
18247
- const suffix = marker === "`" ? "GraveAccent" : "Tilde";
18248
18500
  if (formatCodeAsIndented(node, state)) {
18249
18501
  const exit = state.enter("codeIndented");
18250
18502
  const value = state.indentLines(raw, map3);
@@ -18254,6 +18506,7 @@ function code(node, _, state, info) {
18254
18506
  const tracker = state.createTracker(info);
18255
18507
  const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3));
18256
18508
  const exit = state.enter("codeFenced");
18509
+ const suffix = marker === "`" ? "GraveAccent" : "Tilde";
18257
18510
  let value = tracker.move(sequence);
18258
18511
  if (node.lang) {
18259
18512
  const subexit = state.enter(`codeFencedLang${suffix}`);
@@ -18356,64 +18609,34 @@ function checkEmphasis(state) {
18356
18609
  return marker;
18357
18610
  }
18358
18611
 
18359
- // ../../node_modules/mdast-util-to-markdown/lib/util/encode-character-reference.js
18360
- function encodeCharacterReference(code) {
18361
- return "&#x" + code.toString(16).toUpperCase() + ";";
18362
- }
18363
-
18364
- // ../../node_modules/mdast-util-to-markdown/lib/util/encode-info.js
18365
- function encodeInfo(outside, inside, marker) {
18366
- const outsideKind = classifyCharacter(outside);
18367
- const insideKind = classifyCharacter(inside);
18368
- if (outsideKind === undefined) {
18369
- return insideKind === undefined ? marker === "_" ? { inside: true, outside: true } : { inside: false, outside: false } : insideKind === 1 ? { inside: true, outside: true } : { inside: false, outside: true };
18370
- }
18371
- if (outsideKind === 1) {
18372
- return insideKind === undefined ? { inside: false, outside: false } : insideKind === 1 ? { inside: true, outside: true } : { inside: false, outside: false };
18373
- }
18374
- return insideKind === undefined ? { inside: false, outside: false } : insideKind === 1 ? { inside: true, outside: false } : { inside: false, outside: false };
18375
- }
18376
- var init_encode_info = __esm(() => {
18377
- init_dev6();
18378
- });
18379
-
18380
18612
  // ../../node_modules/mdast-util-to-markdown/lib/handle/emphasis.js
18381
18613
  function emphasis(node, _, state, info) {
18382
- const marker = checkEmphasis(state);
18383
- const exit = state.enter("emphasis");
18384
- const tracker = state.createTracker(info);
18385
- const before = tracker.move(marker);
18386
- let between = tracker.move(state.containerPhrasing(node, {
18387
- after: marker,
18388
- before,
18389
- ...tracker.current()
18390
- }));
18391
- const betweenHead = between.charCodeAt(0);
18392
- const open = encodeInfo(info.before.charCodeAt(info.before.length - 1), betweenHead, marker);
18393
- if (open.inside) {
18394
- between = encodeCharacterReference(betweenHead) + between.slice(1);
18395
- }
18396
- const betweenTail = between.charCodeAt(between.length - 1);
18397
- const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);
18398
- if (close.inside) {
18399
- between = between.slice(0, -1) + encodeCharacterReference(betweenTail);
18400
- }
18401
- const after = tracker.move(marker);
18614
+ const exit = state.enter("phrasing");
18615
+ const value = state.containerPhrasing({ type: "root", children: [node] }, info);
18402
18616
  exit();
18403
- state.attentionEncodeSurroundingInfo = {
18404
- after: close.outside,
18405
- before: open.outside
18617
+ return value;
18618
+ }
18619
+ function attention2(_, state) {
18620
+ const marker = checkEmphasis(state);
18621
+ return {
18622
+ construct: "emphasis",
18623
+ markers: marker === "*" ? ["*", "_"] : ["_", "*"],
18624
+ sizes: [1]
18406
18625
  };
18407
- return before + between + after;
18408
18626
  }
18409
- function emphasisPeek(_, _1, state) {
18627
+ function peek(_, _1, state) {
18410
18628
  return state.options.emphasis || "*";
18411
18629
  }
18412
18630
  var init_emphasis = __esm(() => {
18413
- init_encode_info();
18414
- emphasis.peek = emphasisPeek;
18631
+ emphasis.attention = attention2;
18632
+ emphasis.peek = peek;
18415
18633
  });
18416
18634
 
18635
+ // ../../node_modules/mdast-util-to-markdown/lib/util/encode-character-reference.js
18636
+ function encodeCharacterReference(code) {
18637
+ return "&#x" + code.toString(16).toUpperCase() + ";";
18638
+ }
18639
+
18417
18640
  // ../../node_modules/unist-util-visit/node_modules/unist-util-visit-parents/lib/color.node.js
18418
18641
  function color2(d) {
18419
18642
  return "\x1B[33m" + d + "\x1B[39m";
@@ -18480,14 +18703,14 @@ function toResult2(value) {
18480
18703
  return value === null || value === undefined ? empty2 : [value];
18481
18704
  }
18482
18705
  var empty2, CONTINUE2 = true, EXIT2 = false, SKIP2 = "skip";
18483
- var init_lib14 = __esm(() => {
18706
+ var init_lib15 = __esm(() => {
18484
18707
  init_unist_util_is();
18485
18708
  empty2 = [];
18486
18709
  });
18487
18710
 
18488
18711
  // ../../node_modules/unist-util-visit/node_modules/unist-util-visit-parents/index.js
18489
18712
  var init_unist_util_visit_parents2 = __esm(() => {
18490
- init_lib14();
18713
+ init_lib15();
18491
18714
  });
18492
18715
 
18493
18716
  // ../../node_modules/unist-util-visit/lib/index.js
@@ -18511,14 +18734,14 @@ function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
18511
18734
  return visitor(node, index, parent);
18512
18735
  }
18513
18736
  }
18514
- var init_lib15 = __esm(() => {
18737
+ var init_lib16 = __esm(() => {
18515
18738
  init_unist_util_visit_parents2();
18516
18739
  init_unist_util_visit_parents2();
18517
18740
  });
18518
18741
 
18519
18742
  // ../../node_modules/unist-util-visit/index.js
18520
18743
  var init_unist_util_visit = __esm(() => {
18521
- init_lib15();
18744
+ init_lib16();
18522
18745
  });
18523
18746
 
18524
18747
  // ../../node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.js
@@ -18567,8 +18790,9 @@ function heading(node, _, state, info) {
18567
18790
  `,
18568
18791
  ...tracker.current()
18569
18792
  });
18570
- if (/^[\t ]/.test(value)) {
18571
- value = encodeCharacterReference(value.charCodeAt(0)) + value.slice(1);
18793
+ const head = value.charCodeAt(0);
18794
+ if (head === 9 || head === 32) {
18795
+ value = encodeCharacterReference(head) + value.slice(1);
18572
18796
  }
18573
18797
  value = value ? sequence + " " + value : sequence;
18574
18798
  if (state.options.closeAtx) {
@@ -18655,7 +18879,9 @@ function imageReference(node, _, state, info) {
18655
18879
  value += tracker.move(alt + "][");
18656
18880
  subexit();
18657
18881
  const stack = state.stack;
18658
- state.stack = [];
18882
+ state.stack = stack.filter(function(d) {
18883
+ return d !== "phrasing";
18884
+ });
18659
18885
  subexit = state.enter("reference");
18660
18886
  const reference = state.safe(state.associationId(node), {
18661
18887
  before: value,
@@ -18689,15 +18915,15 @@ function inlineCode(node, _, state) {
18689
18915
  while (new RegExp("(^|[^`])" + sequence + "([^`]|$)").test(value)) {
18690
18916
  sequence += "`";
18691
18917
  }
18692
- if (/[^ \r\n]/.test(value) && (/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value) || /^`|`$/.test(value))) {
18918
+ if (/[^\n\r ]/.test(value) && (/^[\n\r ]/.test(value) && /[\n\r ]$/.test(value) || /^`|`$/.test(value))) {
18693
18919
  value = " " + value + " ";
18694
18920
  }
18695
18921
  while (++index < state.unsafe.length) {
18696
18922
  const pattern = state.unsafe[index];
18697
18923
  const expression = state.compilePattern(pattern);
18698
- let match;
18699
18924
  if (!pattern.atBreak)
18700
18925
  continue;
18926
+ let match;
18701
18927
  while (match = expression.exec(value)) {
18702
18928
  let position = match.index;
18703
18929
  if (value.charCodeAt(position) === 10 && value.charCodeAt(position - 1) === 13) {
@@ -18718,7 +18944,7 @@ var init_inline_code = __esm(() => {
18718
18944
  // ../../node_modules/mdast-util-to-markdown/lib/util/format-link-as-autolink.js
18719
18945
  function formatLinkAsAutolink(node, state) {
18720
18946
  const raw = toString(node);
18721
- return Boolean(!state.options.resourceLink && node.url && !node.title && node.children && node.children.length === 1 && node.children[0].type === "text" && (raw === node.url || "mailto:" + raw === node.url) && /^[a-z][a-z+.-]+:/i.test(node.url) && !/[\0- <>\u007F]/.test(node.url));
18947
+ return Boolean(!state.options.resourceLink && node.url && !node.title && node.children && node.children.length === 1 && node.children[0].type === "text" && (raw === node.url || "mailto:" + raw === node.url) && /^[a-z][+\-.a-z]+:/i.test(node.url) && !/[\0- <>\u007F]/.test(node.url));
18722
18948
  }
18723
18949
  var init_format_link_as_autolink = __esm(() => {
18724
18950
  init_mdast_util_to_string();
@@ -18729,12 +18955,12 @@ function link(node, _, state, info) {
18729
18955
  const quote = checkQuote(state);
18730
18956
  const suffix = quote === '"' ? "Quote" : "Apostrophe";
18731
18957
  const tracker = state.createTracker(info);
18732
- let exit;
18733
- let subexit;
18734
18958
  if (formatLinkAsAutolink(node, state)) {
18735
18959
  const stack = state.stack;
18736
- state.stack = [];
18737
- exit = state.enter("autolink");
18960
+ state.stack = stack.filter(function(d) {
18961
+ return d !== "phrasing";
18962
+ });
18963
+ const exit = state.enter("autolink");
18738
18964
  let value = tracker.move("<");
18739
18965
  value += tracker.move(state.containerPhrasing(node, {
18740
18966
  before: value,
@@ -18746,8 +18972,8 @@ function link(node, _, state, info) {
18746
18972
  state.stack = stack;
18747
18973
  return value;
18748
18974
  }
18749
- exit = state.enter("link");
18750
- subexit = state.enter("label");
18975
+ const exit = state.enter("link");
18976
+ let subexit = state.enter("label");
18751
18977
  let value = tracker.move("[");
18752
18978
  value += tracker.move(state.containerPhrasing(node, {
18753
18979
  before: value,
@@ -18808,7 +19034,9 @@ function linkReference(node, _, state, info) {
18808
19034
  value += tracker.move(text + "][");
18809
19035
  subexit();
18810
19036
  const stack = state.stack;
18811
- state.stack = [];
19037
+ state.stack = stack.filter(function(d) {
19038
+ return d !== "phrasing";
19039
+ });
18812
19040
  subexit = state.enter("reference");
18813
19041
  const reference = state.safe(state.associationId(node), {
18814
19042
  before: value,
@@ -18961,42 +19189,17 @@ function paragraph(node, _, state, info) {
18961
19189
  return value;
18962
19190
  }
18963
19191
 
18964
- // ../../node_modules/mdast-util-phrasing/lib/index.js
18965
- var phrasing;
18966
- var init_lib16 = __esm(() => {
18967
- init_unist_util_is();
18968
- phrasing = convert([
18969
- "break",
18970
- "delete",
18971
- "emphasis",
18972
- "footnote",
18973
- "footnoteReference",
18974
- "image",
18975
- "imageReference",
18976
- "inlineCode",
18977
- "inlineMath",
18978
- "link",
18979
- "linkReference",
18980
- "mdxJsxTextElement",
18981
- "mdxTextExpression",
18982
- "strong",
18983
- "text",
18984
- "textDirective"
18985
- ]);
18986
- });
18987
-
18988
- // ../../node_modules/mdast-util-phrasing/index.js
18989
- var init_mdast_util_phrasing = __esm(() => {
18990
- init_lib16();
18991
- });
18992
-
18993
19192
  // ../../node_modules/mdast-util-to-markdown/lib/handle/root.js
18994
19193
  function root(node, _, state, info) {
18995
19194
  const hasPhrasing = node.children.some(function(d) {
18996
19195
  return phrasing(d);
18997
19196
  });
18998
- const container = hasPhrasing ? state.containerPhrasing : state.containerFlow;
18999
- return container.call(state, node, info);
19197
+ if (!hasPhrasing)
19198
+ return state.containerFlow(node, info);
19199
+ const exit = state.enter("phrasing");
19200
+ const value = state.containerPhrasing(node, info);
19201
+ exit();
19202
+ return value;
19000
19203
  }
19001
19204
  var init_root = __esm(() => {
19002
19205
  init_mdast_util_phrasing();
@@ -19013,44 +19216,36 @@ function checkStrong(state) {
19013
19216
 
19014
19217
  // ../../node_modules/mdast-util-to-markdown/lib/handle/strong.js
19015
19218
  function strong(node, _, state, info) {
19016
- const marker = checkStrong(state);
19017
- const exit = state.enter("strong");
19018
- const tracker = state.createTracker(info);
19019
- const before = tracker.move(marker + marker);
19020
- let between = tracker.move(state.containerPhrasing(node, {
19021
- after: marker,
19022
- before,
19023
- ...tracker.current()
19024
- }));
19025
- const betweenHead = between.charCodeAt(0);
19026
- const open = encodeInfo(info.before.charCodeAt(info.before.length - 1), betweenHead, marker);
19027
- if (open.inside) {
19028
- between = encodeCharacterReference(betweenHead) + between.slice(1);
19029
- }
19030
- const betweenTail = between.charCodeAt(between.length - 1);
19031
- const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);
19032
- if (close.inside) {
19033
- between = between.slice(0, -1) + encodeCharacterReference(betweenTail);
19034
- }
19035
- const after = tracker.move(marker + marker);
19219
+ const exit = state.enter("phrasing");
19220
+ const value = state.containerPhrasing({ type: "root", children: [node] }, info);
19036
19221
  exit();
19037
- state.attentionEncodeSurroundingInfo = {
19038
- after: close.outside,
19039
- before: open.outside
19222
+ return value;
19223
+ }
19224
+ function attention3(_, state) {
19225
+ const marker = checkStrong(state);
19226
+ return {
19227
+ construct: "strong",
19228
+ markers: marker === "*" ? ["*", "_"] : ["_", "*"],
19229
+ sizes: [2]
19040
19230
  };
19041
- return before + between + after;
19042
19231
  }
19043
- function strongPeek(_, _1, state) {
19232
+ function peek2(_, _1, state) {
19044
19233
  return state.options.strong || "*";
19045
19234
  }
19046
19235
  var init_strong = __esm(() => {
19047
- init_encode_info();
19048
- strong.peek = strongPeek;
19236
+ strong.attention = attention3;
19237
+ strong.peek = peek2;
19049
19238
  });
19050
19239
 
19051
19240
  // ../../node_modules/mdast-util-to-markdown/lib/handle/text.js
19052
- function text3(node, _, state, info) {
19053
- return state.safe(node.value, info);
19241
+ function text3(node, parent, state, info) {
19242
+ const siblings = parent ? parent.children : [];
19243
+ const index = siblings.indexOf(node);
19244
+ return state.safe(node.value, {
19245
+ ...info,
19246
+ afterNode: siblings[index + 1],
19247
+ beforeNode: siblings[index - 1]
19248
+ });
19054
19249
  }
19055
19250
 
19056
19251
  // ../../node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.js
@@ -19112,6 +19307,43 @@ var init_handle = __esm(() => {
19112
19307
  };
19113
19308
  });
19114
19309
 
19310
+ // ../../node_modules/mdast-util-to-markdown/lib/util/html-kind.js
19311
+ function htmlKind(value) {
19312
+ if (value.charCodeAt(0) !== 60)
19313
+ return;
19314
+ const next = value.charCodeAt(1);
19315
+ if (next === 33) {
19316
+ const code = value.charCodeAt(2);
19317
+ if (code === 45)
19318
+ return 2;
19319
+ if (code === 91)
19320
+ return 5;
19321
+ if (asciiAlpha(code))
19322
+ return 4;
19323
+ return;
19324
+ }
19325
+ if (next === 63)
19326
+ return 3;
19327
+ const closing = next === 47;
19328
+ const start = closing ? 2 : 1;
19329
+ let end = start;
19330
+ let code = value.charCodeAt(end);
19331
+ if (!asciiAlpha(code))
19332
+ return;
19333
+ while (code === 45 || asciiAlphanumeric(code)) {
19334
+ code = value.charCodeAt(++end);
19335
+ }
19336
+ const name = value.slice(start, end).toLowerCase();
19337
+ if (!closing && code !== 47 && htmlRawNames.includes(name)) {
19338
+ return 1;
19339
+ }
19340
+ return htmlBlockNames.includes(name) ? 6 : 7;
19341
+ }
19342
+ var init_html_kind = __esm(() => {
19343
+ init_dev4();
19344
+ init_micromark_util_html_tag_name();
19345
+ });
19346
+
19115
19347
  // ../../node_modules/mdast-util-to-markdown/lib/join.js
19116
19348
  function joinDefaults(left, right, parent, state) {
19117
19349
  if (right.type === "code" && formatCodeAsIndented(right, state) && (left.type === "list" || left.type === right.type && formatCodeAsIndented(left, state))) {
@@ -19121,17 +19353,28 @@ function joinDefaults(left, right, parent, state) {
19121
19353
  if (left.type === "paragraph" && (left.type === right.type || right.type === "definition" || right.type === "heading" && formatHeadingAsSetext(right, state))) {
19122
19354
  return;
19123
19355
  }
19356
+ if (left.type === "html") {
19357
+ const kind = htmlKind(left.value);
19358
+ if (kind === undefined || kind === 6 || kind === 7)
19359
+ return 1;
19360
+ }
19361
+ if (left.type === "paragraph" && right.type === "html") {
19362
+ const kind = htmlKind(right.value);
19363
+ if (kind === undefined || kind === 7)
19364
+ return 1;
19365
+ }
19124
19366
  return parent.spread ? 1 : 0;
19125
19367
  }
19126
19368
  }
19127
19369
  var join;
19128
19370
  var init_join = __esm(() => {
19129
19371
  init_format_heading_as_setext();
19372
+ init_html_kind();
19130
19373
  join = [joinDefaults];
19131
19374
  });
19132
19375
 
19133
19376
  // ../../node_modules/mdast-util-to-markdown/lib/unsafe.js
19134
- var fullPhrasingSpans, unsafe;
19377
+ var fullPhrasingSpans, unsafe, code2 = -1;
19135
19378
  var init_unsafe = __esm(() => {
19136
19379
  fullPhrasingSpans = [
19137
19380
  "autolink",
@@ -19171,6 +19414,12 @@ var init_unsafe = __esm(() => {
19171
19414
  "headingAtx"
19172
19415
  ]
19173
19416
  },
19417
+ { character: "\r", before: "[\\r\\n]", inConstruct: "phrasing" },
19418
+ { character: "\r", after: "\\r", inConstruct: "phrasing" },
19419
+ { character: `
19420
+ `, before: "\\n", inConstruct: "phrasing" },
19421
+ { character: `
19422
+ `, after: "[\\r\\n]", inConstruct: "phrasing" },
19174
19423
  { character: " ", after: "[\\r\\n]", inConstruct: "phrasing" },
19175
19424
  { character: " ", before: "[\\r\\n]", inConstruct: "phrasing" },
19176
19425
  {
@@ -19231,8 +19480,14 @@ var init_unsafe = __esm(() => {
19231
19480
  inConstruct: ["codeFencedLangGraveAccent", "codeFencedMetaGraveAccent"]
19232
19481
  },
19233
19482
  { character: "`", inConstruct: "phrasing", notInConstruct: fullPhrasingSpans },
19234
- { atBreak: true, character: "~" }
19483
+ { atBreak: true, character: "~" },
19484
+ { character: "<", inConstruct: "autolink" },
19485
+ { character: ">", inConstruct: "autolink" },
19486
+ { character: "", inConstruct: "autolink" }
19235
19487
  ];
19488
+ while (++code2 < 33) {
19489
+ unsafe.push({ character: String.fromCharCode(code2), inConstruct: "autolink" });
19490
+ }
19236
19491
  });
19237
19492
 
19238
19493
  // ../../node_modules/mdast-util-to-markdown/lib/util/association.js
@@ -19250,19 +19505,201 @@ var init_association = __esm(() => {
19250
19505
  function compilePattern(pattern) {
19251
19506
  if (!pattern._compiled) {
19252
19507
  const before = (pattern.atBreak ? "[\\r\\n][\\t ]*" : "") + (pattern.before ? "(?:" + pattern.before + ")" : "");
19253
- pattern._compiled = new RegExp((before ? "(" + before + ")" : "") + (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? "\\" : "") + pattern.character + (pattern.after ? "(?:" + pattern.after + ")" : ""), "g");
19508
+ pattern._compiled = new RegExp((pattern.beforeNode ? "^" : before ? "(" + before + ")" : "") + (/[$()*+.?[\\\]^{|}]/.test(pattern.character) ? "\\" : "") + pattern.character + (pattern.afterNode ? "$" : pattern.after ? "(?:" + pattern.after + ")" : ""), pattern.unicode ? "gu" : "g");
19254
19509
  }
19255
19510
  return pattern._compiled;
19256
19511
  }
19257
19512
 
19513
+ // ../../node_modules/mdast-util-to-markdown/lib/util/character.js
19514
+ function firstCharacter(value) {
19515
+ const code = value.codePointAt(0);
19516
+ return code === undefined ? "" : String.fromCodePoint(code);
19517
+ }
19518
+ function lastCharacter(value) {
19519
+ const code = value.codePointAt(value.length - 2);
19520
+ return code !== undefined && code > 65535 ? value.slice(-2) : value.slice(-1);
19521
+ }
19522
+
19523
+ // ../../node_modules/mdast-util-to-markdown/lib/util/encode-info.js
19524
+ function encodeInfo(outside, inside, marker) {
19525
+ const outsideKind = classifyCharacter(outside);
19526
+ const insideKind = classifyCharacter(inside);
19527
+ if (outsideKind === undefined) {
19528
+ return insideKind === undefined ? marker === "_" ? { inside: true, outside: true } : { inside: false, outside: false } : insideKind === 1 ? { inside: true, outside: true } : { inside: false, outside: true };
19529
+ }
19530
+ if (outsideKind === 1) {
19531
+ return insideKind === undefined ? { inside: false, outside: false } : insideKind === 1 ? { inside: true, outside: true } : { inside: false, outside: false };
19532
+ }
19533
+ return insideKind === undefined ? { inside: false, outside: false } : insideKind === 1 ? { inside: true, outside: false } : { inside: false, outside: false };
19534
+ }
19535
+ var init_encode_info = __esm(() => {
19536
+ init_dev6();
19537
+ });
19538
+
19258
19539
  // ../../node_modules/mdast-util-to-markdown/lib/util/container-phrasing.js
19540
+ function candidates(tokens, involved, runOf) {
19541
+ const related = new Set;
19542
+ for (const token of tokens) {
19543
+ const siblings = runOf.get(token);
19544
+ if (siblings && token.attention && involved.some((d) => d.attention === token.attention)) {
19545
+ for (const sibling of siblings.tokens) {
19546
+ related.add(sibling.attention);
19547
+ }
19548
+ }
19549
+ }
19550
+ const ordered = [];
19551
+ for (const token of tokens) {
19552
+ if (token.attention && related.delete(token.attention)) {
19553
+ ordered.push(token.attention);
19554
+ }
19555
+ }
19556
+ ordered.reverse();
19557
+ return ordered;
19558
+ }
19559
+ function check(tokens, before, after) {
19560
+ const runs = [];
19561
+ const wrong = new Map;
19562
+ const runOf = new Map;
19563
+ let index = 0;
19564
+ while (index < tokens.length) {
19565
+ if (!tokens[index].attention) {
19566
+ index++;
19567
+ continue;
19568
+ }
19569
+ const marker = tokens[index].value.charAt(0);
19570
+ const strict = builtins.get(marker);
19571
+ let end = index + 1;
19572
+ while (end < tokens.length && tokens[end].attention && tokens[end].value.charAt(0) === marker) {
19573
+ end++;
19574
+ }
19575
+ const head = index ? tokens[index - 1].value : before;
19576
+ const previous = classifyCharacter(head.charCodeAt(head.length - 1));
19577
+ const next = classifyCharacter((end < tokens.length ? tokens[end].value : after).charCodeAt(0));
19578
+ const open = !next || next === 2 && Boolean(previous);
19579
+ const close = !previous || previous === 2 && Boolean(next);
19580
+ const run = {
19581
+ tokens: tokens.slice(index, end),
19582
+ markers: [],
19583
+ start: 0,
19584
+ end: 0,
19585
+ open: strict ? open && (Boolean(previous) || !close) : open,
19586
+ close: strict ? close && (Boolean(next) || !open) : close,
19587
+ split: strict !== undefined
19588
+ };
19589
+ for (const token of run.tokens) {
19590
+ wrong.set(token, [...run.tokens]);
19591
+ runOf.set(token, run);
19592
+ let size = token.value.length;
19593
+ while (size--)
19594
+ run.markers.push(token);
19595
+ }
19596
+ run.end = run.markers.length;
19597
+ runs.push(run);
19598
+ index = end;
19599
+ }
19600
+ pair(runs, wrong);
19601
+ index = -1;
19602
+ while (++index < tokens.length) {
19603
+ const involved = wrong.get(tokens[index]);
19604
+ if (involved)
19605
+ return { attention: candidates(tokens, involved, runOf), index };
19606
+ }
19607
+ }
19259
19608
  function containerPhrasing(parent, state, info) {
19609
+ return serialize2(phrasing2(parent, state, info), info.before, info.after);
19610
+ }
19611
+ function encode(tokens, start) {
19612
+ const token = tokens[start ? 0 : tokens.length - 1];
19613
+ if (!token || token.attention)
19614
+ return;
19615
+ const character = start ? firstCharacter(token.value) : lastCharacter(token.value);
19616
+ const reference = encodeCharacterReference(character.codePointAt(0));
19617
+ token.value = start ? reference + token.value.slice(character.length) : token.value.slice(0, token.value.length - character.length) + reference;
19618
+ }
19619
+ function improve(items, chosen, mistake, before, after) {
19620
+ for (const attention of mistake.attention) {
19621
+ const current = chosen.get(attention) || attention.sequences[0];
19622
+ for (const sequence of attention.sequences) {
19623
+ if (sequence === current)
19624
+ continue;
19625
+ const trial = new Map(chosen);
19626
+ trial.set(attention, sequence);
19627
+ const tokens = render(items, trial, before, after);
19628
+ const next = check(tokens, before, after);
19629
+ if (!next || next.index > mistake.index) {
19630
+ return { chosen: trial, mistake: next, tokens };
19631
+ }
19632
+ }
19633
+ }
19634
+ }
19635
+ function pair(runs, wrong) {
19636
+ let index = 0;
19637
+ while (index < runs.length) {
19638
+ const closer = runs[index];
19639
+ const marker = closer.tokens[0].value.charAt(0);
19640
+ const closerSize = closer.end - closer.start;
19641
+ let open = closer.close && closerSize ? index : 0;
19642
+ while (open--) {
19643
+ const opener = runs[open];
19644
+ const openerSize = opener.end - opener.start;
19645
+ if (opener.tokens[0].value.charAt(0) === marker && opener.open && openerSize && (closer.split ? !((opener.close || closer.open) && closerSize % 3) || (openerSize + closerSize) % 3 : openerSize === opener.markers.length && openerSize === closerSize)) {
19646
+ const size = closer.split ? openerSize > 1 && closerSize > 1 ? 2 : 1 : closerSize;
19647
+ const opening = opener.markers.slice(opener.end - size, opener.end);
19648
+ const closing = closer.markers.slice(closer.start, closer.start + size);
19649
+ const openToken = opening[0];
19650
+ const closeToken = closing[0];
19651
+ if (openToken === opening[size - 1] && openToken.value.length === size && closeToken === closing[size - 1] && closeToken.value.length === size && openToken.attention === closeToken.attention) {
19652
+ wrong.delete(openToken);
19653
+ wrong.delete(closeToken);
19654
+ } else {
19655
+ const involved = [...new Set([...opening, ...closing])];
19656
+ for (const token of involved) {
19657
+ const list = wrong.get(token);
19658
+ if (list)
19659
+ list.push(...involved);
19660
+ }
19661
+ }
19662
+ opener.end -= size;
19663
+ closer.start += size;
19664
+ break;
19665
+ }
19666
+ }
19667
+ if (open === -1 || closer.start === closer.end)
19668
+ index++;
19669
+ }
19670
+ }
19671
+ function attentionSequences(type, markers, sizes) {
19672
+ if (markers.length === 0) {
19673
+ throw new Error("Cannot serialize `" + type + "` as attention without markers, expected one or more markers");
19674
+ }
19675
+ if (sizes.length === 0) {
19676
+ throw new Error("Cannot serialize `" + type + "` as attention without sizes, expected one or more sizes");
19677
+ }
19678
+ for (const size of sizes) {
19679
+ if (!Number.isSafeInteger(size) || size < 1) {
19680
+ throw new Error("Cannot serialize `" + type + "` as attention with `" + size + "` as size, expected positive integer");
19681
+ }
19682
+ }
19683
+ const sequences = [];
19684
+ for (const marker of markers) {
19685
+ if (marker.length !== 1) {
19686
+ throw new Error("Cannot serialize `" + type + "` as attention with `" + marker + "` as marker, expected a single ascii character");
19687
+ }
19688
+ if (!asciiPunctuation(marker.charCodeAt(0))) {
19689
+ throw new Error("Cannot serialize `" + type + "` as attention with `" + marker + "` as marker, expected ascii punctuation");
19690
+ }
19691
+ for (const size of sizes) {
19692
+ sequences.push(marker.repeat(size));
19693
+ }
19694
+ }
19695
+ return sequences;
19696
+ }
19697
+ function phrasing2(parent, state, info) {
19260
19698
  const indexStack = state.indexStack;
19261
19699
  const children = parent.children || [];
19262
19700
  const results = [];
19263
19701
  let index = -1;
19264
19702
  let before = info.before;
19265
- let encodeAfter;
19266
19703
  indexStack.push(-1);
19267
19704
  let tracker = state.createTracker(info);
19268
19705
  while (++index < children.length) {
@@ -19273,47 +19710,132 @@ function containerPhrasing(parent, state, info) {
19273
19710
  let handle = state.handle.handlers[children[index + 1].type];
19274
19711
  if (handle && handle.peek)
19275
19712
  handle = handle.peek;
19276
- after = handle ? handle(children[index + 1], parent, state, {
19713
+ after = handle ? firstCharacter(handle(children[index + 1], parent, state, {
19277
19714
  before: "",
19278
19715
  after: "",
19279
19716
  ...tracker.current()
19280
- }).charAt(0) : "";
19717
+ })) : "";
19281
19718
  } else {
19282
19719
  after = info.after;
19283
19720
  }
19284
- if (results.length > 0 && (before === "\r" || before === `
19285
- `) && child.type === "html") {
19286
- results[results.length - 1] = results[results.length - 1].replace(/(\r?\n|\r)$/, " ");
19721
+ const previous = results[results.length - 1];
19722
+ if (typeof previous === "string" && (before === "\r" || before === `
19723
+ `) && child.type === "html" && htmlKind(child.value) !== 7) {
19724
+ results[results.length - 1] = previous.replace(/(\r?\n|\r)$/, " ");
19287
19725
  before = " ";
19288
19726
  tracker = state.createTracker(info);
19289
- tracker.move(results.join(""));
19727
+ tracker.move(serialize2(results, info.before, info.after));
19728
+ }
19729
+ const handle = state.handle.handlers[child.type];
19730
+ if (handle && handle.attention) {
19731
+ const { construct, markers, sizes } = handle.attention(child, state);
19732
+ const sequences = attentionSequences(child.type, markers, sizes);
19733
+ const sequence = sequences[0];
19734
+ const exit = state.enter(construct);
19735
+ tracker.move(sequence);
19736
+ const inside = phrasing2(child, state, {
19737
+ ...tracker.current(),
19738
+ before: sequence,
19739
+ after: sequence
19740
+ });
19741
+ tracker.move(serialize2(inside, sequence, sequence));
19742
+ tracker.move(sequence);
19743
+ exit();
19744
+ results.push({ children: inside, sequences });
19745
+ before = sequence.charAt(sequence.length - 1);
19746
+ } else {
19747
+ const value = state.handle(child, parent, state, {
19748
+ ...tracker.current(),
19749
+ after,
19750
+ before
19751
+ });
19752
+ if (!value)
19753
+ continue;
19754
+ tracker.move(value);
19755
+ results.push(value);
19756
+ before = lastCharacter(value);
19290
19757
  }
19291
- let value = state.handle(child, parent, state, {
19292
- ...tracker.current(),
19293
- after,
19294
- before
19295
- });
19296
- if (encodeAfter && encodeAfter === value.slice(0, 1)) {
19297
- value = encodeCharacterReference(encodeAfter.charCodeAt(0)) + value.slice(1);
19758
+ }
19759
+ indexStack.pop();
19760
+ return results;
19761
+ }
19762
+ function render(items, chosen, before, after) {
19763
+ const tokens = [];
19764
+ let encodeAfter;
19765
+ let previous = lastCharacter(before);
19766
+ let index = -1;
19767
+ while (++index < items.length) {
19768
+ const item = items[index];
19769
+ if (typeof item === "string") {
19770
+ const token = { value: item, attention: undefined };
19771
+ if (encodeAfter && encodeAfter === firstCharacter(item)) {
19772
+ encode([token], true);
19773
+ }
19774
+ encodeAfter = undefined;
19775
+ tokens.push(token);
19776
+ if (token.value)
19777
+ previous = lastCharacter(token.value);
19778
+ continue;
19298
19779
  }
19299
- const encodingInfo = state.attentionEncodeSurroundingInfo;
19300
- state.attentionEncodeSurroundingInfo = undefined;
19301
- encodeAfter = undefined;
19302
- if (encodingInfo) {
19303
- if (results.length > 0 && encodingInfo.before && before === results[results.length - 1].slice(-1)) {
19304
- results[results.length - 1] = results[results.length - 1].slice(0, -1) + encodeCharacterReference(before.charCodeAt(0));
19305
- }
19306
- if (encodingInfo.after)
19307
- encodeAfter = after;
19780
+ const sequence = chosen.get(item) || item.sequences[0];
19781
+ const marker = sequence.charAt(0);
19782
+ const next = items[index + 1];
19783
+ const outsideBefore = previous;
19784
+ const outsideAfter = firstCharacter(next === undefined ? after : typeof next === "string" ? next : chosen.get(next) || next.sequences[0]);
19785
+ const inside = render(item.children, chosen, sequence, sequence);
19786
+ const head = inside.length > 0 ? inside[0].value : "";
19787
+ const open = encodeInfo(outsideBefore.charCodeAt(outsideBefore.length - 1), head.charCodeAt(0), marker);
19788
+ if (open.inside)
19789
+ encode(inside, true);
19790
+ const tail = inside.length > 0 ? lastCharacter(inside[inside.length - 1].value) : "";
19791
+ const close = encodeInfo(outsideAfter.charCodeAt(0), tail.charCodeAt(tail.length - 1), marker);
19792
+ if (close.inside)
19793
+ encode(inside, false);
19794
+ if (open.outside && outsideBefore !== `
19795
+ ` && outsideBefore !== "\r") {
19796
+ encode(tokens, false);
19797
+ }
19798
+ if (close.outside)
19799
+ encodeAfter = outsideAfter;
19800
+ tokens.push({ value: sequence, attention: item }, ...inside, {
19801
+ value: sequence,
19802
+ attention: item
19803
+ });
19804
+ previous = sequence.charAt(sequence.length - 1);
19805
+ }
19806
+ return tokens;
19807
+ }
19808
+ function serialize2(items, before, after) {
19809
+ let chosen = new Map;
19810
+ const initial = render(items, chosen, before, after);
19811
+ let tokens = initial;
19812
+ let mistake = check(tokens, before, after);
19813
+ while (mistake) {
19814
+ const next = improve(items, chosen, mistake, before, after);
19815
+ if (!next) {
19816
+ tokens = initial;
19817
+ break;
19308
19818
  }
19309
- tracker.move(value);
19310
- results.push(value);
19311
- before = value.slice(-1);
19819
+ chosen = next.chosen;
19820
+ tokens = next.tokens;
19821
+ mistake = next.mistake;
19312
19822
  }
19313
- indexStack.pop();
19314
- return results.join("");
19823
+ let result = "";
19824
+ for (const token of tokens)
19825
+ result += token.value;
19826
+ return result;
19315
19827
  }
19316
- var init_container_phrasing = () => {};
19828
+ var builtins;
19829
+ var init_container_phrasing = __esm(() => {
19830
+ init_dev4();
19831
+ init_dev6();
19832
+ init_encode_info();
19833
+ init_html_kind();
19834
+ builtins = new Map([
19835
+ ["*", false],
19836
+ ["_", true]
19837
+ ]);
19838
+ });
19317
19839
 
19318
19840
  // ../../node_modules/mdast-util-to-markdown/lib/util/container-flow.js
19319
19841
  function containerFlow(parent, state, info) {
@@ -19396,19 +19918,24 @@ function safe(state, input, config) {
19396
19918
  const positions = [];
19397
19919
  const result = [];
19398
19920
  const infos = {};
19921
+ const percentEncode = state.stack.includes("autolink");
19922
+ const offset = config.before ? config.before.length : 0;
19923
+ const end = value.length - (config.after ? config.after.length : 0);
19399
19924
  let index = -1;
19400
19925
  while (++index < state.unsafe.length) {
19401
19926
  const pattern = state.unsafe[index];
19402
- if (!patternInScope(state.stack, pattern)) {
19927
+ if (!patternInScope(state.stack, pattern) || !nodeInScope(pattern.beforeNode, config.beforeNode) || !nodeInScope(pattern.afterNode, config.afterNode)) {
19403
19928
  continue;
19404
19929
  }
19405
19930
  const expression = state.compilePattern(pattern);
19931
+ const from = pattern.beforeNode ? offset : 0;
19932
+ const subject = value.slice(from, pattern.afterNode ? end : undefined);
19406
19933
  let match;
19407
- while (match = expression.exec(value)) {
19934
+ while (match = expression.exec(subject)) {
19408
19935
  const before = "before" in pattern || Boolean(pattern.atBreak);
19409
19936
  const after = "after" in pattern;
19410
- const position = match.index + (before ? match[1].length : 0);
19411
- if (positions.includes(position)) {
19937
+ const position = from + match.index + (before ? match[1].length : 0);
19938
+ if (own7.call(infos, position)) {
19412
19939
  if (infos[position].before && !before) {
19413
19940
  infos[position].before = false;
19414
19941
  }
@@ -19422,31 +19949,53 @@ function safe(state, input, config) {
19422
19949
  }
19423
19950
  }
19424
19951
  positions.sort(numerical);
19425
- let start = config.before ? config.before.length : 0;
19426
- const end = value.length - (config.after ? config.after.length : 0);
19952
+ let start = offset;
19427
19953
  index = -1;
19428
19954
  while (++index < positions.length) {
19429
19955
  const position = positions[index];
19430
19956
  if (position < start || position >= end) {
19431
19957
  continue;
19432
19958
  }
19959
+ if (value.charAt(position) === "_" && position > 0 && classifyCharacter(value.charCodeAt(position - 1)) === undefined && !own7.call(infos, position - 1) && !(position - 1 === offset && /[*_]/.test(value.charAt(offset - 1)))) {
19960
+ let sequenceEnd = position + 1;
19961
+ while (sequenceEnd < end && value.charAt(sequenceEnd) === "_") {
19962
+ sequenceEnd++;
19963
+ }
19964
+ const skip = sequenceEnd - position - 1;
19965
+ if (positions[index + skip] === sequenceEnd - 1 && sequenceEnd < value.length && classifyCharacter(value.charCodeAt(sequenceEnd)) === undefined && !own7.call(infos, sequenceEnd) && !(sequenceEnd === end - 1 && /[*_]/.test(value.charAt(end)))) {
19966
+ index += skip;
19967
+ continue;
19968
+ }
19969
+ }
19433
19970
  if (position + 1 < end && positions[index + 1] === position + 1 && infos[position].after && !infos[position + 1].before && !infos[position + 1].after || positions[index - 1] === position - 1 && infos[position].before && !infos[position - 1].before && !infos[position - 1].after) {
19434
19971
  continue;
19435
19972
  }
19436
19973
  if (start !== position) {
19437
- result.push(escapeBackslashes(value.slice(start, position), "\\"));
19974
+ const slice = value.slice(start, position);
19975
+ result.push(percentEncode ? slice : escapeBackslashes(slice, "\\"));
19438
19976
  }
19439
19977
  start = position;
19440
- if (/[!-/:-@[-`{-~]/.test(value.charAt(position)) && (!config.encode || !config.encode.includes(value.charAt(position)))) {
19978
+ if (percentEncode) {
19979
+ result.push("%" + value.charCodeAt(position).toString(16).toUpperCase().padStart(2, "0"));
19980
+ start++;
19981
+ } else if (/[!-/:-@[-`{-~]/.test(value.charAt(position)) && (!config.encode || !config.encode.includes(value.charAt(position)))) {
19441
19982
  result.push("\\");
19442
19983
  } else {
19443
19984
  result.push(encodeCharacterReference(value.charCodeAt(position)));
19444
19985
  start++;
19445
19986
  }
19446
19987
  }
19447
- result.push(escapeBackslashes(value.slice(start, end), config.after));
19988
+ const rest = value.slice(start, end);
19989
+ result.push(percentEncode ? rest : escapeBackslashes(rest, config.after));
19448
19990
  return result.join("");
19449
19991
  }
19992
+ function nodeInScope(types, node) {
19993
+ if (!types)
19994
+ return true;
19995
+ if (!node)
19996
+ return false;
19997
+ return typeof types === "string" ? types === node.type : types.includes(node.type);
19998
+ }
19450
19999
  function numerical(a, b) {
19451
20000
  return a - b;
19452
20001
  }
@@ -19471,7 +20020,11 @@ function escapeBackslashes(value, after) {
19471
20020
  results.push(value.slice(start));
19472
20021
  return results.join("");
19473
20022
  }
19474
- var init_safe = () => {};
20023
+ var own7;
20024
+ var init_safe = __esm(() => {
20025
+ init_dev6();
20026
+ own7 = {}.hasOwnProperty;
20027
+ });
19475
20028
 
19476
20029
  // ../../node_modules/mdast-util-to-markdown/lib/util/track.js
19477
20030
  function track(config) {
@@ -19502,6 +20055,8 @@ function toMarkdown(tree, options) {
19502
20055
  const settings = options || {};
19503
20056
  const state = {
19504
20057
  associationId: association,
20058
+ bulletCurrent: undefined,
20059
+ bulletLastUsed: undefined,
19505
20060
  containerPhrasing: containerPhrasingBound,
19506
20061
  containerFlow: containerFlowBound,
19507
20062
  createTracker: track,
@@ -19526,14 +20081,9 @@ function toMarkdown(tree, options) {
19526
20081
  unknown,
19527
20082
  handlers: state.handlers
19528
20083
  });
19529
- let result = state.handle(tree, undefined, state, {
19530
- before: `
19531
- `,
19532
- after: `
19533
- `,
19534
- now: { line: 1, column: 1 },
19535
- lineShift: 0
19536
- });
20084
+ let result = state.handle(phrasing(tree) ? { type: "root", children: [tree] } : tree, undefined, state, { before: `
20085
+ `, after: `
20086
+ `, now: { line: 1, column: 1 }, lineShift: 0 });
19537
20087
  if (result && result.charCodeAt(result.length - 1) !== 10 && result.charCodeAt(result.length - 1) !== 13) {
19538
20088
  result += `
19539
20089
  `;
@@ -19569,6 +20119,7 @@ function safeBound(value, config) {
19569
20119
  return safe(this, value, config);
19570
20120
  }
19571
20121
  var init_lib17 = __esm(() => {
20122
+ init_mdast_util_phrasing();
19572
20123
  init_zwitch();
19573
20124
  init_configure();
19574
20125
  init_handle();
@@ -20134,7 +20685,7 @@ function previousUnbalanced(events) {
20134
20685
  }
20135
20686
  return result;
20136
20687
  }
20137
- var wwwPrefix, domain, path, trail, emailDomainDotTrail, wwwAutolink, protocolAutolink, emailAutolink, text4, code2;
20688
+ var wwwPrefix, domain, path, trail, emailDomainDotTrail, wwwAutolink, protocolAutolink, emailAutolink, text4, code3;
20138
20689
  var init_syntax2 = __esm(() => {
20139
20690
  init_dev4();
20140
20691
  init_default();
@@ -20162,14 +20713,14 @@ var init_syntax2 = __esm(() => {
20162
20713
  previous: previousEmail
20163
20714
  };
20164
20715
  text4 = {};
20165
- code2 = codes.digit0;
20166
- while (code2 < codes.leftCurlyBrace) {
20167
- text4[code2] = emailAutolink;
20168
- code2++;
20169
- if (code2 === codes.colon)
20170
- code2 = codes.uppercaseA;
20171
- else if (code2 === codes.leftSquareBracket)
20172
- code2 = codes.lowercaseA;
20716
+ code3 = codes.digit0;
20717
+ while (code3 < codes.leftCurlyBrace) {
20718
+ text4[code3] = emailAutolink;
20719
+ code3++;
20720
+ if (code3 === codes.colon)
20721
+ code3 = codes.uppercaseA;
20722
+ else if (code3 === codes.leftSquareBracket)
20723
+ code3 = codes.lowercaseA;
20173
20724
  }
20174
20725
  text4[codes.plusSign] = emailAutolink;
20175
20726
  text4[codes.dash] = emailAutolink;
@@ -20567,12 +21118,13 @@ var init_dev19 = __esm(() => {
20567
21118
  });
20568
21119
 
20569
21120
  // ../../node_modules/micromark-extension-gfm-table/dev/lib/edit-map.js
20570
- class EditMap {
21121
+ class EditMap2 {
20571
21122
  constructor() {
20572
21123
  this.map = [];
21124
+ this.index = new Map;
20573
21125
  }
20574
21126
  add(index, remove, add) {
20575
- addImplementation(this, index, remove, add);
21127
+ addImplementation2(this, index, remove, add);
20576
21128
  }
20577
21129
  consume(events) {
20578
21130
  this.map.sort(function(a, b) {
@@ -20598,22 +21150,22 @@ class EditMap {
20598
21150
  slice = vecs.pop();
20599
21151
  }
20600
21152
  this.map.length = 0;
21153
+ this.index.clear();
20601
21154
  }
20602
21155
  }
20603
- function addImplementation(editMap, at, remove, add) {
20604
- let index = 0;
21156
+ function addImplementation2(editMap, at, remove, add) {
20605
21157
  if (remove === 0 && add.length === 0) {
20606
21158
  return;
20607
21159
  }
20608
- while (index < editMap.map.length) {
20609
- if (editMap.map[index][0] === at) {
20610
- editMap.map[index][1] += remove;
20611
- editMap.map[index][2].push(...add);
20612
- return;
20613
- }
20614
- index += 1;
21160
+ const existing = editMap.index.get(at);
21161
+ if (existing) {
21162
+ existing[1] += remove;
21163
+ existing[2].push(...add);
21164
+ return;
20615
21165
  }
20616
- editMap.map.push([at, remove, add]);
21166
+ const change = [at, remove, add];
21167
+ editMap.map.push(change);
21168
+ editMap.index.set(at, change);
20617
21169
  }
20618
21170
 
20619
21171
  // ../../node_modules/micromark-extension-gfm-table/dev/lib/infer.js
@@ -20664,11 +21216,12 @@ function tokenizeTable(effects, ok2, nok) {
20664
21216
  function start(code) {
20665
21217
  let index = self2.events.length - 1;
20666
21218
  while (index > -1) {
20667
- const type = self2.events[index][1].type;
20668
- if (type === types.lineEnding || type === types.linePrefix)
21219
+ const { type } = self2.events[index][1];
21220
+ if (type === types.lineEnding || type === types.linePrefix) {
20669
21221
  index--;
20670
- else
21222
+ } else {
20671
21223
  break;
21224
+ }
20672
21225
  }
20673
21226
  const tail = index > -1 ? self2.events[index][1].type : null;
20674
21227
  const next = tail === "tableHead" || tail === "tableRow" ? bodyRowStart : headRowBefore;
@@ -20883,7 +21436,7 @@ function resolveTable(events, context) {
20883
21436
  let currentTable;
20884
21437
  let currentBody;
20885
21438
  let currentCell;
20886
- const map = new EditMap;
21439
+ const map = new EditMap2;
20887
21440
  while (++index < events.length) {
20888
21441
  const event = events[index];
20889
21442
  const token = event[1];
@@ -21894,7 +22447,7 @@ var init_dangerous = __esm(() => {
21894
22447
  // ../../node_modules/stringify-entities/lib/util/to-named.js
21895
22448
  function toNamed(code, next, omit, attribute) {
21896
22449
  const character = String.fromCharCode(code);
21897
- if (own7.call(characters, character)) {
22450
+ if (own8.call(characters, character)) {
21898
22451
  const name = characters[character];
21899
22452
  const value = "&" + name;
21900
22453
  if (omit && characterEntitiesLegacy.includes(name) && !dangerous.includes(name) && (!attribute || next && next !== 61 && notAlphanumericRegex.test(String.fromCharCode(next)))) {
@@ -21904,15 +22457,15 @@ function toNamed(code, next, omit, attribute) {
21904
22457
  }
21905
22458
  return "";
21906
22459
  }
21907
- var own7, characters, key, notAlphanumericRegex;
22460
+ var own8, characters, key, notAlphanumericRegex;
21908
22461
  var init_to_named = __esm(() => {
21909
22462
  init_character_entities_legacy();
21910
22463
  init_character_entities_html4();
21911
22464
  init_dangerous();
21912
- own7 = {}.hasOwnProperty;
22465
+ own8 = {}.hasOwnProperty;
21913
22466
  characters = {};
21914
22467
  for (key in characterEntitiesHtml4) {
21915
- if (own7.call(characterEntitiesHtml4, key)) {
22468
+ if (own8.call(characterEntitiesHtml4, key)) {
21916
22469
  characters[characterEntitiesHtml4[key]] = key;
21917
22470
  }
21918
22471
  }
@@ -22100,12 +22653,14 @@ function directiveToMarkdown(options) {
22100
22653
  inConstruct: ["leafDirectiveLabel", "containerDirectiveLabel"]
22101
22654
  },
22102
22655
  {
22656
+ after: "[^\\s\\p{P}\\p{S}]",
22103
22657
  before: "[^:]",
22104
22658
  character: ":",
22105
- after: "[A-Za-z]",
22106
- inConstruct: ["phrasing"]
22659
+ inConstruct: ["phrasing"],
22660
+ unicode: true
22107
22661
  },
22108
- { atBreak: true, character: ":", after: ":" }
22662
+ { afterNode: "textDirective", character: ":", inConstruct: ["phrasing"] },
22663
+ { atBreak: true, before: ":+", character: ":" }
22109
22664
  ]
22110
22665
  };
22111
22666
  function handleDirective(node, _, state, info) {
@@ -22113,6 +22668,8 @@ function directiveToMarkdown(options) {
22113
22668
  const sequence = fence3(node);
22114
22669
  const exit = state.enter(node.type);
22115
22670
  let value = tracker.move(sequence + (node.name || ""));
22671
+ const attributesValue = attributes(node, state);
22672
+ const after = info.after.charCodeAt(0);
22116
22673
  let label;
22117
22674
  if (node.type === "containerDirective") {
22118
22675
  const head = (node.children || [])[0];
@@ -22133,8 +22690,10 @@ function directiveToMarkdown(options) {
22133
22690
  value += tracker.move("]");
22134
22691
  subexit();
22135
22692
  exit();
22693
+ } else if (!attributesValue && (after === 45 || after === 95 || !(unicodePunctuation(after) || unicodeWhitespace(after)))) {
22694
+ value += tracker.move("[]");
22136
22695
  }
22137
- value += tracker.move(attributes(node, state));
22696
+ value += tracker.move(attributesValue || (after === 123 ? "{}" : ""));
22138
22697
  if (node.type === "containerDirective") {
22139
22698
  const head = (node.children || [])[0];
22140
22699
  let shallow = node;
@@ -22160,12 +22719,12 @@ function directiveToMarkdown(options) {
22160
22719
  let id;
22161
22720
  let key;
22162
22721
  for (key in attributes) {
22163
- if (own8.call(attributes, key) && attributes[key] !== undefined && attributes[key] !== null) {
22722
+ if (own9.call(attributes, key) && attributes[key] !== undefined && attributes[key] !== null) {
22164
22723
  const value = String(attributes[key]);
22165
22724
  if (key === "id") {
22166
22725
  id = settings.preferShortcut !== false && shortcut.test(value) ? "#" + value : quoted("id", value, node, state);
22167
22726
  } else if (key === "class") {
22168
- const list = value.split(/[\t\n\r ]+/g);
22727
+ const list = value.split(/[\t\n\r ]+/);
22169
22728
  const classesFullList = [];
22170
22729
  const classesList = [];
22171
22730
  let index = -1;
@@ -22311,13 +22870,14 @@ function fence3(node) {
22311
22870
  }
22312
22871
  return ":".repeat(size);
22313
22872
  }
22314
- var own8, emptyOptions4, shortcut, unquoted;
22873
+ var own9, emptyOptions4, shortcut, unquoted;
22315
22874
  var init_lib25 = __esm(() => {
22316
22875
  init_development();
22876
+ init_dev4();
22317
22877
  init_parse_entities();
22318
22878
  init_stringify_entities();
22319
22879
  init_unist_util_visit_parents3();
22320
- own8 = {}.hasOwnProperty;
22880
+ own9 = {}.hasOwnProperty;
22321
22881
  emptyOptions4 = {};
22322
22882
  shortcut = /^[^\t\n\r "#'.<=>`}]+$/;
22323
22883
  unquoted = /^[^\t\n\r "'<=>`}]+$/;
@@ -24575,7 +25135,7 @@ function element(state, node) {
24575
25135
  while (++index < node.attrs.length) {
24576
25136
  const attribute = node.attrs[index];
24577
25137
  const name = (attribute.prefix ? attribute.prefix + ":" : "") + attribute.name;
24578
- if (!own9.call(proto, name)) {
25138
+ if (!own10.call(proto, name)) {
24579
25139
  properties[name] = attribute.value;
24580
25140
  }
24581
25141
  }
@@ -24617,7 +25177,7 @@ function createLocation(state, node, location) {
24617
25177
  let key;
24618
25178
  if (location.attrs) {
24619
25179
  for (key in location.attrs) {
24620
- if (own9.call(location.attrs, key)) {
25180
+ if (own10.call(location.attrs, key)) {
24621
25181
  properties[find(state.schema, key).property] = position2(location.attrs[key]);
24622
25182
  }
24623
25183
  }
@@ -24650,14 +25210,14 @@ function position2(loc) {
24650
25210
  function point3(point) {
24651
25211
  return point.line && point.column ? point : undefined;
24652
25212
  }
24653
- var own9, proto;
25213
+ var own10, proto;
24654
25214
  var init_lib29 = __esm(() => {
24655
25215
  init_development();
24656
25216
  init_hastscript();
24657
25217
  init_property_information();
24658
25218
  init_vfile_location();
24659
25219
  init_web_namespaces();
24660
- own9 = {}.hasOwnProperty;
25220
+ own10 = {}.hasOwnProperty;
24661
25221
  proto = Object.prototype;
24662
25222
  });
24663
25223
 
@@ -25081,14 +25641,14 @@ var init_decode_codepoint = __esm(() => {
25081
25641
  });
25082
25642
 
25083
25643
  // ../../node_modules/parse5/node_modules/entities/dist/esm/decode.js
25084
- function isNumber(code) {
25644
+ function isNumber2(code) {
25085
25645
  return code >= CharCodes.ZERO && code <= CharCodes.NINE;
25086
25646
  }
25087
25647
  function isHexadecimalCharacter(code) {
25088
25648
  return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F;
25089
25649
  }
25090
25650
  function isAsciiAlphaNumeric(code) {
25091
- return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber(code);
25651
+ return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber2(code);
25092
25652
  }
25093
25653
  function isEntityInAttributeInvalidEnd(code) {
25094
25654
  return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code);
@@ -25162,7 +25722,7 @@ class EntityDecoder {
25162
25722
  const startIndex = offset;
25163
25723
  while (offset < input.length) {
25164
25724
  const char = input.charCodeAt(offset);
25165
- if (isNumber(char) || isHexadecimalCharacter(char)) {
25725
+ if (isNumber2(char) || isHexadecimalCharacter(char)) {
25166
25726
  offset += 1;
25167
25727
  } else {
25168
25728
  this.addToNumericResult(input, startIndex, offset, 16);
@@ -25176,7 +25736,7 @@ class EntityDecoder {
25176
25736
  const startIndex = offset;
25177
25737
  while (offset < input.length) {
25178
25738
  const char = input.charCodeAt(offset);
25179
- if (isNumber(char)) {
25739
+ if (isNumber2(char)) {
25180
25740
  offset += 1;
25181
25741
  } else {
25182
25742
  this.addToNumericResult(input, startIndex, offset, 10);
@@ -32612,11 +33172,11 @@ function convertHastNode(node) {
32612
33172
  if (whitespace(node)) {
32613
33173
  return null;
32614
33174
  }
32615
- return node.value ?? null;
33175
+ return node.value;
32616
33176
  }
32617
33177
  if (node.type === "element") {
32618
33178
  const el = { tagName: node.tagName };
32619
- if (node.properties && Object.keys(node.properties).length > 0) {
33179
+ if (Object.keys(node.properties).length > 0) {
32620
33180
  const { style, attrs } = hastPropsToJx(node.properties);
32621
33181
  if (Object.keys(attrs).length > 0) {
32622
33182
  el.attributes = attrs;
@@ -32625,8 +33185,8 @@ function convertHastNode(node) {
32625
33185
  el.style = style;
32626
33186
  }
32627
33187
  }
32628
- const kids = node.children ? convertHastChildren(node.children) : [];
32629
- if (kids.length === 1 && typeof kids[0] === "string") {
33188
+ const kids = convertHastChildren(node.children);
33189
+ if (kids.length === 1 && isString(kids[0])) {
32630
33190
  [el.textContent] = kids;
32631
33191
  } else if (kids.length > 0) {
32632
33192
  el.children = kids;
@@ -32644,7 +33204,7 @@ function hastPropsToJx(properties) {
32644
33204
  }
32645
33205
  const info = find(html3, key);
32646
33206
  const name = info.attribute;
32647
- if (name === "style" && typeof value === "string") {
33207
+ if (name === "style" && isString(value)) {
32648
33208
  parseInlineStyle(value, style);
32649
33209
  continue;
32650
33210
  }
@@ -32675,6 +33235,7 @@ var init_html_to_jx = __esm(() => {
32675
33235
  init_hast_util_from_html();
32676
33236
  init_hast_util_whitespace();
32677
33237
  init_property_information();
33238
+ init_guards();
32678
33239
  });
32679
33240
 
32680
33241
  // src/transpile.ts
@@ -32690,21 +33251,24 @@ function jxKey(key) {
32690
33251
  function expandDotPaths(attrs) {
32691
33252
  const result = {};
32692
33253
  for (const [key, value] of Object.entries(attrs)) {
32693
- const dotIndex = key.indexOf(".");
32694
- if (dotIndex === -1) {
33254
+ const lastDot = key.lastIndexOf(".");
33255
+ if (lastDot === -1) {
32695
33256
  result[jxKey(key)] = value;
32696
33257
  continue;
32697
33258
  }
32698
- const segments = key.split(".");
32699
33259
  let target = result;
32700
- for (let i = 0;i < segments.length - 1; i++) {
32701
- const seg = jxKey(segments[i]);
32702
- if (!(seg in target) || typeof target[seg] !== "object") {
32703
- target[seg] = {};
33260
+ for (const segment of key.slice(0, lastDot).split(".")) {
33261
+ const seg = jxKey(segment);
33262
+ const existing = seg in target ? target[seg] : undefined;
33263
+ if (isNonNullObject(existing)) {
33264
+ target = existing;
33265
+ } else {
33266
+ const nested = {};
33267
+ target[seg] = nested;
33268
+ target = nested;
32704
33269
  }
32705
- target = target[seg];
32706
33270
  }
32707
- target[jxKey(segments.at(-1))] = value;
33271
+ target[jxKey(key.slice(lastDot + 1))] = value;
32708
33272
  }
32709
33273
  return result;
32710
33274
  }
@@ -32725,22 +33289,34 @@ function applyStyleKeyMapping(styleObj) {
32725
33289
  }
32726
33290
  function routeAttributes(attrs) {
32727
33291
  const expanded = expandDotPaths(attrs);
32728
- if (expanded.style && typeof expanded.style === "object") {
32729
- expanded.style = applyStyleKeyMapping(expanded.style);
33292
+ const { style } = expanded;
33293
+ if (isNonNullObject(style)) {
33294
+ expanded.style = applyStyleKeyMapping(style);
32730
33295
  }
32731
33296
  const props = {};
32732
33297
  const attributes = {};
32733
33298
  for (const [key, value] of Object.entries(expanded)) {
32734
33299
  if (HTML_ATTR_PATTERN.test(key)) {
32735
- attributes[key] = value;
33300
+ attributes[key] = attributeValue(value);
32736
33301
  } else {
32737
33302
  props[key] = value;
32738
33303
  }
32739
33304
  }
32740
33305
  return { attributes, props };
32741
33306
  }
33307
+ function attributeValue(value) {
33308
+ return value;
33309
+ }
33310
+ function setContent(el, children) {
33311
+ const [only] = children;
33312
+ if (children.length === 1 && isString(only)) {
33313
+ el.textContent = only;
33314
+ } else if (children.length > 0) {
33315
+ el.children = children;
33316
+ }
33317
+ }
32742
33318
  function mdastNodeToJx(node) {
32743
- if (!node || typeof node !== "object") {
33319
+ if (!node) {
32744
33320
  return null;
32745
33321
  }
32746
33322
  if (node.type === "yaml" || node.type === "toml") {
@@ -32761,7 +33337,7 @@ function mdastNodeToJx(node) {
32761
33337
  }
32762
33338
  return null;
32763
33339
  }
32764
- const tagFn = JX_TAG_MAP[node.type];
33340
+ const tagFn = JX_TAG_MAP.get(node.type);
32765
33341
  if (!tagFn) {
32766
33342
  return null;
32767
33343
  }
@@ -32777,12 +33353,7 @@ function mdastNodeToJx(node) {
32777
33353
  case "listItem":
32778
33354
  case "tableRow":
32779
33355
  case "tableCell": {
32780
- const children = convertChildren(node.children ?? []);
32781
- if (children.length === 1 && typeof children[0] === "string") {
32782
- [el.textContent] = children;
32783
- } else if (children.length > 0) {
32784
- el.children = children;
32785
- }
33356
+ setContent(el, convertChildren(node.children ?? []));
32786
33357
  break;
32787
33358
  }
32788
33359
  case "inlineCode": {
@@ -32790,34 +33361,18 @@ function mdastNodeToJx(node) {
32790
33361
  break;
32791
33362
  }
32792
33363
  case "link": {
32793
- {
32794
- const linkAttrs = {
32795
- href: node.url ?? ""
32796
- };
32797
- if (node.title) {
32798
- linkAttrs.title = node.title;
32799
- }
32800
- el.attributes = linkAttrs;
32801
- }
32802
- {
32803
- const children = convertChildren(node.children ?? []);
32804
- if (children.length === 1 && typeof children[0] === "string") {
32805
- [el.textContent] = children;
32806
- } else if (children.length > 0) {
32807
- el.children = children;
32808
- }
33364
+ el.attributes = { href: node.url ?? "" };
33365
+ if (node.title) {
33366
+ el.attributes.title = node.title;
32809
33367
  }
33368
+ setContent(el, convertChildren(node.children ?? []));
32810
33369
  break;
32811
33370
  }
32812
33371
  case "image": {
32813
- const imageAttrs = {
32814
- alt: node.alt ?? "",
32815
- src: node.url ?? ""
32816
- };
33372
+ el.attributes = { alt: node.alt ?? "", src: node.url ?? "" };
32817
33373
  if (node.title) {
32818
- imageAttrs.title = node.title;
33374
+ el.attributes.title = node.title;
32819
33375
  }
32820
- el.attributes = imageAttrs;
32821
33376
  break;
32822
33377
  }
32823
33378
  case "list": {
@@ -32830,13 +33385,11 @@ function mdastNodeToJx(node) {
32830
33385
  break;
32831
33386
  }
32832
33387
  case "code": {
32833
- el.children = [
32834
- {
32835
- tagName: "code",
32836
- textContent: node.value ?? null,
32837
- ...node.lang ? { className: `language-${node.lang}` } : {}
32838
- }
32839
- ];
33388
+ const code = { tagName: "code", textContent: node.value ?? null };
33389
+ if (node.lang) {
33390
+ code.className = `language-${node.lang}`;
33391
+ }
33392
+ el.children = [code];
32840
33393
  break;
32841
33394
  }
32842
33395
  case "thematicBreak":
@@ -32846,16 +33399,21 @@ function mdastNodeToJx(node) {
32846
33399
  case "table": {
32847
33400
  const rows = convertChildren(node.children ?? []);
32848
33401
  const [headerRow] = rows;
32849
- if (headerRow && typeof headerRow === "object" && Array.isArray(headerRow.children)) {
33402
+ if (isNonNullObject(headerRow) && Array.isArray(headerRow.children)) {
32850
33403
  for (const cell of headerRow.children) {
32851
- if (cell && typeof cell === "object" && cell.tagName === "td") {
33404
+ if (isNonNullObject(cell) && cell.tagName === "td") {
32852
33405
  cell.tagName = "th";
32853
33406
  }
32854
33407
  }
32855
33408
  }
32856
- const thead = rows.length > 0 ? { children: [rows[0]], tagName: "thead" } : null;
32857
- const tbody = rows.length > 1 ? { children: rows.slice(1), tagName: "tbody" } : null;
32858
- el.children = [thead, tbody].filter(Boolean);
33409
+ const sections = [];
33410
+ if (headerRow !== undefined) {
33411
+ sections.push({ children: [headerRow], tagName: "thead" });
33412
+ }
33413
+ if (rows.length > 1) {
33414
+ sections.push({ children: rows.slice(1), tagName: "tbody" });
33415
+ }
33416
+ el.children = sections;
32859
33417
  break;
32860
33418
  }
32861
33419
  default: {
@@ -32867,10 +33425,7 @@ function mdastNodeToJx(node) {
32867
33425
  function alertToJx(node) {
32868
33426
  const body = convertChildren(node.children ?? []);
32869
33427
  if (node.element) {
32870
- const attributes = { "data-alert": node.alert };
32871
- if (node.titleNodes) {
32872
- attributes["data-title"] = inlineText(node.titleNodes).trim();
32873
- }
33428
+ const attributes = node.titleNodes ? { "data-alert": node.alert, "data-title": inlineText(node.titleNodes).trim() } : { "data-alert": node.alert };
32874
33429
  const el = { attributes, tagName: node.element };
32875
33430
  if (body.length > 0) {
32876
33431
  el.children = body;
@@ -32880,8 +33435,9 @@ function alertToJx(node) {
32880
33435
  const title = { className: "jx-alert-title", tagName: "p" };
32881
33436
  if (node.titleNodes) {
32882
33437
  const inline = convertChildren(node.titleNodes);
32883
- if (inline.length === 1 && typeof inline[0] === "string") {
32884
- [title.textContent] = inline;
33438
+ const [only] = inline;
33439
+ if (inline.length === 1 && isString(only)) {
33440
+ title.textContent = only;
32885
33441
  } else {
32886
33442
  title.children = inline;
32887
33443
  }
@@ -32896,13 +33452,14 @@ function alertToJx(node) {
32896
33452
  };
32897
33453
  }
32898
33454
  function directiveToJx(node) {
32899
- if (PROTOTYPE_DIRECTIVE_NAMES.has(node.name)) {
32900
- return prototypeDirectiveToJx(node);
33455
+ const name = node.name;
33456
+ if (PROTOTYPE_DIRECTIVE_NAMES.has(name)) {
33457
+ return prototypeDirectiveToJx(node, name);
32901
33458
  }
32902
- const el = { tagName: node.name };
33459
+ const el = { tagName: name };
32903
33460
  if (node.attributes && Object.keys(node.attributes).length > 0) {
32904
33461
  const { props, attributes } = routeAttributes(node.attributes);
32905
- const isCustomElement = node.name.includes("-");
33462
+ const isCustomElement = name.includes("-");
32906
33463
  if (isCustomElement) {
32907
33464
  for (const [key, value] of Object.entries(props)) {
32908
33465
  if (key === "style" || key === "children" || key === "textContent" || key === "innerHTML" || key.startsWith("$")) {
@@ -32911,7 +33468,7 @@ function directiveToJx(node) {
32911
33468
  if (!el.attributes) {
32912
33469
  el.attributes = {};
32913
33470
  }
32914
- el.attributes[key] = value;
33471
+ el.attributes[key] = attributeValue(value);
32915
33472
  }
32916
33473
  }
32917
33474
  } else {
@@ -32922,7 +33479,7 @@ function directiveToJx(node) {
32922
33479
  if (!el.attributes) {
32923
33480
  el.attributes = {};
32924
33481
  }
32925
- el.attributes[key] = value;
33482
+ el.attributes[key] = attributeValue(value);
32926
33483
  }
32927
33484
  }
32928
33485
  }
@@ -32932,12 +33489,7 @@ function directiveToJx(node) {
32932
33489
  }
32933
33490
  if (node.type === "textDirective") {
32934
33491
  if (node.children && node.children.length > 0) {
32935
- const children = convertChildren(node.children ?? []);
32936
- if (children.length === 1 && typeof children[0] === "string") {
32937
- [el.textContent] = children;
32938
- } else if (children.length > 0) {
32939
- el.children = children;
32940
- }
33492
+ setContent(el, convertChildren(node.children));
32941
33493
  }
32942
33494
  return el;
32943
33495
  }
@@ -32946,7 +33498,7 @@ function directiveToJx(node) {
32946
33498
  }
32947
33499
  if (node.children && node.children.length > 0) {
32948
33500
  const jxChildren = [];
32949
- const isPhrasingParent = PHRASING_ELEMENTS.has(node.name);
33501
+ const isPhrasingParent = PHRASING_ELEMENTS.has(name);
32950
33502
  for (const child of node.children) {
32951
33503
  if (isPhrasingParent && child.type === "paragraph") {
32952
33504
  for (const inline of child.children ?? []) {
@@ -32972,16 +33524,14 @@ function directiveToJx(node) {
32972
33524
  }
32973
33525
  }
32974
33526
  }
32975
- if (el.children && typeof el.children === "object" && !Array.isArray(el.children)) {} else if (jxChildren.length === 1 && typeof jxChildren[0] === "string") {
32976
- [el.textContent] = jxChildren;
32977
- } else if (jxChildren.length > 0) {
32978
- el.children = jxChildren;
33527
+ if (!isNonNullObject(el.children) || Array.isArray(el.children)) {
33528
+ setContent(el, jxChildren);
32979
33529
  }
32980
33530
  }
32981
33531
  return el;
32982
33532
  }
32983
- function prototypeDirectiveToJx(node) {
32984
- const el = { $prototype: node.name };
33533
+ function prototypeDirectiveToJx(node, name) {
33534
+ const el = { $prototype: name };
32985
33535
  if (node.attributes && Object.keys(node.attributes).length > 0) {
32986
33536
  const expanded = expandDotPaths(node.attributes);
32987
33537
  for (const [key, value] of Object.entries(expanded)) {
@@ -32992,7 +33542,7 @@ function prototypeDirectiveToJx(node) {
32992
33542
  }
32993
33543
  }
32994
33544
  const children = convertChildren(node.children ?? []);
32995
- const template = children.find((c) => c != null && typeof c === "object");
33545
+ const template = children.find((c) => !isString(c));
32996
33546
  if (template) {
32997
33547
  el.map = template;
32998
33548
  }
@@ -33002,17 +33552,19 @@ function convertChildren(children) {
33002
33552
  if (!children) {
33003
33553
  return [];
33004
33554
  }
33005
- return children.flatMap((n) => mdastNodeToJx(n)).filter((c) => c != null);
33555
+ return children.flatMap((n) => mdastNodeToJx(n) ?? []);
33006
33556
  }
33007
33557
  function transpileJxMarkdown(source) {
33008
33558
  const processor = unified().use(remarkParse).use(remarkFrontmatter, ["yaml"]).use(import_remark_parse_frontmatter.default).use(remarkGfm).use(remarkDirective);
33009
33559
  const tree = processor.parse(source);
33010
33560
  const vfile = { data: {} };
33011
33561
  processor.runSync(tree, vfile);
33012
- const frontmatter = vfile.data?.frontmatter ?? {};
33562
+ const frontmatter = vfile.data.frontmatter ?? {};
33013
33563
  const doc = {};
33014
- for (const [key, value] of Object.entries(frontmatter)) {
33015
- doc[key] = value;
33564
+ if (!isNumber(frontmatter) && !isBoolean(frontmatter)) {
33565
+ for (const [key, value] of Object.entries(frontmatter)) {
33566
+ doc[key] = value;
33567
+ }
33016
33568
  }
33017
33569
  const bodyNodes = tree.children.filter((n) => n.type !== "yaml" && n.type !== "toml");
33018
33570
  const children = [];
@@ -33036,10 +33588,10 @@ function slugifyHeading(text) {
33036
33588
  return text.normalize("NFC").toLowerCase().replaceAll(/[^\p{L}\p{N}_\s-]/gu, "").replaceAll(/\s+/gu, "-").replaceAll(/-+/g, "-").replaceAll(/^-|-$/g, "");
33037
33589
  }
33038
33590
  function jxNodeText(node) {
33039
- if (typeof node === "string") {
33591
+ if (isString(node)) {
33040
33592
  return node;
33041
33593
  }
33042
- let out = typeof node.textContent === "string" ? node.textContent : "";
33594
+ let out = isString(node.textContent) ? node.textContent : "";
33043
33595
  if (Array.isArray(node.children)) {
33044
33596
  for (const child of node.children) {
33045
33597
  out += jxNodeText(child);
@@ -33052,13 +33604,13 @@ function assignHeadingIds(children) {
33052
33604
  const seen = new Map;
33053
33605
  function walk(nodes) {
33054
33606
  for (const node of nodes) {
33055
- if (typeof node !== "object" || node === null) {
33607
+ if (!isNonNullObject(node)) {
33056
33608
  continue;
33057
33609
  }
33058
- const tag = typeof node.tagName === "string" ? node.tagName : "";
33610
+ const tag = isString(node.tagName) ? node.tagName : "";
33059
33611
  if (tag && HEADING_TAGS.has(tag)) {
33060
33612
  const text = jxNodeText(node).trim();
33061
- let id = typeof node.id === "string" && node.id.length > 0 ? node.id : "";
33613
+ let id = isString(node.id) && node.id.length > 0 ? node.id : "";
33062
33614
  if (id) {
33063
33615
  seen.set(id, (seen.get(id) ?? 0) + 1);
33064
33616
  } else {
@@ -33088,6 +33640,7 @@ var init_transpile = __esm(() => {
33088
33640
  init_remark_gfm();
33089
33641
  init_remark_directive();
33090
33642
  init_html_to_jx();
33643
+ init_guards();
33091
33644
  init_alerts();
33092
33645
  init_html_to_jx();
33093
33646
  import_remark_parse_frontmatter = __toESM(require_dist2(), 1);
@@ -33155,25 +33708,25 @@ var init_transpile = __esm(() => {
33155
33708
  "summary",
33156
33709
  "dt"
33157
33710
  ]);
33158
- JX_TAG_MAP = {
33159
- blockquote: () => "blockquote",
33160
- break: () => "br",
33161
- code: () => "pre",
33162
- delete: () => "del",
33163
- emphasis: () => "em",
33164
- heading: (n) => `h${n.depth}`,
33165
- image: () => "img",
33166
- inlineCode: () => "code",
33167
- link: () => "a",
33168
- list: (n) => n.ordered ? "ol" : "ul",
33169
- listItem: () => "li",
33170
- paragraph: () => "p",
33171
- strong: () => "strong",
33172
- table: () => "table",
33173
- tableCell: (n) => n.isHeader ? "th" : "td",
33174
- tableRow: () => "tr",
33175
- thematicBreak: () => "hr"
33176
- };
33711
+ JX_TAG_MAP = new Map([
33712
+ ["blockquote", () => "blockquote"],
33713
+ ["break", () => "br"],
33714
+ ["code", () => "pre"],
33715
+ ["delete", () => "del"],
33716
+ ["emphasis", () => "em"],
33717
+ ["heading", (n) => `h${n.depth}`],
33718
+ ["image", () => "img"],
33719
+ ["inlineCode", () => "code"],
33720
+ ["link", () => "a"],
33721
+ ["list", (n) => n.ordered ? "ol" : "ul"],
33722
+ ["listItem", () => "li"],
33723
+ ["paragraph", () => "p"],
33724
+ ["strong", () => "strong"],
33725
+ ["table", () => "table"],
33726
+ ["tableCell", (n) => n.isHeader ? "th" : "td"],
33727
+ ["tableRow", () => "tr"],
33728
+ ["thematicBreak", () => "hr"]
33729
+ ]);
33177
33730
  HEADING_TAGS = new Set(["h1", "h2", "h3", "h4", "h5", "h6"]);
33178
33731
  });
33179
33732
 
@@ -33237,6 +33790,10 @@ import { existsSync, readFileSync, readdirSync as readdirSync2, statSync as stat
33237
33790
  import { basename, dirname, extname, relative, resolve } from "node:path";
33238
33791
 
33239
33792
  // ../../packages/schema/src/asset-paths.ts
33793
+ init_guards();
33794
+ var CONTENT_SECTION_KEY = "content";
33795
+ var SAFE_CONTENT_TYPE_NAME = /^[\w.~-]+$/;
33796
+ var LOCALE_PLACEHOLDER = "{locale}";
33240
33797
  function normalizeDir(value) {
33241
33798
  const forward = value.replaceAll("\\", "/");
33242
33799
  return forward.length > 1 && forward.endsWith("/") ? forward.slice(0, -1) : forward;
@@ -33271,6 +33828,7 @@ function assetUrlFor(mounts, absolutePath) {
33271
33828
  var URL_TERMINATOR = String.raw`"'\s<>()\\`;
33272
33829
 
33273
33830
  // ../../packages/schema/src/locale.ts
33831
+ init_guards();
33274
33832
  var RTL_SCRIPTS = new Set([
33275
33833
  "Adlm",
33276
33834
  "Arab",
@@ -33313,7 +33871,7 @@ var RTL_SCRIPTS = new Set([
33313
33871
  "Yezi"
33314
33872
  ]);
33315
33873
  function canonicalizeLocale(tag) {
33316
- if (typeof tag !== "string" || tag.trim() === "") {
33874
+ if (!isString(tag) || tag.trim() === "") {
33317
33875
  return null;
33318
33876
  }
33319
33877
  try {
@@ -33326,7 +33884,7 @@ var DEFAULT_ROUTING = "prefix-except-default";
33326
33884
  function resolveI18n(projectConfig) {
33327
33885
  const raw = projectConfig.i18n;
33328
33886
  const errors = [];
33329
- if (!raw || typeof raw !== "object") {
33887
+ if (!isNonNullObject(raw)) {
33330
33888
  return { errors, i18n: null };
33331
33889
  }
33332
33890
  const declared = Array.isArray(raw.locales) ? raw.locales : [];
@@ -33370,9 +33928,14 @@ function localeUrlPrefix(locale, i18n) {
33370
33928
  }
33371
33929
 
33372
33930
  // src/content-loader.ts
33931
+ init_guards();
33373
33932
  init_alerts();
33374
33933
 
33934
+ // src/content-links.ts
33935
+ init_guards();
33936
+
33375
33937
  // src/content-routes.ts
33938
+ init_guards();
33376
33939
  init_content_rules();
33377
33940
  function slugifySegment(text) {
33378
33941
  return text.normalize("NFKD").replaceAll(/(?<=\p{Script=Latin})\p{M}+/gu, "").normalize("NFC").replaceAll("&", " and ").replaceAll(/['’]/g, "").toLowerCase().replaceAll(/[^\p{L}\p{M}\p{N}]+/gu, "-").replaceAll(/^-+|-+$/g, "");
@@ -33387,13 +33950,13 @@ var TRANSFORMS = {
33387
33950
  upper: (value) => value.toUpperCase()
33388
33951
  };
33389
33952
  function parseRouteTemplate(source, where) {
33390
- if (typeof source !== "string" || !source.startsWith("/")) {
33953
+ if (!isString(source) || !source.startsWith("/")) {
33391
33954
  throw new TypeError(`${where}: a route template is a site-absolute path starting with "/", got ${JSON.stringify(source)}`);
33392
33955
  }
33393
33956
  const tokens = [];
33394
33957
  let last = 0;
33395
33958
  for (const match of source.matchAll(/\{([^{}]*)\}/g)) {
33396
- const index = match.index ?? 0;
33959
+ const { index } = match;
33397
33960
  if (index > last) {
33398
33961
  tokens.push({ literal: source.slice(last, index) });
33399
33962
  }
@@ -33439,10 +34002,10 @@ function directoryOf(path) {
33439
34002
  return slash === -1 ? "" : path.slice(0, slash);
33440
34003
  }
33441
34004
  function textOf(value) {
33442
- if (typeof value === "string") {
34005
+ if (isString(value)) {
33443
34006
  return value.trim() === "" ? null : value;
33444
34007
  }
33445
- if (typeof value === "number" || typeof value === "boolean") {
34008
+ if (isNumber(value) || isBoolean(value)) {
33446
34009
  return String(value);
33447
34010
  }
33448
34011
  if (value instanceof Date && !Number.isNaN(value.getTime())) {
@@ -33695,10 +34258,10 @@ function contentOf(anchor) {
33695
34258
  if (Array.isArray(anchor.children)) {
33696
34259
  return anchor.children;
33697
34260
  }
33698
- if (typeof anchor.innerHTML === "string") {
34261
+ if (anchor.innerHTML !== undefined) {
33699
34262
  return [{ innerHTML: anchor.innerHTML, tagName: "span" }];
33700
34263
  }
33701
- return typeof anchor.textContent === "string" ? [anchor.textContent] : [];
34264
+ return isString(anchor.textContent) ? [anchor.textContent] : [];
33702
34265
  }
33703
34266
  function rewriteLinks(nodes, from, index, report) {
33704
34267
  for (let i = 0;i < nodes.length; i++) {
@@ -33707,11 +34270,11 @@ function rewriteLinks(nodes, from, index, report) {
33707
34270
  rewriteLinks(node, from, index, report);
33708
34271
  continue;
33709
34272
  }
33710
- if (typeof node !== "object" || node === null) {
34273
+ if (!isNonNullObject(node)) {
33711
34274
  continue;
33712
34275
  }
33713
34276
  const href = node.tagName === "a" ? node.attributes?.href : undefined;
33714
- if (typeof href === "string") {
34277
+ if (isString(href)) {
33715
34278
  const resolution = resolveHref(href, from, index);
33716
34279
  if ("problem" in resolution) {
33717
34280
  report({ href, reason: resolution.problem });
@@ -33735,9 +34298,10 @@ function rewriteLinks(nodes, from, index, report) {
33735
34298
  init_content_rules();
33736
34299
 
33737
34300
  // src/dates.ts
34301
+ init_guards();
33738
34302
  var DATE_FORMATS = ["date", "date-time"];
33739
34303
  function isDateFormat(format) {
33740
- return typeof format === "string" && DATE_FORMATS.includes(format);
34304
+ return DATE_FORMATS.some((candidate) => candidate === format);
33741
34305
  }
33742
34306
  var DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
33743
34307
  var RFC_3339 = /^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?([Zz]|[+-]\d{2}:\d{2})?$/;
@@ -33754,7 +34318,7 @@ function parseDateValue(value, format) {
33754
34318
  if (value instanceof Date) {
33755
34319
  return Number.isNaN(value.getTime()) ? null : format === "date" ? toDateOnly(value) : toInstant(value);
33756
34320
  }
33757
- if (typeof value !== "string") {
34321
+ if (!isString(value)) {
33758
34322
  return null;
33759
34323
  }
33760
34324
  const text = value.trim();
@@ -33787,7 +34351,7 @@ function coerceEntryDates(entries, schema, contentTypeName) {
33787
34351
  if (!properties) {
33788
34352
  return warnings;
33789
34353
  }
33790
- const dateFields = Object.entries(properties).map(([field, def]) => [field, def.format]).filter((pair) => isDateFormat(pair[1]));
34354
+ const dateFields = Object.entries(properties).flatMap(([field, def]) => isDateFormat(def.format) ? [[field, def.format]] : []);
33791
34355
  if (dateFields.length === 0) {
33792
34356
  return warnings;
33793
34357
  }
@@ -33818,9 +34382,7 @@ function coerceEntryDates(entries, schema, contentTypeName) {
33818
34382
  return warnings;
33819
34383
  }
33820
34384
  function parseComparable(a, b) {
33821
- const aDate = typeof a === "string" && (DATE_ONLY.test(a) || RFC_3339.test(a));
33822
- const bDate = typeof b === "string" && (DATE_ONLY.test(b) || RFC_3339.test(b));
33823
- if (aDate && bDate) {
34385
+ if (isString(a) && isCoercedDate(a) && isString(b) && isCoercedDate(b)) {
33824
34386
  return [a, b];
33825
34387
  }
33826
34388
  return [Number(a), Number(b)];
@@ -33828,23 +34390,24 @@ function parseComparable(a, b) {
33828
34390
 
33829
34391
  // src/content-loader.ts
33830
34392
  init_walk();
34393
+
34394
+ // src/content-data.ts
34395
+ async function entriesOf(data, name) {
34396
+ return await data?.load?.(name) ?? data?.get(name);
34397
+ }
34398
+
34399
+ // src/content-loader.ts
33831
34400
  function loadJSONEntries(filePath) {
33832
34401
  const raw = JSON.parse(readFileSync(filePath, "utf8"));
33833
34402
  if (Array.isArray(raw)) {
33834
- return raw.map((item, i) => ({
33835
- body: null,
33836
- data: item,
33837
- id: item.id ?? `${basename(filePath, ".json")}-${i}`
33838
- }));
34403
+ return raw.map((item, i) => jsonEntry(item, `${basename(filePath, ".json")}-${i}`));
33839
34404
  }
33840
- const rawObj = raw;
33841
- return [
33842
- {
33843
- body: null,
33844
- data: rawObj,
33845
- id: rawObj.id ?? basename(filePath, ".json")
33846
- }
33847
- ];
34405
+ return [jsonEntry(raw, basename(filePath, ".json"))];
34406
+ }
34407
+ function jsonEntry(item, fallbackId) {
34408
+ const data = item;
34409
+ const id = data.id ?? fallbackId;
34410
+ return { body: null, data, id };
33848
34411
  }
33849
34412
  function discoverJSONFiles(resolvedSource, exclude) {
33850
34413
  if (extname(resolvedSource)) {
@@ -33852,7 +34415,6 @@ function discoverJSONFiles(resolvedSource, exclude) {
33852
34415
  }
33853
34416
  return walkFiles(resolvedSource, (name) => name.toLowerCase().endsWith(".json"), exclude);
33854
34417
  }
33855
- var LOCALE_PLACEHOLDER = "{locale}";
33856
34418
  function localesForExpansion(projectConfig) {
33857
34419
  return resolveI18n(projectConfig ?? {}).i18n?.locales ?? [];
33858
34420
  }
@@ -33873,8 +34435,6 @@ function localeSource(root, source, locale) {
33873
34435
  }
33874
34436
  return source.split(LOCALE_PLACEHOLDER).join(locale);
33875
34437
  }
33876
- var SECTION_KEY = "content";
33877
- var SAFE_TYPE_NAME = /^[\w.~-]+$/;
33878
34438
  var ASSET_KEYS = ["src", "poster"];
33879
34439
  function isNonRelativeRef(value) {
33880
34440
  return value === "" || value.startsWith("/") || value.startsWith("#") || value.includes("${") || /^[a-z][\w+.-]*:/i.test(value);
@@ -33909,28 +34469,31 @@ function contentAssetMounts(section, root, projectConfig) {
33909
34469
  return filter === undefined ? {} : { filter };
33910
34470
  };
33911
34471
  for (const [name, contentTypeDef] of Object.entries(section ?? {})) {
33912
- const source = contentTypeDef?.source;
34472
+ if (!isNonNullObject(contentTypeDef)) {
34473
+ continue;
34474
+ }
34475
+ const { source } = contentTypeDef;
33913
34476
  if (!source || source.startsWith("http://") || source.startsWith("https://")) {
33914
34477
  continue;
33915
34478
  }
33916
34479
  if (source.includes(LOCALE_PLACEHOLDER)) {
33917
34480
  for (const locale of locales) {
33918
- if (!SAFE_TYPE_NAME.test(locale)) {
34481
+ if (!SAFE_CONTENT_TYPE_NAME.test(locale)) {
33919
34482
  continue;
33920
34483
  }
33921
34484
  const dir = resolve(root, localeSource(root, source, locale)).split("\\").join("/");
33922
- if (SAFE_TYPE_NAME.test(name) && existsSync(dir) && statSync2(dir).isDirectory()) {
34485
+ if (SAFE_CONTENT_TYPE_NAME.test(name) && existsSync(dir) && statSync2(dir).isDirectory()) {
33923
34486
  mounts.push({
33924
34487
  dir,
33925
- urlPrefix: `/${SECTION_KEY}/${name}/${locale}`,
34488
+ urlPrefix: `/${CONTENT_SECTION_KEY}/${name}/${locale}`,
33926
34489
  ...filterOf(contentTypeDef)
33927
34490
  });
33928
34491
  }
33929
34492
  }
33930
34493
  continue;
33931
34494
  }
33932
- if (!SAFE_TYPE_NAME.test(name)) {
33933
- console.warn(`Content type "${name}": name is not URL-safe — its source directory is not published ` + `at /${SECTION_KEY}/${name}, so content-relative asset references stay unresolved.`);
34495
+ if (!SAFE_CONTENT_TYPE_NAME.test(name)) {
34496
+ console.warn(`Content type "${name}": name is not URL-safe — its source directory is not published ` + `at /${CONTENT_SECTION_KEY}/${name}, so content-relative asset references stay unresolved.`);
33934
34497
  continue;
33935
34498
  }
33936
34499
  const resolvedSource = resolve(root, source).split("\\").join("/");
@@ -33939,7 +34502,7 @@ function contentAssetMounts(section, root, projectConfig) {
33939
34502
  }
33940
34503
  mounts.push({
33941
34504
  dir: resolvedSource,
33942
- urlPrefix: `/${SECTION_KEY}/${name}`,
34505
+ urlPrefix: `/${CONTENT_SECTION_KEY}/${name}`,
33943
34506
  ...filterOf(contentTypeDef)
33944
34507
  });
33945
34508
  }
@@ -33977,15 +34540,14 @@ function rewriteNodeAssets(node, entryDir, mount, onProblem) {
33977
34540
  }
33978
34541
  return;
33979
34542
  }
33980
- if (!node || typeof node !== "object") {
34543
+ if (!isNonNullObject(node)) {
33981
34544
  return;
33982
34545
  }
33983
- const record = node;
33984
- const attributes = record.attributes;
34546
+ const { attributes } = node;
33985
34547
  for (const key of ASSET_KEYS) {
33986
- for (const holder of [record, attributes]) {
34548
+ for (const holder of [node, attributes]) {
33987
34549
  const value = holder?.[key];
33988
- if (typeof value === "string") {
34550
+ if (holder && isString(value)) {
33989
34551
  const rewritten = rewriteRef(value, entryDir, mount, onProblem);
33990
34552
  if (rewritten) {
33991
34553
  holder[key] = rewritten;
@@ -33993,7 +34555,7 @@ function rewriteNodeAssets(node, entryDir, mount, onProblem) {
33993
34555
  }
33994
34556
  }
33995
34557
  }
33996
- const { children } = record;
34558
+ const { children } = node;
33997
34559
  if (Array.isArray(children)) {
33998
34560
  for (const child of children) {
33999
34561
  rewriteNodeAssets(child, entryDir, mount, onProblem);
@@ -34002,22 +34564,30 @@ function rewriteNodeAssets(node, entryDir, mount, onProblem) {
34002
34564
  }
34003
34565
  function rewriteEntryAssets(entries, filePath, mount, typeName, schema) {
34004
34566
  const entryDir = dirname(filePath);
34005
- const uriFields = Object.entries(schema?.properties ?? {}).filter(([, def]) => def?.format === "uri-reference" || def?.items?.format === "uri-reference").map(([field]) => field);
34567
+ const uriFields = Object.entries(schema?.properties ?? {}).flatMap(([field, def]) => isNonNullObject(def) && (def.format === "uri-reference" || def.items?.format === "uri-reference") ? [field] : []);
34006
34568
  for (const entry of entries) {
34007
- const onProblem = (value, problem) => console.warn(problem === "missing" ? `Content type "${typeName}": entry "${entry.id}" references missing asset "${value}"` : `Content type "${typeName}": entry "${entry.id}" references "${value}", which the ` + `collection does not publish (it is excluded, hidden or a document), so the ` + `reference is left as written`);
34008
- for (const child of entry.$children ?? []) {
34009
- rewriteNodeAssets(child, entryDir, mount, onProblem);
34010
- }
34569
+ const onProblem = assetProblemReporter(typeName, entry);
34570
+ rewriteBodyAssets(entry, filePath, mount, typeName);
34011
34571
  for (const field of uriFields) {
34012
34572
  const value = entry.data[field];
34013
- if (typeof value === "string") {
34573
+ if (isString(value)) {
34014
34574
  entry.data[field] = rewriteRef(value, entryDir, mount, onProblem) ?? value;
34015
34575
  } else if (Array.isArray(value)) {
34016
- entry.data[field] = value.map((item) => typeof item === "string" ? rewriteRef(item, entryDir, mount, onProblem) ?? item : item);
34576
+ entry.data[field] = value.map((item) => isString(item) ? rewriteRef(item, entryDir, mount, onProblem) ?? item : item);
34017
34577
  }
34018
34578
  }
34019
34579
  }
34020
34580
  }
34581
+ function assetProblemReporter(typeName, entry) {
34582
+ return (value, problem) => console.warn(problem === "missing" ? `Content type "${typeName}": entry "${entry.id}" references missing asset "${value}"` : `Content type "${typeName}": entry "${entry.id}" references "${value}", which the ` + `collection does not publish (it is excluded, hidden or a document), so the ` + `reference is left as written`);
34583
+ }
34584
+ function rewriteBodyAssets(entry, filePath, mount, typeName) {
34585
+ const entryDir = dirname(filePath);
34586
+ const onProblem = assetProblemReporter(typeName, entry);
34587
+ for (const child of entry.$children ?? []) {
34588
+ rewriteNodeAssets(child, entryDir, mount, onProblem);
34589
+ }
34590
+ }
34021
34591
  function loadContentConfig(projectRoot, projectConfig) {
34022
34592
  const contentDir = resolve(projectRoot, "content");
34023
34593
  const config = { content: projectConfig?.content ?? {} };
@@ -34025,48 +34595,63 @@ function loadContentConfig(projectRoot, projectConfig) {
34025
34595
  }
34026
34596
  async function loadContentSection(section, root, formats, projectConfig) {
34027
34597
  const contentTypes = new Map;
34028
- const mounts = new Map(contentAssetMounts(section, root, projectConfig).map((mount) => [
34029
- mount.urlPrefix.slice(`/${SECTION_KEY}/`.length),
34598
+ const mounts = sectionMounts(section, root, projectConfig);
34599
+ for (const name of Object.keys(section)) {
34600
+ contentTypes.set(name, await loadSectionType(name, { formats, mounts, projectConfig, root, section }));
34601
+ }
34602
+ return contentTypes;
34603
+ }
34604
+ function sectionMounts(section, root, projectConfig) {
34605
+ return new Map(contentAssetMounts(section, root, projectConfig).map((mount) => [
34606
+ mount.urlPrefix.slice(`/${CONTENT_SECTION_KEY}/`.length),
34030
34607
  mount
34031
34608
  ]));
34609
+ }
34610
+ async function loadSectionType(name, source) {
34611
+ const { section, root, formats, projectConfig, mounts, onDeferred } = source;
34612
+ const contentTypeDef = section[name];
34613
+ if (!contentTypeDef) {
34614
+ return [];
34615
+ }
34616
+ const deferral = onDeferred ? { deferBody: true, onDeferred } : {};
34617
+ const typeSource = contentTypeDef.source;
34618
+ if (!isString(typeSource) || !typeSource.includes(LOCALE_PLACEHOLDER)) {
34619
+ return await loadContentType(name, contentTypeDef, root, formats, {
34620
+ mount: mounts.get(name),
34621
+ projectConfig,
34622
+ ...deferral
34623
+ });
34624
+ }
34032
34625
  const locales = localesForExpansion(projectConfig);
34033
- for (const [name, contentTypeDef] of Object.entries(section)) {
34034
- const source = contentTypeDef?.source;
34035
- if (typeof source !== "string" || !source.includes(LOCALE_PLACEHOLDER)) {
34036
- const entries = await loadContentType(name, contentTypeDef, root, formats, {
34037
- mount: mounts.get(name),
34038
- projectConfig
34039
- });
34040
- contentTypes.set(name, entries);
34041
- continue;
34042
- }
34043
- if (locales.length === 0) {
34044
- console.warn(`Content type "${name}": source "${source}" uses ${LOCALE_PLACEHOLDER}, but the project ` + `declares no i18n locales — nothing to expand it over, so no entries were loaded.`);
34045
- contentTypes.set(name, []);
34046
- continue;
34047
- }
34048
- const all = [];
34049
- for (const locale of locales) {
34050
- const localized = { ...contentTypeDef, source: localeSource(root, source, locale) };
34051
- const entries = await loadContentType(name, localized, root, formats, {
34052
- locale,
34053
- mount: mounts.get(`${name}/${locale}`),
34054
- projectConfig
34055
- });
34056
- for (const entry of entries) {
34057
- entry._meta = { ...entry._meta, locale };
34058
- }
34059
- all.push(...entries);
34626
+ if (locales.length === 0) {
34627
+ console.warn(`Content type "${name}": source "${typeSource}" uses ${LOCALE_PLACEHOLDER}, but the project ` + `declares no i18n locales — nothing to expand it over, so no entries were loaded.`);
34628
+ return [];
34629
+ }
34630
+ const all = [];
34631
+ for (const locale of locales) {
34632
+ const localized = { ...contentTypeDef, source: localeSource(root, typeSource, locale) };
34633
+ const entries = await loadContentType(name, localized, root, formats, {
34634
+ locale,
34635
+ mount: mounts.get(`${name}/${locale}`),
34636
+ projectConfig,
34637
+ ...deferral
34638
+ });
34639
+ for (const entry of entries) {
34640
+ entry._meta = { ...entry._meta, locale };
34060
34641
  }
34061
- contentTypes.set(name, all);
34642
+ all.push(...entries);
34062
34643
  }
34063
- return contentTypes;
34644
+ return all;
34064
34645
  }
34065
34646
  function getContentTypeElements(projectRoot, contentTypeName, projectConfig) {
34066
34647
  const { config } = loadContentConfig(projectRoot, projectConfig);
34067
34648
  const def = config.content[contentTypeName];
34068
34649
  return def?.$elements;
34069
34650
  }
34651
+ var LINK_MODES = ["warn", "error", "ignore"];
34652
+ function isLinkMode(value) {
34653
+ return LINK_MODES.some((mode) => mode === value);
34654
+ }
34070
34655
  var KNOWN_TYPE_KEYS = [
34071
34656
  "$elements",
34072
34657
  "alerts",
@@ -34108,7 +34693,7 @@ function compileTypeRules(name, def) {
34108
34693
  const at = `Content type "${name}"`;
34109
34694
  try {
34110
34695
  for (const key of Object.keys(def)) {
34111
- if (KNOWN_TYPE_KEYS.includes(key) || key === "$comment") {
34696
+ if (KNOWN_TYPE_KEYS.some((known) => known === key) || key === "$comment") {
34112
34697
  continue;
34113
34698
  }
34114
34699
  const suggestion = nearestOption(key);
@@ -34117,11 +34702,11 @@ function compileTypeRules(name, def) {
34117
34702
  }
34118
34703
  console.warn(`${at}: ignores the unknown option "${key}" (the options are ${KNOWN_TYPE_KEYS.join(", ")})`);
34119
34704
  }
34120
- if (def.idField !== undefined && (typeof def.idField !== "string" || def.idField === "")) {
34705
+ if (def.idField !== undefined && (!isString(def.idField) || def.idField === "")) {
34121
34706
  throw new TypeError(`"idField" must be a field name`);
34122
34707
  }
34123
34708
  const links = def.links ?? "warn";
34124
- if (links !== "warn" && links !== "error" && links !== "ignore") {
34709
+ if (!isLinkMode(links)) {
34125
34710
  throw new TypeError(`"links" must be "warn", "error" or "ignore", got ${JSON.stringify(links)}`);
34126
34711
  }
34127
34712
  normalizeAlerts(def.alerts, `"alerts"`);
@@ -34182,7 +34767,7 @@ function finishEntries(files, ctx) {
34182
34767
  if (rules.idField) {
34183
34768
  for (const entry of entries) {
34184
34769
  const value = entry.data[rules.idField];
34185
- if (typeof value === "string" && value !== "" || typeof value === "number") {
34770
+ if (isString(value) && value !== "" || isNumber(value)) {
34186
34771
  const unsafe = traversalReason(String(value));
34187
34772
  if (unsafe === null) {
34188
34773
  entry.id = String(value);
@@ -34213,13 +34798,48 @@ function finishEntries(files, ctx) {
34213
34798
  }
34214
34799
  if (rules.route) {
34215
34800
  assignRoutes(entries, unpublished, ctx, rules.route);
34216
- if (ctx.sourceRoot) {
34217
- resolveEntryLinks(kept, unpublished, ctx);
34218
- }
34801
+ const links = ctx.sourceRoot ? resolveEntryLinks(kept, unpublished, ctx) : undefined;
34802
+ deferBodies(kept, ctx, links);
34219
34803
  return entries.filter((entry) => entry._meta?.route !== undefined);
34220
34804
  }
34805
+ deferBodies(kept, ctx);
34221
34806
  return entries;
34222
34807
  }
34808
+ function deferBodies(kept, ctx, links) {
34809
+ const { reload, onDeferred } = ctx;
34810
+ if (!reload || !onDeferred) {
34811
+ return;
34812
+ }
34813
+ for (const file of kept) {
34814
+ const [entry] = file.entries;
34815
+ if (file.entries.length !== 1 || !entry || entry.$children !== undefined) {
34816
+ continue;
34817
+ }
34818
+ onDeferred(entry, async () => {
34819
+ const [full] = await reload(file.filePath);
34820
+ if (!full) {
34821
+ return;
34822
+ }
34823
+ const completed = {
34824
+ ...full,
34825
+ ...entry,
34826
+ _meta: { ...full._meta, ...entry._meta }
34827
+ };
34828
+ for (const key of Object.keys(entry)) {
34829
+ Reflect.deleteProperty(entry, key);
34830
+ }
34831
+ Object.assign(entry, completed);
34832
+ if (ctx.mount) {
34833
+ rewriteBodyAssets(entry, file.filePath, ctx.mount, ctx.name);
34834
+ }
34835
+ if (links && file.rel !== null) {
34836
+ const broken = [];
34837
+ collectBrokenLinks(entry, file.rel, links, broken, new Set);
34838
+ reportBrokenLinks(broken, ctx.name, ctx.rules.links);
34839
+ }
34840
+ });
34841
+ }
34842
+ }
34223
34843
  function settleIndexIds(name, entries) {
34224
34844
  const indexFolders = new Set;
34225
34845
  for (const entry of entries) {
@@ -34242,7 +34862,7 @@ function settleIndexIds(name, entries) {
34242
34862
  }
34243
34863
  function trailingSlashOf(projectConfig) {
34244
34864
  const value = projectConfig?.build?.trailingSlash;
34245
- return typeof value === "string" ? value : "always";
34865
+ return isString(value) ? value : "always";
34246
34866
  }
34247
34867
  function localePrefixOf(ctx) {
34248
34868
  const { i18n } = resolveI18n(ctx.projectConfig ?? {});
@@ -34290,7 +34910,21 @@ function assignRoutes(entries, unpublished, ctx, spec) {
34290
34910
  }
34291
34911
  var UNROUTED_LISTED = 3;
34292
34912
  function resolveEntryLinks(kept, unpublished, ctx) {
34293
- const { name, rules, sourceRoot } = ctx;
34913
+ const index = buildLinkIndex(kept, unpublished, ctx);
34914
+ const broken = [];
34915
+ const seen = new Set;
34916
+ for (const file of kept) {
34917
+ for (const entry of file.entries) {
34918
+ if (entry.$children && file.rel !== null) {
34919
+ collectBrokenLinks(entry, file.rel, index, broken, seen);
34920
+ }
34921
+ }
34922
+ }
34923
+ reportBrokenLinks(broken, ctx.name, ctx.rules.links);
34924
+ return index;
34925
+ }
34926
+ function buildLinkIndex(kept, unpublished, ctx) {
34927
+ const { rules, sourceRoot } = ctx;
34294
34928
  const files = new Map;
34295
34929
  const indexes = new Map;
34296
34930
  const isReadme = (rel) => /^readme\./i.test(rel.slice(rel.lastIndexOf("/") + 1));
@@ -34321,7 +34955,7 @@ function resolveEntryLinks(kept, unpublished, ctx) {
34321
34955
  }
34322
34956
  }
34323
34957
  const onDisk = (path) => resolve(sourceRoot, path);
34324
- const index = {
34958
+ return {
34325
34959
  asset: (path) => {
34326
34960
  const absolute = onDisk(path);
34327
34961
  if (!ctx.mount || !existsSync(absolute) || statSync2(absolute).isDirectory()) {
@@ -34350,27 +34984,22 @@ function resolveEntryLinks(kept, unpublished, ctx) {
34350
34984
  localePrefix: localePrefixOf(ctx),
34351
34985
  trailingSlash: trailingSlashOf(ctx.projectConfig)
34352
34986
  };
34353
- const broken = [];
34354
- const seen = new Set;
34355
- for (const file of kept) {
34356
- for (const entry of file.entries) {
34357
- if (!entry.$children || file.rel === null) {
34358
- continue;
34359
- }
34360
- rewriteLinks(entry.$children, file.rel, index, (problem) => {
34361
- const key = `${file.rel}\x00${problem.href}`;
34362
- if (!seen.has(key)) {
34363
- seen.add(key);
34364
- broken.push({ from: file.rel, href: problem.href, reason: problem.reason });
34365
- }
34366
- });
34987
+ }
34988
+ function collectBrokenLinks(entry, rel, index, broken, seen) {
34989
+ rewriteLinks(entry.$children ?? [], rel, index, (problem) => {
34990
+ const key = `${rel}\x00${problem.href}`;
34991
+ if (!seen.has(key)) {
34992
+ seen.add(key);
34993
+ broken.push({ from: rel, href: problem.href, reason: problem.reason });
34367
34994
  }
34368
- }
34369
- if (rules.links === "ignore" || broken.length === 0) {
34995
+ });
34996
+ }
34997
+ function reportBrokenLinks(broken, name, mode) {
34998
+ if (mode === "ignore" || broken.length === 0) {
34370
34999
  return;
34371
35000
  }
34372
35001
  const lines = broken.map(({ from, href, reason }) => `"${from}" links to "${href}", which ${reason}`);
34373
- if (rules.links === "error") {
35002
+ if (mode === "error") {
34374
35003
  const plural = broken.length === 1 ? "" : "s";
34375
35004
  const list = lines.map((line) => ` - ${line}`).join(`
34376
35005
  `);
@@ -34390,8 +35019,8 @@ async function loadContentType(name, contentTypeDef, projectRoot, registry, opti
34390
35019
  if (!source) {
34391
35020
  return [];
34392
35021
  }
34393
- const { mount, projectConfig, locale } = options;
34394
- const schema = contentTypeDef.schema;
35022
+ const { mount, projectConfig, locale, deferBody, onDeferred } = options;
35023
+ const { schema } = contentTypeDef;
34395
35024
  const rules = compileTypeRules(name, contentTypeDef);
34396
35025
  const finishContext = (extra) => ({
34397
35026
  coerceDates: false,
@@ -34406,7 +35035,7 @@ async function loadContentType(name, contentTypeDef, projectRoot, registry, opti
34406
35035
  ...extra
34407
35036
  });
34408
35037
  const directiveOptions = contentTypeDef.$elements?.length ? {
34409
- allowedNames: contentTypeDef.$elements.filter((e) => typeof e === "string" || typeof e === "object" && e?.$ref).map((e) => typeof e === "string" ? e : e.$ref)
35038
+ allowedNames: contentTypeDef.$elements.flatMap((e) => isString(e) ? [e] : isNonNullObject(e) && e.$ref ? [e.$ref] : [])
34410
35039
  } : undefined;
34411
35040
  const formatName = contentTypeDef.format;
34412
35041
  let entry;
@@ -34462,25 +35091,32 @@ async function loadContentType(name, contentTypeDef, projectRoot, registry, opti
34462
35091
  if (!entry) {
34463
35092
  throw unknownFormatError(source, ext || `content type "${name}" (directory sources need an explicit "format")`);
34464
35093
  }
34465
- const discovered = entry.capabilities.discover ? await entry.call("discover", source, {
34466
- baseDir: projectRoot,
34467
- ...rules.exclude.empty ? {} : { exclude: contentTypeDef.exclude }
34468
- }) : [resolvedSource];
35094
+ const discoverOptions = { baseDir: projectRoot };
35095
+ if (!rules.exclude.empty) {
35096
+ discoverOptions.exclude = contentTypeDef.exclude;
35097
+ }
35098
+ const discovered = entry.capabilities.discover ? await entry.call("discover", source, discoverOptions) : [resolvedSource];
34469
35099
  const files = discovered.filter((file) => !isExcluded(file));
34470
35100
  const fileExtensions = files.map((file) => extname(file).toLowerCase());
35101
+ const format = entry;
35102
+ const loadFile = (filePath, withoutBody) => {
35103
+ const rel = relOf(filePath);
35104
+ return format.call("load", filePath, {
35105
+ directiveOptions,
35106
+ schema,
35107
+ ...sourceRoot !== undefined && { sourceRoot },
35108
+ ...rules.alerts !== undefined && { alerts: rules.alerts },
35109
+ ...rules.idField !== undefined && { idField: rules.idField },
35110
+ ...withoutBody && { deferBody: true },
35111
+ onUnknownAlert: (type) => console.warn(`Content callouts: "${name}": "${rel ?? filePath}" has a [!${type}] callout, but ` + `"${type.toLowerCase()}" is not an enabled type, so it stays a blockquote with the ` + `marker showing. Add "alerts": { "${type.toUpperCase()}": true } to render it.`)
35112
+ });
35113
+ };
34471
35114
  const loaded = [];
34472
35115
  for (const filePath of files) {
34473
35116
  const rel = relOf(filePath);
34474
35117
  let fileEntries;
34475
35118
  try {
34476
- fileEntries = await entry.call("load", filePath, {
34477
- directiveOptions,
34478
- schema,
34479
- ...sourceRoot !== undefined && { sourceRoot },
34480
- ...rules.alerts !== undefined && { alerts: rules.alerts },
34481
- ...rules.idField !== undefined && { idField: rules.idField },
34482
- onUnknownAlert: (type) => console.warn(`Content callouts: "${name}": "${rel ?? filePath}" has a [!${type}] callout, but ` + `"${type.toLowerCase()}" is not an enabled type, so it stays a blockquote with the ` + `marker showing. Add "alerts": { "${type.toUpperCase()}": true } to render it.`)
34483
- });
35119
+ fileEntries = await loadFile(filePath, deferBody === true);
34484
35120
  } catch (error) {
34485
35121
  throw unreadableFile(name, rel ?? filePath, error);
34486
35122
  }
@@ -34492,17 +35128,30 @@ async function loadContentType(name, contentTypeDef, projectRoot, registry, opti
34492
35128
  return finishEntries(loaded, finishContext({
34493
35129
  coerceDates: true,
34494
35130
  entryExtensions: new Set([...entry.extensions, ...fileExtensions]),
34495
- sourceRoot
35131
+ sourceRoot,
35132
+ ...deferBody === true && {
35133
+ onDeferred,
35134
+ reload: async (filePath) => await loadFile(filePath, false)
35135
+ }
34496
35136
  }));
34497
35137
  }
34498
- function unreadableFile(type, path, error) {
34499
- return new Error(`Content type "${type}": cannot read "${path}": ${errorMessage(error)}. Fix the file, or add it ` + `to "exclude" if it is not a document (a templates folder, for example).`, { cause: error });
35138
+ function unreadableFile(type, path, cause) {
35139
+ return new Error(`Content type "${type}": cannot read "${path}": ${errorMessage(cause)}. Fix the file, or add it ` + `to "exclude" if it is not a document (a templates folder, for example).`, { cause });
34500
35140
  }
34501
35141
  function unknownFormatError(path, ext) {
34502
35142
  return new Error(`No format class registered for "${ext}" (${path}). ` + `Enable an extension providing this format in project.json "extensions", ` + `e.g. "@jxsuite/parser".`);
34503
35143
  }
34504
- function errorMessage(error) {
34505
- return error instanceof Error ? error.message : String(error);
35144
+ function errorMessage(cause) {
35145
+ return cause instanceof Error ? cause.message : String(cause);
35146
+ }
35147
+ function jsTypeName(value) {
35148
+ if (isString(value)) {
35149
+ return "string";
35150
+ }
35151
+ if (isNumber(value)) {
35152
+ return "number";
35153
+ }
35154
+ return isBoolean(value) ? "boolean" : "object";
34506
35155
  }
34507
35156
  function validateEntries(entries, schema, contentTypeName) {
34508
35157
  const required = schema.required ?? [];
@@ -34518,16 +35167,16 @@ function validateEntries(entries, schema, contentTypeName) {
34518
35167
  if (value == null) {
34519
35168
  continue;
34520
35169
  }
34521
- if (isDateFormat(def.format) && typeof value === "string" && !isCoercedDate(value)) {
35170
+ if (isDateFormat(def.format) && isString(value) && !isCoercedDate(value)) {
34522
35171
  console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" is declared ` + `${def.format} but "${value}" was not coerced — it will sort and filter as plain text.`);
34523
- } else if (def.type === "string" && typeof value !== "string") {
34524
- console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected string, got ${typeof value}`);
34525
- } else if (def.type === "number" && typeof value !== "number") {
34526
- console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected number, got ${typeof value}`);
34527
- } else if (def.type === "boolean" && typeof value !== "boolean") {
34528
- console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected boolean, got ${typeof value}`);
35172
+ } else if (def.type === "string" && !isString(value)) {
35173
+ console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected string, got ${jsTypeName(value)}`);
35174
+ } else if (def.type === "number" && !isNumber(value)) {
35175
+ console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected number, got ${jsTypeName(value)}`);
35176
+ } else if (def.type === "boolean" && !isBoolean(value)) {
35177
+ console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected boolean, got ${jsTypeName(value)}`);
34529
35178
  } else if (def.type === "array" && !Array.isArray(value)) {
34530
- console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected array, got ${typeof value}`);
35179
+ console.warn(`Content validation: "${contentTypeName}/${entry.id}" field "${field}" expected array, got ${jsTypeName(value)}`);
34531
35180
  }
34532
35181
  }
34533
35182
  }
@@ -34539,9 +35188,19 @@ function refTargetName(ref) {
34539
35188
  }
34540
35189
  return ref.slice(CONTENT_REF_PREFIX.length);
34541
35190
  }
35191
+ function referencedContentTypes(def) {
35192
+ const targets = new Set;
35193
+ for (const field of Object.values(def?.schema?.properties ?? {})) {
35194
+ const target = refTargetName(field.$ref) ?? refTargetName(field.items?.$ref);
35195
+ if (target !== undefined) {
35196
+ targets.add(target);
35197
+ }
35198
+ }
35199
+ return [...targets];
35200
+ }
34542
35201
  function resolveContentTypeRefs(contentTypes, section) {
34543
35202
  for (const [name, contentTypeDef] of Object.entries(section)) {
34544
- const schema = contentTypeDef.schema;
35203
+ const { schema } = contentTypeDef;
34545
35204
  if (!schema?.properties) {
34546
35205
  continue;
34547
35206
  }
@@ -34563,7 +35222,7 @@ function resolveContentTypeRefs(contentTypes, section) {
34563
35222
  }
34564
35223
  for (const entry of entries) {
34565
35224
  const value = entry.data[field];
34566
- if (toOne && typeof value === "string") {
35225
+ if (toOne && isString(value)) {
34567
35226
  const resolved = refEntries.find((e) => e.id === value);
34568
35227
  if (resolved) {
34569
35228
  entry.data[field] = resolved;
@@ -34572,7 +35231,7 @@ function resolveContentTypeRefs(contentTypes, section) {
34572
35231
  }
34573
35232
  } else if (toMany && Array.isArray(value)) {
34574
35233
  entry.data[field] = value.map((id) => {
34575
- if (typeof id !== "string") {
35234
+ if (!isString(id)) {
34576
35235
  return id;
34577
35236
  }
34578
35237
  const resolved = refEntries.find((e) => e.id === id);
@@ -34599,7 +35258,10 @@ function reportUnservedRoutes(contentType, entries, ctx, prefix) {
34599
35258
  return;
34600
35259
  }
34601
35260
  const patterns = ctx.patterns.map((pattern) => withoutLocalePrefix(pattern, prefix));
34602
- const unserved = entries.map((entry) => entry._meta?.route).filter((route) => route !== undefined && !patterns.some((pattern) => routeParams(route, pattern, []) !== null));
35261
+ const unserved = entries.flatMap((entry) => {
35262
+ const route = entry._meta?.route;
35263
+ return route !== undefined && !patterns.some((pattern) => routeParams(route, pattern, []) !== null) ? [route] : [];
35264
+ });
34603
35265
  if (unserved.length === 0) {
34604
35266
  return;
34605
35267
  }
@@ -34622,7 +35284,11 @@ function routedPaths(contentType, entries, ctx, urlPattern) {
34622
35284
  example ??= route;
34623
35285
  const params = routeParams(route, pattern, ctx.params ?? []);
34624
35286
  if (params) {
34625
- paths.push({ ...params, ...entry._meta === undefined ? {} : { _meta: entry._meta } });
35287
+ const pathEntry = { ...params };
35288
+ if (entry._meta !== undefined) {
35289
+ pathEntry._meta = entry._meta;
35290
+ }
35291
+ paths.push(pathEntry);
34626
35292
  }
34627
35293
  }
34628
35294
  if (paths.length === 0 && example !== undefined) {
@@ -34632,18 +35298,159 @@ function routedPaths(contentType, entries, ctx, urlPattern) {
34632
35298
  return paths;
34633
35299
  }
34634
35300
 
35301
+ class ContentStore extends Map {
35302
+ #source;
35303
+ #mounts;
35304
+ #loads = new Map;
35305
+ #linked = new Set;
35306
+ #entries = new WeakSet;
35307
+ #deferred = new WeakMap;
35308
+ #completing = new WeakMap;
35309
+ constructor(source) {
35310
+ super();
35311
+ this.#source = source;
35312
+ this.#mounts = sectionMounts(source.section, source.root, source.projectConfig);
35313
+ }
35314
+ static async whole(source) {
35315
+ const store = new ContentStore(source);
35316
+ const loaded = await loadContentSection(source.section, source.root, source.formats, source.projectConfig);
35317
+ for (const [name, entries] of loaded) {
35318
+ store.#adopt(name, entries);
35319
+ store.#loads.set(name, Promise.resolve());
35320
+ }
35321
+ resolveContentTypeRefs(store, source.section);
35322
+ for (const name of loaded.keys()) {
35323
+ store.#linked.add(name);
35324
+ }
35325
+ return store;
35326
+ }
35327
+ static lazy(source) {
35328
+ return new ContentStore(source);
35329
+ }
35330
+ async load(name) {
35331
+ if (!Object.hasOwn(this.#source.section, name)) {
35332
+ return;
35333
+ }
35334
+ const related = this.#relatedTypes(name);
35335
+ await Promise.all(related.map(async (type) => await this.#loadType(type)));
35336
+ const unlinked = related.filter((type) => !this.#linked.has(type));
35337
+ for (const type of unlinked) {
35338
+ this.#linked.add(type);
35339
+ }
35340
+ if (unlinked.length > 0) {
35341
+ const { section } = this.#source;
35342
+ resolveContentTypeRefs(this, Object.fromEntries(unlinked.flatMap((type) => section[type] ? [[type, section[type]]] : [])));
35343
+ }
35344
+ return this.get(name);
35345
+ }
35346
+ async materialize(entries) {
35347
+ const seen = new Set;
35348
+ const pending = [];
35349
+ const visit = (entry) => {
35350
+ if (seen.has(entry)) {
35351
+ return;
35352
+ }
35353
+ seen.add(entry);
35354
+ pending.push(this.#complete(entry));
35355
+ for (const value of Object.values(entry.data)) {
35356
+ for (const item of Array.isArray(value) ? value : [value]) {
35357
+ if (this.#isEntry(item)) {
35358
+ visit(item);
35359
+ }
35360
+ }
35361
+ }
35362
+ };
35363
+ for (const entry of entries) {
35364
+ if (entry) {
35365
+ visit(entry);
35366
+ }
35367
+ }
35368
+ await Promise.all(pending);
35369
+ }
35370
+ async complete() {
35371
+ const lists = await Promise.all(Object.keys(this.#source.section).map(async (name) => await this.load(name) ?? []));
35372
+ await this.materialize(lists.flat());
35373
+ }
35374
+ #relatedTypes(name) {
35375
+ const { section } = this.#source;
35376
+ const found = new Set([name]);
35377
+ const queue = [name];
35378
+ for (let type = queue.shift();type !== undefined; type = queue.shift()) {
35379
+ for (const target of referencedContentTypes(section[type])) {
35380
+ if (Object.hasOwn(section, target) && !found.has(target)) {
35381
+ found.add(target);
35382
+ queue.push(target);
35383
+ }
35384
+ }
35385
+ }
35386
+ return [...found];
35387
+ }
35388
+ #loadType(name) {
35389
+ let load = this.#loads.get(name);
35390
+ if (!load) {
35391
+ const { section, root, formats, projectConfig } = this.#source;
35392
+ load = loadSectionType(name, {
35393
+ formats,
35394
+ mounts: this.#mounts,
35395
+ onDeferred: (entry, completeBody) => {
35396
+ this.#deferred.set(entry, completeBody);
35397
+ },
35398
+ projectConfig,
35399
+ root,
35400
+ section
35401
+ }).then((entries) => {
35402
+ this.#adopt(name, entries);
35403
+ });
35404
+ load.catch(() => {
35405
+ this.#loads.delete(name);
35406
+ });
35407
+ this.#loads.set(name, load);
35408
+ }
35409
+ return load;
35410
+ }
35411
+ #adopt(name, entries) {
35412
+ for (const entry of entries) {
35413
+ this.#entries.add(entry);
35414
+ }
35415
+ this.set(name, entries);
35416
+ }
35417
+ #isEntry(value) {
35418
+ return isNonNullObject(value) && this.#entries.has(value);
35419
+ }
35420
+ #complete(entry) {
35421
+ let completing = this.#completing.get(entry);
35422
+ if (!completing) {
35423
+ const completeBody = this.#deferred.get(entry);
35424
+ if (!completeBody) {
35425
+ return Promise.resolve();
35426
+ }
35427
+ completing = completeBody().then(() => {
35428
+ this.#deferred.delete(entry);
35429
+ });
35430
+ completing.catch(() => {
35431
+ this.#completing.delete(entry);
35432
+ });
35433
+ this.#completing.set(entry, completing);
35434
+ }
35435
+ return completing;
35436
+ }
35437
+ }
35438
+
34635
35439
  class Content {
34636
35440
  static async projectData(sectionValue, ctx) {
34637
- const section = sectionValue ?? {};
34638
- const data = await loadContentSection(section, ctx.root, ctx.registry.formats, ctx.projectConfig);
34639
- resolveContentTypeRefs(data, section);
34640
- return data;
35441
+ const source = {
35442
+ formats: ctx.registry.formats,
35443
+ projectConfig: ctx.projectConfig,
35444
+ root: ctx.root,
35445
+ section: sectionValue ?? {}
35446
+ };
35447
+ return ctx.lazy === true ? ContentStore.lazy(source) : await ContentStore.whole(source);
34641
35448
  }
34642
35449
  static assets(sectionValue, ctx) {
34643
35450
  return contentAssetMounts(sectionValue ?? {}, ctx.root, ctx.projectConfig);
34644
35451
  }
34645
35452
  static async resolvePaths(pathsDef, ctx) {
34646
- const entries = ctx.data.get(pathsDef.contentType);
35453
+ const entries = await entriesOf(ctx.data, pathsDef.contentType);
34647
35454
  if (!entries || entries.length === 0) {
34648
35455
  console.warn(`Warning: $paths references content type "${pathsDef.contentType}" but it has no entries`);
34649
35456
  return [];
@@ -34652,7 +35459,7 @@ class Content {
34652
35459
  const field = pathsDef.field ?? "id";
34653
35460
  const localized = entries.some((entry) => entry._meta?.locale !== undefined);
34654
35461
  const wanted = ctx.locale;
34655
- const scoped = localized && typeof wanted === "string" ? entries.filter((entry) => entry._meta?.locale === wanted) : entries;
35462
+ const scoped = localized && isString(wanted) ? entries.filter((entry) => entry._meta?.locale === wanted) : entries;
34656
35463
  if (pathsDef.param === undefined && pathsDef.field === undefined && ctx.urlPattern !== undefined && scoped.some((entry) => entry._meta?.route !== undefined)) {
34657
35464
  return routedPaths(pathsDef.contentType, scoped, ctx, ctx.urlPattern);
34658
35465
  }
@@ -34678,13 +35485,17 @@ class Content {
34678
35485
  }
34679
35486
  export {
34680
35487
  Content,
35488
+ ContentStore,
34681
35489
  LOCALE_PLACEHOLDER,
34682
35490
  contentAssetMounts,
34683
35491
  getContentTypeElements,
34684
35492
  loadContentConfig,
34685
35493
  loadContentSection,
35494
+ loadSectionType,
34686
35495
  localeSource,
34687
35496
  localesForExpansion,
35497
+ referencedContentTypes,
34688
35498
  resolveContentTypeRefs,
34689
- rewriteEntryAssets
35499
+ rewriteEntryAssets,
35500
+ sectionMounts
34690
35501
  };