@ni/ok-components 1.3.4 → 1.3.5

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.
@@ -29164,7 +29164,7 @@ so this becomes the fallback color for the slot */ ''}
29164
29164
  return Fragment.empty;
29165
29165
  if (!Array.isArray(value))
29166
29166
  throw new RangeError("Invalid input for Fragment.fromJSON");
29167
- return new Fragment(value.map(schema.nodeFromJSON));
29167
+ return Fragment.fromArray(value.map(schema.nodeFromJSON));
29168
29168
  }
29169
29169
  /**
29170
29170
  Build a fragment from an array of nodes. Ensures that adjacent
@@ -29398,17 +29398,6 @@ so this becomes the fallback color for the slot */ ''}
29398
29398
  */
29399
29399
  class ReplaceError extends Error {
29400
29400
  }
29401
- /*
29402
- ReplaceError = function(this: any, message: string) {
29403
- let err = Error.call(this, message)
29404
- ;(err as any).__proto__ = ReplaceError.prototype
29405
- return err
29406
- } as any
29407
-
29408
- ReplaceError.prototype = Object.create(Error.prototype)
29409
- ReplaceError.prototype.constructor = ReplaceError
29410
- ReplaceError.prototype.name = "ReplaceError"
29411
- */
29412
29401
  /**
29413
29402
  A slice represents a piece cut out of a larger document. It
29414
29403
  stores not only a fragment, but also the depth up to which nodes on
@@ -29454,7 +29443,7 @@ so this becomes the fallback color for the slot */ ''}
29454
29443
  @internal
29455
29444
  */
29456
29445
  insertAt(pos, fragment) {
29457
- let content = insertInto(this.content, pos + this.openStart, fragment);
29446
+ let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
29458
29447
  return content && new Slice(content, this.openStart, this.openEnd);
29459
29448
  }
29460
29449
  /**
@@ -29528,14 +29517,14 @@ so this becomes the fallback color for the slot */ ''}
29528
29517
  throw new RangeError("Removing non-flat range");
29529
29518
  return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
29530
29519
  }
29531
- function insertInto(content, dist, insert, parent) {
29520
+ function insertInto(content, dist, insert, openStart, openEnd, parent) {
29532
29521
  let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
29533
29522
  if (offset == dist || child.isText) {
29534
- if (parent && !parent.canReplace(index, index, insert))
29523
+ if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert))
29535
29524
  return null;
29536
29525
  return content.cut(0, dist).append(insert).append(content.cut(dist));
29537
29526
  }
29538
- let inner = insertInto(child.content, dist - offset - 1, insert, child);
29527
+ let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
29539
29528
  return inner && content.replaceChild(index, child.copy(inner));
29540
29529
  }
29541
29530
  function replace$1($from, $to, slice) {
@@ -30065,10 +30054,11 @@ so this becomes the fallback color for the slot */ ''}
30065
30054
  */
30066
30055
  forEach(f) { this.content.forEach(f); }
30067
30056
  /**
30068
- Invoke a callback for all descendant nodes recursively between
30057
+ Invoke a callback for all descendant nodes recursively overlapping
30069
30058
  the given two positions that are relative to start of this
30070
- node's content. The callback is invoked with the node, its
30071
- position relative to the original node (method receiver),
30059
+ node's content. This includes all ancestors of the nodes
30060
+ containing the two positions. The callback is invoked with the
30061
+ node, its position relative to the original node (method receiver),
30072
30062
  its parent node, and its child index. When the callback returns
30073
30063
  false for a given node, that node's children will not be
30074
30064
  recursed over. The last parameter can be used to specify a
@@ -32156,6 +32146,8 @@ so this becomes the fallback color for the slot */ ''}
32156
32146
  @internal
32157
32147
  */
32158
32148
  serializeNodeInner(node, options) {
32149
+ if (node.isText)
32150
+ return doc$1(options).createTextNode(node.text);
32159
32151
  let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
32160
32152
  if (contentDOM) {
32161
32153
  if (node.isLeaf)
@@ -32190,6 +32182,9 @@ so this becomes the fallback color for the slot */ ''}
32190
32182
  return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
32191
32183
  }
32192
32184
  static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
32185
+ // Kludge for backwards-compatibility with accidental original behavious
32186
+ if (typeof structure == "string")
32187
+ return { dom: doc.createTextNode(structure) };
32193
32188
  return renderSpec(doc, structure, xmlNS, blockArraysIn);
32194
32189
  }
32195
32190
  /**
@@ -32261,11 +32256,9 @@ so this becomes the fallback color for the slot */ ''}
32261
32256
  return result;
32262
32257
  }
32263
32258
  function renderSpec(doc, structure, xmlNS, blockArraysIn) {
32264
- if (typeof structure == "string")
32265
- return { dom: doc.createTextNode(structure) };
32266
- if (structure.nodeType != null)
32259
+ if (structure.nodeType == 1)
32267
32260
  return { dom: structure };
32268
- if (structure.dom && structure.dom.nodeType != null)
32261
+ if (structure.dom && structure.dom.nodeType == 1)
32269
32262
  return structure;
32270
32263
  let tagName = structure[0], suspicious;
32271
32264
  if (typeof tagName != "string")
@@ -32301,6 +32294,9 @@ so this becomes the fallback color for the slot */ ''}
32301
32294
  throw new RangeError("Content hole must be the only child of its parent node");
32302
32295
  return { dom, contentDOM: dom };
32303
32296
  }
32297
+ else if (typeof child == "string") {
32298
+ dom.appendChild(doc.createTextNode(child));
32299
+ }
32304
32300
  else {
32305
32301
  let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
32306
32302
  dom.appendChild(inner);
@@ -42781,8 +42777,44 @@ so this becomes the fallback color for the slot */ ''}
42781
42777
  }
42782
42778
  return true;
42783
42779
  };
42780
+
42781
+ // src/commands/deleteSelection.ts
42782
+ var hasTextContent = (nodeSpec) => {
42783
+ if (!nodeSpec.content) {
42784
+ return false;
42785
+ }
42786
+ const textRegex = /^text(\*|\+)/;
42787
+ return textRegex.test(nodeSpec.content);
42788
+ };
42789
+ var expandSelectionForSide = ($pos, schema, side) => {
42790
+ if (!$pos.parent.isInline) {
42791
+ return $pos.pos;
42792
+ }
42793
+ if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) {
42794
+ return $pos.pos;
42795
+ }
42796
+ const parentContent = schema.nodes[$pos.parent.type.name].spec;
42797
+ if (!hasTextContent(parentContent)) {
42798
+ return $pos.pos;
42799
+ }
42800
+ return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
42801
+ };
42802
+ var expandSelectionForInlineText = ($from, $to, schema) => {
42803
+ const from = expandSelectionForSide($from, schema, "left");
42804
+ const to = expandSelectionForSide($to, schema, "right");
42805
+ return { from, to };
42806
+ };
42784
42807
  var deleteSelection = () => ({ state, dispatch }) => {
42785
- return deleteSelection$1(state, dispatch);
42808
+ const { $from, $to } = state.selection;
42809
+ if (state.selection.empty) {
42810
+ return false;
42811
+ }
42812
+ const { from, to } = expandSelectionForInlineText($from, $to, state.schema);
42813
+ if (dispatch) {
42814
+ state.tr.deleteRange(from, to).scrollIntoView();
42815
+ dispatch(state.tr);
42816
+ }
42817
+ return true;
42786
42818
  };
42787
42819
 
42788
42820
  // src/commands/enter.ts
@@ -45442,6 +45474,7 @@ so this becomes the fallback color for the slot */ ''}
45442
45474
  });
45443
45475
  extension.name = this.name;
45444
45476
  extension.parent = this.parent;
45477
+ this.child = null;
45445
45478
  return extension;
45446
45479
  }
45447
45480
  extend(extendedConfig = {}) {
@@ -45977,6 +46010,36 @@ so this becomes the fallback color for the slot */ ''}
45977
46010
  })
45978
46011
  );
45979
46012
  }
46013
+ /**
46014
+ * Destroy the extension manager and clean up all extension references
46015
+ * to prevent memory leaks through parent/child extension chains.
46016
+ *
46017
+ * Walks each extension's full parent chain and nulls every forward
46018
+ * `parent.child → current` link where the parent still points to the
46019
+ * current node. This breaks the retention path from module-scope
46020
+ * singleton roots through deep extend() chains.
46021
+ *
46022
+ * Only ancestor `.child` links matching the current chain are cleared.
46023
+ * The `.parent` pointer on ancestors is never touched — extensions
46024
+ * may be shared across live editors, so their own backward references
46025
+ * and non-matching forward links must remain intact.
46026
+ */
46027
+ destroy() {
46028
+ this.extensions.forEach((extension) => {
46029
+ let current = extension;
46030
+ while (current.parent) {
46031
+ const parent = current.parent;
46032
+ if (parent.child === current) {
46033
+ parent.child = null;
46034
+ }
46035
+ current = parent;
46036
+ }
46037
+ });
46038
+ this.extensions = [];
46039
+ this.baseExtensions = [];
46040
+ this.schema = null;
46041
+ this.editor = null;
46042
+ }
45980
46043
  /**
45981
46044
  * Go through all extensions, create extension storages & setup marks
45982
46045
  * & bind editor event listener.
@@ -46390,12 +46453,23 @@ so this becomes the fallback color for the slot */ ''}
46390
46453
  });
46391
46454
  var Tabindex = Extension.create({
46392
46455
  name: "tabindex",
46456
+ addOptions() {
46457
+ return {
46458
+ value: void 0
46459
+ };
46460
+ },
46393
46461
  addProseMirrorPlugins() {
46394
46462
  return [
46395
46463
  new Plugin({
46396
46464
  key: new PluginKey("tabindex"),
46397
46465
  props: {
46398
- attributes: () => this.editor.isEditable ? { tabindex: "0" } : {}
46466
+ attributes: () => {
46467
+ var _a;
46468
+ if (!this.editor.isEditable && this.options.value === void 0) {
46469
+ return {};
46470
+ }
46471
+ return { tabindex: (_a = this.options.value) != null ? _a : "0" };
46472
+ }
46399
46473
  }
46400
46474
  })
46401
46475
  ];
@@ -46734,6 +46808,7 @@ img.ProseMirror-separator {
46734
46808
  this.className = "tiptap";
46735
46809
  this.editorView = null;
46736
46810
  this.isFocused = false;
46811
+ this.destroyed = false;
46737
46812
  /**
46738
46813
  * The editor is considered initialized after the `create` event has been emitted.
46739
46814
  */
@@ -47025,7 +47100,7 @@ img.ProseMirror-separator {
47025
47100
  * Creates an extension manager.
47026
47101
  */
47027
47102
  createExtensionManager() {
47028
- var _a, _b;
47103
+ var _a, _b, _c, _d;
47029
47104
  const coreExtensions = this.options.enableCoreExtensions ? [
47030
47105
  Editable,
47031
47106
  ClipboardTextSerializer.configure({
@@ -47034,7 +47109,9 @@ img.ProseMirror-separator {
47034
47109
  Commands,
47035
47110
  FocusEvents,
47036
47111
  Keymap,
47037
- Tabindex,
47112
+ Tabindex.configure({
47113
+ value: (_d = (_c = this.options.coreExtensionOptions) == null ? void 0 : _c.tabindex) == null ? void 0 : _d.value
47114
+ }),
47038
47115
  Drop,
47039
47116
  Paste,
47040
47117
  Delete,
@@ -47271,9 +47348,18 @@ img.ProseMirror-separator {
47271
47348
  * Destroy the editor.
47272
47349
  */
47273
47350
  destroy() {
47351
+ if (this.destroyed) {
47352
+ return;
47353
+ }
47354
+ this.destroyed = true;
47274
47355
  this.emit("destroy");
47275
47356
  this.unmount();
47276
47357
  this.removeAllListeners();
47358
+ this.extensionManager.destroy();
47359
+ this.extensionManager = null;
47360
+ this.schema = null;
47361
+ this.commandManager = null;
47362
+ this.extensionStorage = {};
47277
47363
  }
47278
47364
  /**
47279
47365
  * Check if the editor is already destroyed.
@@ -47292,7 +47378,8 @@ img.ProseMirror-separator {
47292
47378
  }
47293
47379
  $pos(pos) {
47294
47380
  const $pos = this.state.doc.resolve(pos);
47295
- return new NodePos($pos, this);
47381
+ const node = pos > 0 && $pos.nodeAfter && !$pos.nodeAfter.isText ? $pos.nodeAfter : null;
47382
+ return new NodePos($pos, this, false, node);
47296
47383
  }
47297
47384
  get $doc() {
47298
47385
  return this.$pos(0);
@@ -49890,6 +49977,15 @@ ${indentedChild}`;
49890
49977
  function decodeHTML(str, mode = DecodingMode.Legacy) {
49891
49978
  return htmlDecoder(str, mode);
49892
49979
  }
49980
+ /**
49981
+ * Decodes an HTML string, requiring all entities to be terminated by a semicolon.
49982
+ *
49983
+ * @param str The string to decode.
49984
+ * @returns The decoded string.
49985
+ */
49986
+ function decodeHTMLStrict(str) {
49987
+ return htmlDecoder(str, DecodingMode.Strict);
49988
+ }
49893
49989
 
49894
49990
  // Utilities
49895
49991
  //
@@ -50069,6 +50165,10 @@ ${indentedChild}`;
50069
50165
  return P.test(ch) || regex.test(ch)
50070
50166
  }
50071
50167
 
50168
+ function isPunctCharCode (code) {
50169
+ return isPunctChar(fromCodePoint(code))
50170
+ }
50171
+
50072
50172
  // Markdown ASCII punctuation characters.
50073
50173
  //
50074
50174
  // !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~
@@ -50130,6 +50230,7 @@ ${indentedChild}`;
50130
50230
  // (remove this when node v10 is no longer supported).
50131
50231
  //
50132
50232
  if ('ẞ'.toLowerCase() === 'Ṿ') {
50233
+ /* c8 ignore next 2 */
50133
50234
  str = str.replace(/ẞ/g, 'ß');
50134
50235
  }
50135
50236
 
@@ -50168,6 +50269,28 @@ ${indentedChild}`;
50168
50269
  return str.toLowerCase().toUpperCase()
50169
50270
  }
50170
50271
 
50272
+ function isAsciiTrimmable (c) {
50273
+ return c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d
50274
+ }
50275
+
50276
+ // "Light" .trim() for blocks (headers, paragraphs), where unicode spaces
50277
+ // should be preserved.
50278
+ function asciiTrim (str) {
50279
+ let start = 0;
50280
+ for (; start < str.length; start++) {
50281
+ if (!isAsciiTrimmable(str.charCodeAt(start))) {
50282
+ break
50283
+ }
50284
+ }
50285
+ let end = str.length - 1;
50286
+ for (; end >= start; end--) {
50287
+ if (!isAsciiTrimmable(str.charCodeAt(end))) {
50288
+ break
50289
+ }
50290
+ }
50291
+ return str.slice(start, end + 1)
50292
+ }
50293
+
50171
50294
  // Re-export libraries commonly used in both markdown-it and its plugins,
50172
50295
  // so plugins won't have to depend on them explicitly, which reduces their
50173
50296
  // bundled size (e.g. a browser build).
@@ -50177,6 +50300,7 @@ ${indentedChild}`;
50177
50300
  var utils = /*#__PURE__*/Object.freeze({
50178
50301
  __proto__: null,
50179
50302
  arrayReplaceAt: arrayReplaceAt,
50303
+ asciiTrim: asciiTrim,
50180
50304
  assign: assign$1,
50181
50305
  escapeHtml: escapeHtml,
50182
50306
  escapeRE: escapeRE$1,
@@ -50184,6 +50308,7 @@ ${indentedChild}`;
50184
50308
  has: has,
50185
50309
  isMdAsciiPunct: isMdAsciiPunct,
50186
50310
  isPunctChar: isPunctChar,
50311
+ isPunctCharCode: isPunctCharCode,
50187
50312
  isSpace: isSpace,
50188
50313
  isString: isString$1,
50189
50314
  isValidEntityCode: isValidEntityCode,
@@ -51547,14 +51672,36 @@ ${indentedChild}`;
51547
51672
  const QUOTE_RE = /['"]/g;
51548
51673
  const APOSTROPHE$1 = '\u2019'; /* ’ */
51549
51674
 
51550
- function replaceAt (str, index, ch) {
51551
- return str.slice(0, index) + ch + str.slice(index + 1)
51675
+ function addReplacement (replacements, tokenIdx, pos, ch) {
51676
+ if (!replacements[tokenIdx]) {
51677
+ replacements[tokenIdx] = [];
51678
+ }
51679
+
51680
+ replacements[tokenIdx].push({ pos, ch });
51681
+ }
51682
+
51683
+ function applyReplacements (str, replacements) {
51684
+ let result = '';
51685
+ let lastPos = 0;
51686
+
51687
+ replacements.sort((a, b) => a.pos - b.pos);
51688
+
51689
+ for (let i = 0; i < replacements.length; i++) {
51690
+ const replacement = replacements[i];
51691
+
51692
+ result += str.slice(lastPos, replacement.pos) + replacement.ch;
51693
+ lastPos = replacement.pos + 1;
51694
+ }
51695
+
51696
+ return result + str.slice(lastPos)
51552
51697
  }
51553
51698
 
51554
51699
  function process_inlines (tokens, state) {
51555
51700
  let j;
51556
51701
 
51557
51702
  const stack = [];
51703
+ // token index -> list of replacements in the original token content
51704
+ const replacements = {};
51558
51705
 
51559
51706
  for (let i = 0; i < tokens.length; i++) {
51560
51707
  const token = tokens[i];
@@ -51568,9 +51715,9 @@ ${indentedChild}`;
51568
51715
 
51569
51716
  if (token.type !== 'text') { continue }
51570
51717
 
51571
- let text = token.content;
51718
+ const text = token.content;
51572
51719
  let pos = 0;
51573
- let max = text.length;
51720
+ const max = text.length;
51574
51721
 
51575
51722
  /* eslint no-labels:0,block-scoped-var:0 */
51576
51723
  OUTER:
@@ -51618,8 +51765,8 @@ ${indentedChild}`;
51618
51765
  }
51619
51766
  }
51620
51767
 
51621
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
51622
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
51768
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
51769
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
51623
51770
 
51624
51771
  const isLastWhiteSpace = isWhiteSpace(lastChar);
51625
51772
  const isNextWhiteSpace = isWhiteSpace(nextChar);
@@ -51662,7 +51809,7 @@ ${indentedChild}`;
51662
51809
  if (!canOpen && !canClose) {
51663
51810
  // middle of word
51664
51811
  if (isSingle) {
51665
- token.content = replaceAt(token.content, t.index, APOSTROPHE$1);
51812
+ addReplacement(replacements, i, t.index, APOSTROPHE$1);
51666
51813
  }
51667
51814
  continue
51668
51815
  }
@@ -51685,18 +51832,8 @@ ${indentedChild}`;
51685
51832
  closeQuote = state.md.options.quotes[1];
51686
51833
  }
51687
51834
 
51688
- // replace token.content *before* tokens[item.token].content,
51689
- // because, if they are pointing at the same token, replaceAt
51690
- // could mess up indices when quote length != 1
51691
- token.content = replaceAt(token.content, t.index, closeQuote);
51692
- tokens[item.token].content = replaceAt(
51693
- tokens[item.token].content, item.pos, openQuote);
51694
-
51695
- pos += closeQuote.length - 1;
51696
- if (item.token === i) { pos += openQuote.length - 1; }
51697
-
51698
- text = token.content;
51699
- max = text.length;
51835
+ addReplacement(replacements, i, t.index, closeQuote);
51836
+ addReplacement(replacements, item.token, item.pos, openQuote);
51700
51837
 
51701
51838
  stack.length = j;
51702
51839
  continue OUTER
@@ -51712,10 +51849,14 @@ ${indentedChild}`;
51712
51849
  level: thisLevel
51713
51850
  });
51714
51851
  } else if (canClose && isSingle) {
51715
- token.content = replaceAt(token.content, t.index, APOSTROPHE$1);
51852
+ addReplacement(replacements, i, t.index, APOSTROPHE$1);
51716
51853
  }
51717
51854
  }
51718
51855
  }
51856
+
51857
+ Object.keys(replacements).forEach(function (tokenIdx) {
51858
+ tokens[tokenIdx].content = applyReplacements(tokens[tokenIdx].content, replacements[tokenIdx]);
51859
+ });
51719
51860
  }
51720
51861
 
51721
51862
  function smartquotes (state) {
@@ -53319,11 +53460,22 @@ ${indentedChild}`;
53319
53460
 
53320
53461
  let nextLine = startLine + 1;
53321
53462
 
53463
+ // Block types 6 and 7 (the only ones whose end condition is a blank line)
53464
+ // have `/^$/` as their closing regexp. For all other types (1-5, e.g.
53465
+ // `<!--` comments), a blank line is regular content and must not terminate
53466
+ // the block - it ends only when its closing sequence is found.
53467
+ const endsOnBlankLine = HTML_SEQUENCES[i][1].test('');
53468
+
53322
53469
  // If we are here - we detected HTML block.
53323
53470
  // Let's roll down till block end.
53324
53471
  if (!HTML_SEQUENCES[i][1].test(lineText)) {
53325
53472
  for (; nextLine < endLine; nextLine++) {
53326
- if (state.sCount[nextLine] < state.blkIndent) { break }
53473
+ if (state.sCount[nextLine] < state.blkIndent) {
53474
+ // An outdented blank line shouldn't end a block that doesn't end on a
53475
+ // blank line (e.g. a `<!--` comment inside a list item). Such blocks
53476
+ // must continue until their closing sequence regardless of indent.
53477
+ if (endsOnBlankLine || !state.isEmpty(nextLine)) { break }
53478
+ }
53327
53479
 
53328
53480
  pos = state.bMarks[nextLine] + state.tShift[nextLine];
53329
53481
  max = state.eMarks[nextLine];
@@ -53386,7 +53538,7 @@ ${indentedChild}`;
53386
53538
  token_o.map = [startLine, state.line];
53387
53539
 
53388
53540
  const token_i = state.push('inline', '', 0);
53389
- token_i.content = state.src.slice(pos, max).trim();
53541
+ token_i.content = asciiTrim(state.src.slice(pos, max));
53390
53542
  token_i.map = [startLine, state.line];
53391
53543
  token_i.children = [];
53392
53544
 
@@ -53398,6 +53550,7 @@ ${indentedChild}`;
53398
53550
 
53399
53551
  // lheading (---, ===)
53400
53552
 
53553
+
53401
53554
  function lheading (state, startLine, endLine/*, silent */) {
53402
53555
  const terminatorRules = state.md.block.ruler.getRules('paragraph');
53403
53556
 
@@ -53455,10 +53608,11 @@ ${indentedChild}`;
53455
53608
 
53456
53609
  if (!level) {
53457
53610
  // Didn't find valid underline
53611
+ state.parentType = oldParentType;
53458
53612
  return false
53459
53613
  }
53460
53614
 
53461
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
53615
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
53462
53616
 
53463
53617
  state.line = nextLine + 1;
53464
53618
 
@@ -53481,6 +53635,7 @@ ${indentedChild}`;
53481
53635
 
53482
53636
  // Paragraph
53483
53637
 
53638
+
53484
53639
  function paragraph (state, startLine, endLine) {
53485
53640
  const terminatorRules = state.md.block.ruler.getRules('paragraph');
53486
53641
  const oldParentType = state.parentType;
@@ -53507,7 +53662,7 @@ ${indentedChild}`;
53507
53662
  if (terminate) { break }
53508
53663
  }
53509
53664
 
53510
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
53665
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
53511
53666
 
53512
53667
  state.line = nextLine;
53513
53668
 
@@ -53734,8 +53889,30 @@ ${indentedChild}`;
53734
53889
  const max = this.posMax;
53735
53890
  const marker = this.src.charCodeAt(start);
53736
53891
 
53737
- // treat beginning of the line as a whitespace
53738
- const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20;
53892
+ // Astral characters below are combined manually, because .codePointAt()
53893
+ // does not guarantee numeric type output. And we don't wish JIT cache issues.
53894
+ // The broken surrogate pairs are evaluated as U+FFFD to prevent possible
53895
+ // crashes.
53896
+
53897
+ let lastChar;
53898
+ if (start === 0) {
53899
+ // treat beginning of the line as a whitespace
53900
+ lastChar = 0x20;
53901
+ } else if (start === 1) {
53902
+ lastChar = this.src.charCodeAt(0);
53903
+ if ((lastChar & 0xF800) === 0xD800) { lastChar = 0xFFFD; }
53904
+ } else {
53905
+ lastChar = this.src.charCodeAt(start - 1);
53906
+ if ((lastChar & 0xFC00) === 0xDC00) {
53907
+ // low surrogate => add high one, replace broken pair with U+FFFD
53908
+ const highSurr = this.src.charCodeAt(start - 2);
53909
+ lastChar = (highSurr & 0xFC00) === 0xD800
53910
+ ? 0x10000 + ((highSurr - 0xD800) << 10) + (lastChar - 0xDC00)
53911
+ : 0xFFFD;
53912
+ } else if ((lastChar & 0xFC00) === 0xD800) {
53913
+ lastChar = 0xFFFD;
53914
+ }
53915
+ }
53739
53916
 
53740
53917
  let pos = start;
53741
53918
  while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }
@@ -53743,10 +53920,19 @@ ${indentedChild}`;
53743
53920
  const count = pos - start;
53744
53921
 
53745
53922
  // treat end of the line as a whitespace
53746
- const nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
53923
+ let nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
53924
+ if ((nextChar & 0xFC00) === 0xD800) {
53925
+ // high surrogate => add low one, replace broken pair with U+FFFD
53926
+ const lowSurr = this.src.charCodeAt(pos + 1);
53927
+ nextChar = (lowSurr & 0xFC00) === 0xDC00
53928
+ ? 0x10000 + ((nextChar - 0xD800) << 10) + (lowSurr - 0xDC00)
53929
+ : 0xFFFD;
53930
+ } else if ((nextChar & 0xFC00) === 0xDC00) {
53931
+ nextChar = 0xFFFD;
53932
+ }
53747
53933
 
53748
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
53749
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
53934
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
53935
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
53750
53936
 
53751
53937
  const isLastWhiteSpace = isWhiteSpace(lastChar);
53752
53938
  const isNextWhiteSpace = isWhiteSpace(nextChar);
@@ -54773,7 +54959,7 @@ ${indentedChild}`;
54773
54959
  } else {
54774
54960
  const match = state.src.slice(pos).match(NAMED_RE);
54775
54961
  if (match) {
54776
- const decoded = decodeHTML(match[0]);
54962
+ const decoded = decodeHTMLStrict(match[0]);
54777
54963
  if (decoded !== match[0]) {
54778
54964
  if (!silent) {
54779
54965
  const token = state.push('text_special', '', 0);
@@ -55435,11 +55621,6 @@ ${indentedChild}`;
55435
55621
  // DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead
55436
55622
  const tlds_default = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
55437
55623
 
55438
- function resetScanCache (self) {
55439
- self.__index__ = -1;
55440
- self.__text_cache__ = '';
55441
- }
55442
-
55443
55624
  function createValidator (re) {
55444
55625
  return function (text, pos) {
55445
55626
  const tail = text.slice(pos);
@@ -55478,8 +55659,11 @@ ${indentedChild}`;
55478
55659
  function untpl (tpl) { return tpl.replace('%TLDS%', re.src_tlds) }
55479
55660
 
55480
55661
  re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), 'i');
55662
+ re.email_fuzzy_global = RegExp(untpl(re.tpl_email_fuzzy), 'ig');
55481
55663
  re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), 'i');
55664
+ re.link_fuzzy_global = RegExp(untpl(re.tpl_link_fuzzy), 'ig');
55482
55665
  re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'i');
55666
+ re.link_no_ip_fuzzy_global = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'ig');
55483
55667
  re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), 'i');
55484
55668
 
55485
55669
  //
@@ -55573,12 +55757,6 @@ ${indentedChild}`;
55573
55757
  '(' + self.re.schema_test.source + ')|(' + self.re.host_fuzzy_test.source + ')|@',
55574
55758
  'i'
55575
55759
  );
55576
-
55577
- //
55578
- // Cleanup
55579
- //
55580
-
55581
- resetScanCache(self);
55582
55760
  }
55583
55761
 
55584
55762
  /**
@@ -55586,55 +55764,45 @@ ${indentedChild}`;
55586
55764
  *
55587
55765
  * Match result. Single element of array, returned by [[LinkifyIt#match]]
55588
55766
  **/
55589
- function Match (self, shift) {
55590
- const start = self.__index__;
55591
- const end = self.__last_index__;
55592
- const text = self.__text_cache__.slice(start, end);
55767
+ function Match (text, schema, index, lastIndex) {
55768
+ const raw = text.slice(index, lastIndex);
55593
55769
 
55594
55770
  /**
55595
55771
  * Match#schema -> String
55596
55772
  *
55597
55773
  * Prefix (protocol) for matched string.
55598
55774
  **/
55599
- this.schema = self.__schema__.toLowerCase();
55775
+ this.schema = schema.toLowerCase();
55600
55776
  /**
55601
55777
  * Match#index -> Number
55602
55778
  *
55603
55779
  * First position of matched string.
55604
55780
  **/
55605
- this.index = start + shift;
55781
+ this.index = index;
55606
55782
  /**
55607
55783
  * Match#lastIndex -> Number
55608
55784
  *
55609
55785
  * Next position after matched string.
55610
55786
  **/
55611
- this.lastIndex = end + shift;
55787
+ this.lastIndex = lastIndex;
55612
55788
  /**
55613
55789
  * Match#raw -> String
55614
55790
  *
55615
55791
  * Matched string.
55616
55792
  **/
55617
- this.raw = text;
55793
+ this.raw = raw;
55618
55794
  /**
55619
55795
  * Match#text -> String
55620
55796
  *
55621
55797
  * Notmalized text of matched string.
55622
55798
  **/
55623
- this.text = text;
55799
+ this.text = raw;
55624
55800
  /**
55625
55801
  * Match#url -> String
55626
55802
  *
55627
55803
  * Normalized url of matched string.
55628
55804
  **/
55629
- this.url = text;
55630
- }
55631
-
55632
- function createMatch (self, shift) {
55633
- const match = new Match(self, shift);
55634
-
55635
- self.__compiled__[match.schema].normalize(match, self);
55636
-
55637
- return match
55805
+ this.url = raw;
55638
55806
  }
55639
55807
 
55640
55808
  /**
@@ -55689,12 +55857,6 @@ ${indentedChild}`;
55689
55857
 
55690
55858
  this.__opts__ = assign({}, defaultOptions, options);
55691
55859
 
55692
- // Cache last tested result. Used to skip repeating steps on next `match` call.
55693
- this.__index__ = -1;
55694
- this.__last_index__ = -1; // Next scan position
55695
- this.__schema__ = '';
55696
- this.__text_cache__ = '';
55697
-
55698
55860
  this.__schemas__ = assign({}, defaultSchemas, schemas);
55699
55861
  this.__compiled__ = {};
55700
55862
 
@@ -55736,69 +55898,38 @@ ${indentedChild}`;
55736
55898
  * Searches linkifiable pattern and returns `true` on success or `false` on fail.
55737
55899
  **/
55738
55900
  LinkifyIt.prototype.test = function test (text) {
55739
- // Reset scan cache
55740
- this.__text_cache__ = text;
55741
- this.__index__ = -1;
55742
-
55743
55901
  if (!text.length) { return false }
55744
55902
 
55745
- let m, ml, me, len, shift, next, re, tld_pos, at_pos;
55903
+ let m, re;
55746
55904
 
55747
55905
  // try to scan for link with schema - that's the most simple rule
55748
55906
  if (this.re.schema_test.test(text)) {
55749
55907
  re = this.re.schema_search;
55750
55908
  re.lastIndex = 0;
55751
55909
  while ((m = re.exec(text)) !== null) {
55752
- len = this.testSchemaAt(text, m[2], re.lastIndex);
55753
- if (len) {
55754
- this.__schema__ = m[2];
55755
- this.__index__ = m.index + m[1].length;
55756
- this.__last_index__ = m.index + m[0].length + len;
55757
- break
55758
- }
55910
+ if (this.testSchemaAt(text, m[2], re.lastIndex)) { return true }
55759
55911
  }
55760
55912
  }
55761
55913
 
55762
55914
  if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {
55763
55915
  // guess schemaless links
55764
- tld_pos = text.search(this.re.host_fuzzy_test);
55765
- if (tld_pos >= 0) {
55766
- // if tld is located after found link - no need to check fuzzy pattern
55767
- if (this.__index__ < 0 || tld_pos < this.__index__) {
55768
- if ((ml = text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) {
55769
- shift = ml.index + ml[1].length;
55770
-
55771
- if (this.__index__ < 0 || shift < this.__index__) {
55772
- this.__schema__ = '';
55773
- this.__index__ = shift;
55774
- this.__last_index__ = ml.index + ml[0].length;
55775
- }
55776
- }
55916
+ if (text.search(this.re.host_fuzzy_test) >= 0) {
55917
+ if (text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy) !== null) {
55918
+ return true
55777
55919
  }
55778
55920
  }
55779
55921
  }
55780
55922
 
55781
55923
  if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {
55782
55924
  // guess schemaless emails
55783
- at_pos = text.indexOf('@');
55784
- if (at_pos >= 0) {
55925
+ if (text.indexOf('@') >= 0) {
55785
55926
  // We can't skip this check, because this cases are possible:
55786
55927
  // 192.168.1.1@gmail.com, my.in@example.com
55787
- if ((me = text.match(this.re.email_fuzzy)) !== null) {
55788
- shift = me.index + me[1].length;
55789
- next = me.index + me[0].length;
55790
-
55791
- if (this.__index__ < 0 || shift < this.__index__ ||
55792
- (shift === this.__index__ && next > this.__last_index__)) {
55793
- this.__schema__ = 'mailto:';
55794
- this.__index__ = shift;
55795
- this.__last_index__ = next;
55796
- }
55797
- }
55928
+ if (text.match(this.re.email_fuzzy) !== null) { return true }
55798
55929
  }
55799
55930
  }
55800
55931
 
55801
- return this.__index__ >= 0
55932
+ return false
55802
55933
  };
55803
55934
 
55804
55935
  /**
@@ -55847,23 +55978,88 @@ ${indentedChild}`;
55847
55978
  **/
55848
55979
  LinkifyIt.prototype.match = function match (text) {
55849
55980
  const result = [];
55850
- let shift = 0;
55981
+ const type_schemed = [];
55982
+ const type_fuzzy_link = [];
55983
+ const type_fuzzy_email = [];
55984
+ let m, len, re;
55851
55985
 
55852
- // Try to take previous element from cache, if .test() called before
55853
- if (this.__index__ >= 0 && this.__text_cache__ === text) {
55854
- result.push(createMatch(this, shift));
55855
- shift = this.__last_index__;
55986
+ function choose (a, b) {
55987
+ if (!a) { return b }
55988
+ if (!b) { return a }
55989
+ if (a.index !== b.index) { return a.index < b.index ? a : b }
55990
+ return a.lastIndex >= b.lastIndex ? a : b
55856
55991
  }
55857
55992
 
55858
- // Cut head if cache was used
55859
- let tail = shift ? text.slice(shift) : text;
55993
+ if (!text.length) { return null }
55860
55994
 
55861
- // Scan string until end reached
55862
- while (this.test(tail)) {
55863
- result.push(createMatch(this, shift));
55995
+ // scan for links with schema
55996
+ if (this.re.schema_test.test(text)) {
55997
+ re = this.re.schema_search;
55998
+ re.lastIndex = 0;
55999
+ while ((m = re.exec(text)) !== null) {
56000
+ len = this.testSchemaAt(text, m[2], re.lastIndex);
56001
+ if (len) {
56002
+ type_schemed.push({
56003
+ schema: m[2],
56004
+ index: m.index + m[1].length,
56005
+ lastIndex: m.index + m[0].length + len
56006
+ });
56007
+ }
56008
+ }
56009
+ }
55864
56010
 
55865
- tail = tail.slice(this.__last_index__);
55866
- shift += this.__last_index__;
56011
+ if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {
56012
+ re = this.__opts__.fuzzyIP ? this.re.link_fuzzy_global : this.re.link_no_ip_fuzzy_global;
56013
+ re.lastIndex = 0;
56014
+ while ((m = re.exec(text)) !== null) {
56015
+ type_fuzzy_link.push({
56016
+ schema: '',
56017
+ index: m.index + m[1].length,
56018
+ lastIndex: m.index + m[0].length
56019
+ });
56020
+ }
56021
+ }
56022
+
56023
+ if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {
56024
+ re = this.re.email_fuzzy_global;
56025
+ re.lastIndex = 0;
56026
+ while ((m = re.exec(text)) !== null) {
56027
+ type_fuzzy_email.push({
56028
+ schema: 'mailto:',
56029
+ index: m.index + m[1].length,
56030
+ lastIndex: m.index + m[0].length
56031
+ });
56032
+ }
56033
+ }
56034
+
56035
+ const indexes = [0, 0, 0];
56036
+ let lastIndex = 0;
56037
+
56038
+ for (;;) {
56039
+ const candidates = [
56040
+ type_schemed[indexes[0]],
56041
+ type_fuzzy_email[indexes[1]],
56042
+ type_fuzzy_link[indexes[2]]
56043
+ ];
56044
+
56045
+ const candidate = choose(choose(candidates[0], candidates[1]), candidates[2]);
56046
+
56047
+ if (!candidate) { break }
56048
+
56049
+ if (candidate === candidates[0]) {
56050
+ indexes[0]++;
56051
+ } else if (candidate === candidates[1]) {
56052
+ indexes[1]++;
56053
+ } else {
56054
+ indexes[2]++;
56055
+ }
56056
+
56057
+ if (candidate.index < lastIndex) { continue }
56058
+
56059
+ const match = new Match(text, candidate.schema, candidate.index, candidate.lastIndex);
56060
+ this.__compiled__[match.schema].normalize(match, this);
56061
+ result.push(match);
56062
+ lastIndex = candidate.lastIndex;
55867
56063
  }
55868
56064
 
55869
56065
  if (result.length) {
@@ -55880,10 +56076,6 @@ ${indentedChild}`;
55880
56076
  * of the string, and null otherwise.
55881
56077
  **/
55882
56078
  LinkifyIt.prototype.matchAtStart = function matchAtStart (text) {
55883
- // Reset scan cache
55884
- this.__text_cache__ = text;
55885
- this.__index__ = -1;
55886
-
55887
56079
  if (!text.length) return null
55888
56080
 
55889
56081
  const m = this.re.schema_at_start.exec(text);
@@ -55892,11 +56084,10 @@ ${indentedChild}`;
55892
56084
  const len = this.testSchemaAt(text, m[2], m[0].length);
55893
56085
  if (!len) return null
55894
56086
 
55895
- this.__schema__ = m[2];
55896
- this.__index__ = m.index + m[1].length;
55897
- this.__last_index__ = m.index + m[0].length + len;
56087
+ const match = new Match(text, m[2], m.index + m[1].length, m.index + m[0].length + len);
55898
56088
 
55899
- return createMatch(this, 0)
56089
+ this.__compiled__[match.schema].normalize(match, this);
56090
+ return match
55900
56091
  };
55901
56092
 
55902
56093
  /** chainable
@@ -56948,7 +57139,7 @@ ${indentedChild}`;
56948
57139
  * ```javascript
56949
57140
  * var md = require('markdown-it')()
56950
57141
  * .set({ html: true, breaks: true })
56951
- * .set({ typographer, true });
57142
+ * .set({ typographer: true });
56952
57143
  * ```
56953
57144
  *
56954
57145
  * __Note:__ To achieve the best possible performance, don't modify a
@@ -58896,7 +59087,7 @@ ${indentedChild}`;
58896
59087
  // THIS FILE IS AUTOMATICALLY GENERATED DO NOT EDIT DIRECTLY
58897
59088
  // See update-tlds.js for encoding/decoding format
58898
59089
  // https://data.iana.org/TLD/tlds-alpha-by-domain.txt
58899
- const encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';
59090
+ const encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2odyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rck0msd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2oodside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';
58900
59091
  // Internationalized domain names containing non-ASCII
58901
59092
  const encodedUtlds = 'ελ1υ2бг1ел3дети4ею2католик6ом3мкд2он1сква6онлайн5рг3рус2ф2сайт3рб3укр3қаз3հայ3ישראל5קום3ابوظبي5رامكو5لاردن4بحرين5جزائر5سعودية6عليان5مغرب5مارات5یران5بارت2زار4يتك3ھارت5تونس4سودان3رية5شبكة4عراق2ب2مان4فلسطين6قطر3كاثوليك6وم3مصر2ليسيا5وريتانيا7قع4همراه5پاکستان7ڀارت4कॉम3नेट3भारत0म्3ोत5संगठन5বাংলা5ভারত2ৰত4ਭਾਰਤ4ભારત4ଭାରତ4இந்தியா6லங்கை6சிங்கப்பூர்11భారత్5ಭಾರತ4ഭാരതം5ලංකා4คอม3ไทย3ລາວ3გე2みんな3アマゾン4クラウド4グーグル4コム2ストア3セール3ファッション6ポイント4世界2中信1国1國1文网3亚马逊3企业2佛山2信息2健康2八卦2公司1益2台湾1灣2商城1店1标2嘉里0大酒店5在线2大拿2天主教3娱乐2家電2广东2微博2慈善2我爱你3手机2招聘2政务1府2新加坡2闻2时尚2書籍2机构2淡马锡3游戏2澳門2点看2移动2组织机构4网址1店1站1络2联通2谷歌2购物2通販2集团2電訊盈科4飞利浦3食品2餐厅2香格里拉3港2닷넷1컴2삼성2한국2';
58902
59093
 
@@ -60288,11 +60479,6 @@ ${indentedChild}`;
60288
60479
  tt(Email$1, DOT, EmailDomainDot);
60289
60480
  tt(Email$1, HYPHEN, EmailDomainHyphen);
60290
60481
 
60291
- // Final possible email states
60292
- const EmailColon = tt(Email$1, COLON); // URL followed by colon (potential port number here)
60293
- /*const EmailColonPort = */
60294
- ta(EmailColon, groups.numeric, Email); // URL followed by colon and port number
60295
-
60296
60482
  // Account for dots and hyphens. Hyphens are usually parts of domain names
60297
60483
  // (but not TLDs)
60298
60484
  const DomainHyphen = tt(Domain, HYPHEN); // domain followed by hyphen
@@ -60375,16 +60561,18 @@ ${indentedChild}`;
60375
60561
  // Continue not accepting for open brackets
60376
60562
  tt(UrlNonaccept, OPEN, UrlOpen);
60377
60563
 
60378
- // Closing bracket component. This character WILL be included in the URL
60379
- tt(UrlOpen, CLOSE, Url$1);
60380
-
60381
- // URL that beings with an opening bracket, followed by a symbols.
60564
+ // URL that begins with an opening bracket, followed by a symbols.
60382
60565
  // Note that the final state can still be `UrlOpen` (if the URL has a
60383
60566
  // single opening bracket for some reason).
60384
60567
  const UrlOpenQ = makeState(Url);
60385
60568
  ta(UrlOpen, qsAccepting, UrlOpenQ);
60386
60569
  const UrlOpenSyms = makeState(); // UrlOpen followed by some symbols it cannot end it
60387
- ta(UrlOpen, qsNonAccepting);
60570
+ ta(UrlOpen, qsNonAccepting, UrlOpenSyms);
60571
+
60572
+ // Closing bracket component. This character WILL be included in the URL.
60573
+ // Must come after qsNonAccepting (which includes all close-bracket tokens)
60574
+ // so that CLOSE -> Url wins over CLOSE -> UrlOpenSyms.
60575
+ tt(UrlOpen, CLOSE, Url$1);
60388
60576
 
60389
60577
  // URL that begins with an opening bracket, followed by some symbols
60390
60578
  ta(UrlOpenQ, qsAccepting, UrlOpenQ);
@@ -61138,6 +61326,25 @@ ${indentedChild}`;
61138
61326
  return [inputRule];
61139
61327
  }
61140
61328
  });
61329
+ function isSameLineOrderedListToken(token) {
61330
+ var _a, _b;
61331
+ const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0];
61332
+ return Boolean(
61333
+ token.text && ((_b = token.tokens) == null ? void 0 : _b.length) === 1 && (nestedToken == null ? void 0 : nestedToken.type) === "list" && nestedToken.ordered && nestedToken.raw === token.text
61334
+ );
61335
+ }
61336
+ function parseSameLineOrderedListText(text, helpers) {
61337
+ if (helpers.tokenizeInline) {
61338
+ return helpers.parseInline(helpers.tokenizeInline(text));
61339
+ }
61340
+ return helpers.parseInline([
61341
+ {
61342
+ type: "text",
61343
+ raw: text,
61344
+ text
61345
+ }
61346
+ ]);
61347
+ }
61141
61348
  var ListItem = Node3.create({
61142
61349
  name: "listItem",
61143
61350
  addOptions() {
@@ -61168,6 +61375,17 @@ ${indentedChild}`;
61168
61375
  const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
61169
61376
  let content = [];
61170
61377
  if (token.tokens && token.tokens.length > 0) {
61378
+ if (isSameLineOrderedListToken(token)) {
61379
+ return {
61380
+ type: "listItem",
61381
+ content: [
61382
+ {
61383
+ type: "paragraph",
61384
+ content: parseSameLineOrderedListText(token.text || "", helpers)
61385
+ }
61386
+ ]
61387
+ };
61388
+ }
61171
61389
  const hasParagraphTokens = token.tokens.some((t) => t.type === "paragraph");
61172
61390
  if (hasParagraphTokens) {
61173
61391
  content = parseBlockChildren(token.tokens);
@@ -63811,6 +64029,7 @@ ${indentedChild}`;
63811
64029
  addOptions() {
63812
64030
  return {
63813
64031
  limit: null,
64032
+ autoTrim: true,
63814
64033
  mode: "textSize",
63815
64034
  textCounter: (text) => text.length,
63816
64035
  wordCounter: (text) => text.split(" ").filter((word) => word !== "").length
@@ -63848,7 +64067,8 @@ ${indentedChild}`;
63848
64067
  return;
63849
64068
  }
63850
64069
  const limit = this.options.limit;
63851
- if (limit === null || limit === void 0 || limit === 0) {
64070
+ const autoTrim = this.options.autoTrim;
64071
+ if (limit === null || limit === void 0 || limit === 0 || autoTrim === false) {
63852
64072
  initialEvaluationDone = true;
63853
64073
  return;
63854
64074
  }
@@ -63991,10 +64211,114 @@ ${indentedChild}`;
63991
64211
  };
63992
64212
  }
63993
64213
  });
64214
+ function createPlaceholderDecoration(options) {
64215
+ const {
64216
+ editor,
64217
+ placeholder,
64218
+ dataAttribute,
64219
+ pos,
64220
+ node,
64221
+ isEmptyDoc,
64222
+ hasAnchor,
64223
+ classes: { emptyNode, emptyEditor }
64224
+ } = options;
64225
+ const classes = [emptyNode];
64226
+ if (isEmptyDoc) {
64227
+ classes.push(emptyEditor);
64228
+ }
64229
+ return Decoration.node(pos, pos + node.nodeSize, {
64230
+ class: classes.join(" "),
64231
+ [dataAttribute]: typeof placeholder === "function" ? placeholder({
64232
+ editor,
64233
+ node,
64234
+ pos,
64235
+ hasAnchor
64236
+ }) : placeholder
64237
+ });
64238
+ }
64239
+
64240
+ // src/placeholder/utils/findScrollParent.ts
64241
+ function isScrollable(el) {
64242
+ const style = getComputedStyle(el);
64243
+ const overflow = `${style.overflow} ${style.overflowY} ${style.overflowX}`;
64244
+ return /auto|scroll|overlay/.test(overflow);
64245
+ }
64246
+ function findScrollParent(element) {
64247
+ let el = element;
64248
+ while (el) {
64249
+ if (isScrollable(el)) {
64250
+ return el;
64251
+ }
64252
+ const parent = el.parentElement;
64253
+ if (!parent) {
64254
+ const root = el.getRootNode();
64255
+ if (root instanceof ShadowRoot) {
64256
+ el = root.host;
64257
+ continue;
64258
+ }
64259
+ return window;
64260
+ }
64261
+ el = parent;
64262
+ }
64263
+ return window;
64264
+ }
64265
+
64266
+ // src/placeholder/utils/getViewportBoundaryPositions.ts
64267
+ function getContainerRect(container) {
64268
+ if (container === window) {
64269
+ return { top: 0, bottom: window.innerHeight };
64270
+ }
64271
+ return container.getBoundingClientRect();
64272
+ }
64273
+ function getViewportBoundaryPositions({
64274
+ doc,
64275
+ view,
64276
+ scrollContainer
64277
+ }) {
64278
+ const editorRect = view.dom.getBoundingClientRect();
64279
+ const containerRect = scrollContainer ? getContainerRect(scrollContainer) : { top: 0, bottom: window.innerHeight };
64280
+ const visibleTop = Math.max(editorRect.top, containerRect.top);
64281
+ const visibleBottom = Math.min(editorRect.bottom, containerRect.bottom);
64282
+ if (visibleTop >= visibleBottom) {
64283
+ return { top: 0, bottom: doc.content.size };
64284
+ }
64285
+ const isRTL = getComputedStyle(view.dom).direction === "rtl";
64286
+ const x = isRTL ? Math.max(editorRect.right - 2, editorRect.left + 2) : editorRect.left + 2;
64287
+ const topPos = view.posAtCoords({ left: x, top: visibleTop + 2 });
64288
+ const bottomPos = view.posAtCoords({ left: x, top: visibleBottom - 2 });
64289
+ return {
64290
+ top: topPos ? topPos.pos : 0,
64291
+ bottom: bottomPos ? bottomPos.pos : doc.content.size
64292
+ };
64293
+ }
64294
+
64295
+ // src/placeholder/utils/throttle.ts
64296
+ function throttle(fn, delay) {
64297
+ let timer = null;
64298
+ const call = ((...args) => {
64299
+ if (timer) {
64300
+ return;
64301
+ }
64302
+ fn(...args);
64303
+ timer = setTimeout(() => {
64304
+ timer = null;
64305
+ }, delay);
64306
+ });
64307
+ const cancel = () => {
64308
+ if (timer) {
64309
+ clearTimeout(timer);
64310
+ timer = null;
64311
+ }
64312
+ };
64313
+ return { call, cancel };
64314
+ }
64315
+
64316
+ // src/placeholder/placeholder.ts
63994
64317
  var DEFAULT_DATA_ATTRIBUTE = "placeholder";
63995
64318
  function preparePlaceholderAttribute(attr) {
63996
64319
  return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase();
63997
64320
  }
64321
+ var PLUGIN_KEY = new PluginKey("tiptap__placeholder");
63998
64322
  var Placeholder = Extension.create({
63999
64323
  name: "placeholder",
64000
64324
  addOptions() {
@@ -64012,40 +64336,124 @@ ${indentedChild}`;
64012
64336
  const dataAttribute = this.options.dataAttribute ? `data-${preparePlaceholderAttribute(this.options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;
64013
64337
  return [
64014
64338
  new Plugin({
64015
- key: new PluginKey("placeholder"),
64339
+ state: {
64340
+ init() {
64341
+ return {
64342
+ // null means "no viewport info yet" — decoration callback falls
64343
+ // back to full document scan until the scroll handler fires.
64344
+ topPos: null,
64345
+ bottomPos: null
64346
+ };
64347
+ },
64348
+ apply(tr, prev) {
64349
+ const meta = tr.getMeta(PLUGIN_KEY);
64350
+ if (meta == null ? void 0 : meta.positions) {
64351
+ return {
64352
+ topPos: meta.positions.top,
64353
+ bottomPos: meta.positions.bottom
64354
+ };
64355
+ }
64356
+ if (!tr.docChanged) {
64357
+ return prev;
64358
+ }
64359
+ return {
64360
+ topPos: prev.topPos !== null ? tr.mapping.map(prev.topPos) : null,
64361
+ bottomPos: prev.bottomPos !== null ? tr.mapping.map(prev.bottomPos) : null
64362
+ };
64363
+ }
64364
+ },
64365
+ key: PLUGIN_KEY,
64366
+ view(view) {
64367
+ const scrollContainer = findScrollParent(view.dom);
64368
+ const computeAndDispatch = () => {
64369
+ const positions = getViewportBoundaryPositions({
64370
+ view,
64371
+ doc: view.state.doc,
64372
+ scrollContainer
64373
+ });
64374
+ const prev = PLUGIN_KEY.getState(view.state);
64375
+ if (prev.topPos === positions.top && prev.bottomPos === positions.bottom) {
64376
+ return;
64377
+ }
64378
+ const tr = view.state.tr.setMeta(PLUGIN_KEY, { positions }).setMeta("tiptap__viewportUpdate", true);
64379
+ view.dispatch(tr);
64380
+ };
64381
+ const { call: throttledUpdate, cancel: cancelThrottle } = throttle(computeAndDispatch, 250);
64382
+ const scrollParent = scrollContainer;
64383
+ scrollParent.addEventListener("scroll", throttledUpdate, { passive: true });
64384
+ computeAndDispatch();
64385
+ return {
64386
+ update(_, prevState) {
64387
+ if (view.state.doc.content.size !== prevState.doc.content.size) {
64388
+ computeAndDispatch();
64389
+ }
64390
+ },
64391
+ destroy: () => {
64392
+ cancelThrottle();
64393
+ scrollParent.removeEventListener("scroll", throttledUpdate);
64394
+ }
64395
+ };
64396
+ },
64016
64397
  props: {
64017
64398
  decorations: ({ doc, selection }) => {
64399
+ var _a, _b;
64018
64400
  const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;
64019
- const { anchor } = selection;
64020
- const decorations = [];
64021
64401
  if (!active) {
64022
64402
  return null;
64023
64403
  }
64404
+ const { anchor } = selection;
64405
+ const decorations = [];
64024
64406
  const isEmptyDoc = this.editor.isEmpty;
64025
- doc.descendants((node, pos) => {
64026
- const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
64027
- const isEmpty = !node.isLeaf && isNodeEmpty(node);
64028
- if (!node.type.isTextblock) {
64029
- return this.options.includeChildren;
64407
+ const useResolvedPath = this.options.showOnlyCurrent && !this.options.includeChildren;
64408
+ if (useResolvedPath) {
64409
+ const resolved = doc.resolve(anchor);
64410
+ if (resolved.depth > 0) {
64411
+ const node = resolved.node(1);
64412
+ const nodeStart = resolved.before(1);
64413
+ if (node.type.isTextblock && isNodeEmpty(node)) {
64414
+ const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize;
64415
+ const decoration = createPlaceholderDecoration({
64416
+ node,
64417
+ dataAttribute,
64418
+ hasAnchor,
64419
+ placeholder: this.options.placeholder,
64420
+ classes: {
64421
+ emptyEditor: this.options.emptyEditorClass,
64422
+ emptyNode: this.options.emptyNodeClass
64423
+ },
64424
+ editor: this.editor,
64425
+ isEmptyDoc,
64426
+ pos: resolved.before(1)
64427
+ });
64428
+ decorations.push(decoration);
64429
+ }
64030
64430
  }
64031
- if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
64032
- const classes = [this.options.emptyNodeClass];
64033
- if (isEmptyDoc) {
64034
- classes.push(this.options.emptyEditorClass);
64431
+ } else {
64432
+ const pluginState = PLUGIN_KEY.getState(this.editor.state);
64433
+ const from = (_a = pluginState.topPos) != null ? _a : 0;
64434
+ const to = (_b = pluginState.bottomPos) != null ? _b : doc.content.size;
64435
+ doc.nodesBetween(from, to, (node, pos) => {
64436
+ const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
64437
+ const isEmpty = !node.isLeaf && isNodeEmpty(node);
64438
+ if (!node.type.isTextblock) {
64439
+ return this.options.includeChildren;
64035
64440
  }
64036
- const decoration = Decoration.node(pos, pos + node.nodeSize, {
64037
- class: classes.join(" "),
64038
- [dataAttribute]: typeof this.options.placeholder === "function" ? this.options.placeholder({
64441
+ if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
64442
+ const decoration = createPlaceholderDecoration({
64443
+ classes: { emptyEditor: this.options.emptyEditorClass, emptyNode: this.options.emptyNodeClass },
64039
64444
  editor: this.editor,
64445
+ isEmptyDoc,
64446
+ dataAttribute,
64447
+ hasAnchor,
64448
+ placeholder: this.options.placeholder,
64040
64449
  node,
64041
- pos,
64042
- hasAnchor
64043
- }) : this.options.placeholder
64044
- });
64045
- decorations.push(decoration);
64046
- }
64047
- return this.options.includeChildren;
64048
- });
64450
+ pos
64451
+ });
64452
+ decorations.push(decoration);
64453
+ }
64454
+ return this.options.includeChildren;
64455
+ });
64456
+ }
64049
64457
  return DecorationSet.create(doc, decorations);
64050
64458
  }
64051
64459
  }
@@ -72782,24 +73190,56 @@ focus outline in that case.
72782
73190
  </template>
72783
73191
  `;
72784
73192
 
73193
+ function createLazyMeasurementsView(count, flat, getItemKey) {
73194
+ const cache = new Array(count);
73195
+ return new Proxy(cache, {
73196
+ get(target, prop, receiver) {
73197
+ if (typeof prop === "string") {
73198
+ const c = prop.charCodeAt(0);
73199
+ if (c >= 48 && c <= 57) {
73200
+ const i = +prop;
73201
+ if (Number.isInteger(i) && i >= 0 && i < count) {
73202
+ let v = target[i];
73203
+ if (!v) {
73204
+ const s = flat[i * 2];
73205
+ v = target[i] = {
73206
+ index: i,
73207
+ key: getItemKey(i),
73208
+ start: s,
73209
+ size: flat[i * 2 + 1],
73210
+ end: s + flat[i * 2 + 1],
73211
+ lane: 0
73212
+ };
73213
+ }
73214
+ return v;
73215
+ }
73216
+ }
73217
+ if (prop === "length") return count;
73218
+ }
73219
+ return Reflect.get(target, prop, receiver);
73220
+ }
73221
+ });
73222
+ }
73223
+
72785
73224
  function memo(getDeps, fn, opts) {
72786
73225
  let deps = opts.initialDeps ?? [];
72787
73226
  let result;
72788
73227
  let isInitial = true;
72789
73228
  function memoizedFunction() {
72790
- var _a, _b, _c;
72791
- let depTime;
72792
- if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();
73229
+ var _a;
73230
+ const debugEnabled = !!opts.key && !!((_a = opts.debug) == null ? void 0 : _a.call(opts));
73231
+ let depTime = 0;
73232
+ if (debugEnabled) depTime = Date.now();
72793
73233
  const newDeps = getDeps();
72794
73234
  const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);
72795
73235
  if (!depsChanged) {
72796
73236
  return result;
72797
73237
  }
72798
73238
  deps = newDeps;
72799
- let resultTime;
72800
- if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();
73239
+ let resultTime = 0;
73240
+ if (debugEnabled) resultTime = Date.now();
72801
73241
  result = fn(...newDeps);
72802
- if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {
73242
+ if (debugEnabled) {
72803
73243
  const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
72804
73244
  const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
72805
73245
  const resultFpsPercentage = resultEndTime / 16;
@@ -72849,6 +73289,14 @@ focus outline in that case.
72849
73289
  };
72850
73290
  };
72851
73291
 
73292
+ let _isIOSResult;
73293
+ const isIOSWebKit = () => {
73294
+ if (_isIOSResult !== void 0) return _isIOSResult;
73295
+ if (typeof navigator === "undefined") return _isIOSResult = false;
73296
+ if (/iP(hone|od|ad)/.test(navigator.userAgent)) return _isIOSResult = true;
73297
+ const mtp = navigator.maxTouchPoints;
73298
+ return _isIOSResult = navigator.platform === "MacIntel" && mtp !== void 0 && mtp > 0;
73299
+ };
72852
73300
  const getRect = (element) => {
72853
73301
  const { offsetWidth, offsetHeight } = element;
72854
73302
  return { width: offsetWidth, height: offsetHeight };
@@ -72857,9 +73305,10 @@ focus outline in that case.
72857
73305
  const defaultRangeExtractor = (range) => {
72858
73306
  const start = Math.max(range.startIndex - range.overscan, 0);
72859
73307
  const end = Math.min(range.endIndex + range.overscan, range.count - 1);
72860
- const arr = [];
72861
- for (let i = start; i <= end; i++) {
72862
- arr.push(i);
73308
+ const len = end - start + 1;
73309
+ const arr = new Array(len);
73310
+ for (let i = 0; i < len; i++) {
73311
+ arr[i] = start + i;
72863
73312
  }
72864
73313
  return arr;
72865
73314
  };
@@ -72904,7 +73353,7 @@ focus outline in that case.
72904
73353
  passive: true
72905
73354
  };
72906
73355
  const supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
72907
- const observeElementOffset = (instance, cb) => {
73356
+ const observeOffset = (instance, cb, readOffset) => {
72908
73357
  const element = instance.scrollElement;
72909
73358
  if (!element) {
72910
73359
  return;
@@ -72913,24 +73362,21 @@ focus outline in that case.
72913
73362
  if (!targetWindow) {
72914
73363
  return;
72915
73364
  }
73365
+ const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
72916
73366
  let offset = 0;
72917
- const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(
73367
+ const fallback = registerScrollendEvent ? null : debounce(
72918
73368
  targetWindow,
72919
- () => {
72920
- cb(offset, false);
72921
- },
73369
+ () => cb(offset, false),
72922
73370
  instance.options.isScrollingResetDelay
72923
73371
  );
72924
73372
  const createHandler = (isScrolling) => () => {
72925
- const { horizontal, isRtl } = instance.options;
72926
- offset = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
72927
- fallback();
73373
+ offset = readOffset(element);
73374
+ fallback == null ? void 0 : fallback();
72928
73375
  cb(offset, isScrolling);
72929
73376
  };
72930
73377
  const handler = createHandler(true);
72931
73378
  const endHandler = createHandler(false);
72932
73379
  element.addEventListener("scroll", handler, addEventListenerOptions);
72933
- const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
72934
73380
  if (registerScrollendEvent) {
72935
73381
  element.addEventListener("scrollend", endHandler, addEventListenerOptions);
72936
73382
  }
@@ -72941,6 +73387,10 @@ focus outline in that case.
72941
73387
  }
72942
73388
  };
72943
73389
  };
73390
+ const observeElementOffset = (instance, cb) => observeOffset(instance, cb, (el) => {
73391
+ const { horizontal, isRtl } = instance.options;
73392
+ return horizontal ? el.scrollLeft * (isRtl && -1 || 1) : el.scrollTop;
73393
+ });
72944
73394
  const measureElement = (element, entry, instance) => {
72945
73395
  if (entry == null ? void 0 : entry.borderBoxSize) {
72946
73396
  const box = entry.borderBoxSize[0];
@@ -72953,17 +73403,17 @@ focus outline in that case.
72953
73403
  }
72954
73404
  return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
72955
73405
  };
72956
- const elementScroll = (offset, {
73406
+ const scrollWithAdjustments = (offset, {
72957
73407
  adjustments = 0,
72958
73408
  behavior
72959
73409
  }, instance) => {
72960
73410
  var _a, _b;
72961
- const toOffset = offset + adjustments;
72962
73411
  (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {
72963
- [instance.options.horizontal ? "left" : "top"]: toOffset,
73412
+ [instance.options.horizontal ? "left" : "top"]: offset + adjustments,
72964
73413
  behavior
72965
73414
  });
72966
73415
  };
73416
+ const elementScroll = scrollWithAdjustments;
72967
73417
  let Virtualizer$1 = class Virtualizer {
72968
73418
  constructor(opts) {
72969
73419
  this.unsubs = [];
@@ -72972,16 +73422,24 @@ focus outline in that case.
72972
73422
  this.isScrolling = false;
72973
73423
  this.scrollState = null;
72974
73424
  this.measurementsCache = [];
73425
+ this._flatMeasurements = null;
72975
73426
  this.itemSizeCache = /* @__PURE__ */ new Map();
73427
+ this.itemSizeCacheVersion = 0;
72976
73428
  this.laneAssignments = /* @__PURE__ */ new Map();
72977
- this.pendingMeasuredCacheIndexes = [];
73429
+ this.pendingMin = null;
72978
73430
  this.prevLanes = void 0;
72979
73431
  this.lanesChangedFlag = false;
72980
73432
  this.lanesSettling = false;
73433
+ this.pendingScrollAnchor = null;
72981
73434
  this.scrollRect = null;
72982
73435
  this.scrollOffset = null;
72983
73436
  this.scrollDirection = null;
72984
73437
  this.scrollAdjustments = 0;
73438
+ this._iosDeferredAdjustment = 0;
73439
+ this._iosTouching = false;
73440
+ this._iosJustTouchEnded = false;
73441
+ this._iosTouchEndTimerId = null;
73442
+ this._intendedScrollOffset = null;
72985
73443
  this.elementsCache = /* @__PURE__ */ new Map();
72986
73444
  this.now = () => {
72987
73445
  var _a, _b, _c;
@@ -73003,6 +73461,12 @@ focus outline in that case.
73003
73461
  const index = this.indexFromElement(node);
73004
73462
  if (!node.isConnected) {
73005
73463
  this.observer.unobserve(node);
73464
+ for (const [cacheKey, cachedNode] of this.elementsCache) {
73465
+ if (cachedNode === node) {
73466
+ this.elementsCache.delete(cacheKey);
73467
+ break;
73468
+ }
73469
+ }
73006
73470
  return;
73007
73471
  }
73008
73472
  if (this.shouldMeasureDuringScroll(index)) {
@@ -73034,10 +73498,8 @@ focus outline in that case.
73034
73498
  })();
73035
73499
  this.range = null;
73036
73500
  this.setOptions = (opts2) => {
73037
- Object.entries(opts2).forEach(([key, value]) => {
73038
- if (typeof value === "undefined") delete opts2[key];
73039
- });
73040
- this.options = {
73501
+ var _a, _b;
73502
+ const merged = {
73041
73503
  debug: false,
73042
73504
  initialOffset: 0,
73043
73505
  overscan: 1,
@@ -73057,14 +73519,50 @@ focus outline in that case.
73057
73519
  indexAttribute: "data-index",
73058
73520
  initialMeasurementsCache: [],
73059
73521
  lanes: 1,
73522
+ anchorTo: "start",
73523
+ followOnAppend: false,
73524
+ scrollEndThreshold: 1,
73060
73525
  isScrollingResetDelay: 150,
73061
73526
  enabled: true,
73062
73527
  isRtl: false,
73063
73528
  useScrollendEvent: false,
73064
73529
  useAnimationFrameWithResizeObserver: false,
73065
- laneAssignmentMode: "estimate",
73066
- ...opts2
73530
+ laneAssignmentMode: "estimate"
73067
73531
  };
73532
+ for (const key in opts2) {
73533
+ const v = opts2[key];
73534
+ if (v !== void 0) merged[key] = v;
73535
+ }
73536
+ const prevOptions = this.options;
73537
+ let anchor = null;
73538
+ let followOnAppend = null;
73539
+ if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && merged.anchorTo === "end" && this.scrollElement !== null) {
73540
+ const prevCount = prevOptions.count;
73541
+ const nextCount = merged.count;
73542
+ const measurements = this.getMeasurements();
73543
+ const prevFirstKey = prevCount > 0 ? ((_a = measurements[0]) == null ? void 0 : _a.key) ?? prevOptions.getItemKey(0) : null;
73544
+ const prevLastKey = prevCount > 0 ? ((_b = measurements[prevCount - 1]) == null ? void 0 : _b.key) ?? prevOptions.getItemKey(prevCount - 1) : null;
73545
+ const didCountChange = nextCount !== prevCount;
73546
+ const didEdgeKeysChange = didCountChange || prevCount > 0 && nextCount > 0 && (merged.getItemKey(0) !== prevFirstKey || merged.getItemKey(nextCount - 1) !== prevLastKey);
73547
+ if (didEdgeKeysChange) {
73548
+ const item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;
73549
+ if (item) {
73550
+ anchor = [item.key, this.getScrollOffset() - item.start];
73551
+ }
73552
+ const behavior = merged.followOnAppend === true ? "auto" : merged.followOnAppend || null;
73553
+ if (behavior && nextCount > prevCount && this.isAtEnd(prevOptions.scrollEndThreshold) && (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)) {
73554
+ followOnAppend = behavior;
73555
+ }
73556
+ }
73557
+ }
73558
+ this.options = merged;
73559
+ if (anchor || followOnAppend) {
73560
+ this.pendingScrollAnchor = [
73561
+ (anchor == null ? void 0 : anchor[0]) ?? null,
73562
+ (anchor == null ? void 0 : anchor[1]) ?? 0,
73563
+ followOnAppend
73564
+ ];
73565
+ }
73068
73566
  };
73069
73567
  this.notify = (sync) => {
73070
73568
  var _a, _b;
@@ -73135,21 +73633,104 @@ focus outline in that case.
73135
73633
  );
73136
73634
  this.unsubs.push(
73137
73635
  this.options.observeElementOffset(this, (offset, isScrolling) => {
73636
+ if (this._intendedScrollOffset !== null && Math.abs(offset - this._intendedScrollOffset) < 1.5) {
73637
+ offset = this._intendedScrollOffset;
73638
+ }
73639
+ this._intendedScrollOffset = null;
73138
73640
  this.scrollAdjustments = 0;
73139
73641
  this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null;
73140
73642
  this.scrollOffset = offset;
73141
73643
  this.isScrolling = isScrolling;
73644
+ this._flushIosDeferredIfReady();
73142
73645
  if (this.scrollState) {
73143
73646
  this.scheduleScrollReconcile();
73144
73647
  }
73145
73648
  this.maybeNotify();
73146
73649
  })
73147
73650
  );
73651
+ if ("addEventListener" in this.scrollElement) {
73652
+ const scrollEl = this.scrollElement;
73653
+ const onTouchStart = () => {
73654
+ this._iosTouching = true;
73655
+ this._iosJustTouchEnded = false;
73656
+ if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
73657
+ this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
73658
+ this._iosTouchEndTimerId = null;
73659
+ }
73660
+ };
73661
+ const onTouchEnd = () => {
73662
+ this._iosTouching = false;
73663
+ if (!isIOSWebKit() || this.targetWindow == null) {
73664
+ return;
73665
+ }
73666
+ this._iosJustTouchEnded = true;
73667
+ this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => {
73668
+ this._iosJustTouchEnded = false;
73669
+ this._iosTouchEndTimerId = null;
73670
+ this._flushIosDeferredIfReady();
73671
+ }, 150);
73672
+ };
73673
+ scrollEl.addEventListener(
73674
+ "touchstart",
73675
+ onTouchStart,
73676
+ addEventListenerOptions
73677
+ );
73678
+ scrollEl.addEventListener(
73679
+ "touchend",
73680
+ onTouchEnd,
73681
+ addEventListenerOptions
73682
+ );
73683
+ this.unsubs.push(() => {
73684
+ scrollEl.removeEventListener("touchstart", onTouchStart);
73685
+ scrollEl.removeEventListener("touchend", onTouchEnd);
73686
+ if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
73687
+ this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
73688
+ this._iosTouchEndTimerId = null;
73689
+ }
73690
+ });
73691
+ }
73148
73692
  this._scrollToOffset(this.getScrollOffset(), {
73149
73693
  adjustments: void 0,
73150
73694
  behavior: void 0
73151
73695
  });
73152
73696
  }
73697
+ const anchor = this.pendingScrollAnchor;
73698
+ this.pendingScrollAnchor = null;
73699
+ if (anchor && this.scrollElement && this.options.enabled) {
73700
+ const [key, offset, followOnAppend] = anchor;
73701
+ if (key !== null) {
73702
+ const { count, getItemKey } = this.options;
73703
+ let index = 0;
73704
+ while (index < count && getItemKey(index) !== key) {
73705
+ index++;
73706
+ }
73707
+ const item = index < count ? this.getMeasurements()[index] : void 0;
73708
+ if (item) {
73709
+ const delta = item.start + offset - this.getScrollOffset();
73710
+ if (!approxEqual(delta, 0)) {
73711
+ this.applyScrollAdjustment(delta);
73712
+ }
73713
+ }
73714
+ }
73715
+ if (followOnAppend) {
73716
+ this.scrollToEnd({ behavior: followOnAppend });
73717
+ }
73718
+ }
73719
+ };
73720
+ this._flushIosDeferredIfReady = () => {
73721
+ if (this._iosDeferredAdjustment === 0) return;
73722
+ if (this.isScrolling) return;
73723
+ if (this._iosTouching) return;
73724
+ if (this._iosJustTouchEnded) return;
73725
+ const cur = this.getScrollOffset();
73726
+ const max = this.getMaxScrollOffset();
73727
+ if (cur < 0 || cur > max) return;
73728
+ const delta = this._iosDeferredAdjustment;
73729
+ this._iosDeferredAdjustment = 0;
73730
+ this._scrollToOffset(cur, {
73731
+ adjustments: this.scrollAdjustments += delta,
73732
+ behavior: void 0
73733
+ });
73153
73734
  };
73154
73735
  this.rafId = null;
73155
73736
  this.getSize = () => {
@@ -73211,7 +73792,7 @@ focus outline in that case.
73211
73792
  this.lanesChangedFlag = true;
73212
73793
  }
73213
73794
  this.prevLanes = lanes;
73214
- this.pendingMeasuredCacheIndexes = [];
73795
+ this.pendingMin = null;
73215
73796
  return {
73216
73797
  count,
73217
73798
  paddingStart,
@@ -73227,7 +73808,7 @@ focus outline in that case.
73227
73808
  }
73228
73809
  );
73229
73810
  this.getMeasurements = memo(
73230
- () => [this.getMeasurementOptions(), this.itemSizeCache],
73811
+ () => [this.getMeasurementOptions(), this.itemSizeCacheVersion],
73231
73812
  ({
73232
73813
  count,
73233
73814
  paddingStart,
@@ -73236,7 +73817,8 @@ focus outline in that case.
73236
73817
  enabled,
73237
73818
  lanes,
73238
73819
  laneAssignmentMode
73239
- }, itemSizeCache) => {
73820
+ }, _itemSizeCacheVersion) => {
73821
+ const itemSizeCache = this.itemSizeCache;
73240
73822
  if (!enabled) {
73241
73823
  this.measurementsCache = [];
73242
73824
  this.itemSizeCache.clear();
@@ -73256,7 +73838,7 @@ focus outline in that case.
73256
73838
  this.measurementsCache = [];
73257
73839
  this.itemSizeCache.clear();
73258
73840
  this.laneAssignments.clear();
73259
- this.pendingMeasuredCacheIndexes = [];
73841
+ this.pendingMin = null;
73260
73842
  }
73261
73843
  if (this.measurementsCache.length === 0 && !this.lanesSettling) {
73262
73844
  this.measurementsCache = this.options.initialMeasurementsCache;
@@ -73264,11 +73846,40 @@ focus outline in that case.
73264
73846
  this.itemSizeCache.set(item.key, item.size);
73265
73847
  });
73266
73848
  }
73267
- const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
73268
- this.pendingMeasuredCacheIndexes = [];
73849
+ const min = this.lanesSettling ? 0 : this.pendingMin ?? 0;
73850
+ this.pendingMin = null;
73269
73851
  if (this.lanesSettling && this.measurementsCache.length === count) {
73270
73852
  this.lanesSettling = false;
73271
73853
  }
73854
+ if (lanes === 1) {
73855
+ const gap = this.options.gap;
73856
+ const need = count * 2;
73857
+ let flat = this._flatMeasurements;
73858
+ if (!flat || flat.length < need) {
73859
+ const next = new Float64Array(need);
73860
+ if (flat && min > 0) next.set(flat.subarray(0, min * 2));
73861
+ flat = next;
73862
+ this._flatMeasurements = flat;
73863
+ }
73864
+ let runningStart;
73865
+ if (min === 0) {
73866
+ runningStart = paddingStart + scrollMargin;
73867
+ } else {
73868
+ const prevIdx = min - 1;
73869
+ runningStart = flat[prevIdx * 2] + flat[prevIdx * 2 + 1] + gap;
73870
+ }
73871
+ for (let i = min; i < count; i++) {
73872
+ const key = getItemKey(i);
73873
+ const measuredSize = itemSizeCache.get(key);
73874
+ const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
73875
+ flat[i * 2] = runningStart;
73876
+ flat[i * 2 + 1] = size;
73877
+ runningStart += size + gap;
73878
+ }
73879
+ const view = createLazyMeasurementsView(count, flat, getItemKey);
73880
+ this.measurementsCache = view;
73881
+ return view;
73882
+ }
73272
73883
  const measurements = this.measurementsCache.slice(0, min);
73273
73884
  const laneLastIndex = new Array(lanes).fill(
73274
73885
  void 0
@@ -73331,7 +73942,11 @@ focus outline in that case.
73331
73942
  measurements,
73332
73943
  outerSize,
73333
73944
  scrollOffset,
73334
- lanes
73945
+ lanes,
73946
+ // Pass the typed array so binary search + forward-walk can
73947
+ // read start/end directly from Float64Array, skipping the
73948
+ // Proxy traps that materialize a full VirtualItem per probe.
73949
+ flat: lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null
73335
73950
  }) : null;
73336
73951
  },
73337
73952
  {
@@ -73426,23 +74041,60 @@ focus outline in that case.
73426
74041
  }
73427
74042
  };
73428
74043
  this.resizeItem = (index, size) => {
73429
- var _a;
73430
- const item = this.measurementsCache[index];
73431
- if (!item) return;
73432
- const itemSize = this.itemSizeCache.get(item.key) ?? item.size;
74044
+ var _a, _b;
74045
+ if (index < 0 || index >= this.options.count) return;
74046
+ let cachedSize;
74047
+ let itemStart;
74048
+ let key;
74049
+ const flat = this._flatMeasurements;
74050
+ if (this.options.lanes === 1 && flat !== null) {
74051
+ key = this.options.getItemKey(index);
74052
+ itemStart = flat[index * 2];
74053
+ cachedSize = flat[index * 2 + 1];
74054
+ } else {
74055
+ const item = this.measurementsCache[index];
74056
+ if (!item) return;
74057
+ key = item.key;
74058
+ itemStart = item.start;
74059
+ cachedSize = item.size;
74060
+ }
74061
+ const itemSize = this.itemSizeCache.get(key) ?? cachedSize;
73433
74062
  const delta = size - itemSize;
73434
74063
  if (delta !== 0) {
73435
- if (((_a = this.scrollState) == null ? void 0 : _a.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments)) {
73436
- if (this.options.debug) {
73437
- console.info("correction", delta);
73438
- }
73439
- this._scrollToOffset(this.getScrollOffset(), {
73440
- adjustments: this.scrollAdjustments += delta,
73441
- behavior: void 0
73442
- });
74064
+ const wasAtEnd = this.options.anchorTo === "end" && ((_a = this.scrollState) == null ? void 0 : _a.behavior) !== "smooth" && this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold;
74065
+ const prevTotalSize = wasAtEnd ? this.getTotalSize() : 0;
74066
+ const shouldAdjustScroll = ((_b = this.scrollState) == null ? void 0 : _b.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(
74067
+ // The callback expects a VirtualItem; build one lazily only
74068
+ // when the consumer actually supplied a custom predicate.
74069
+ this.measurementsCache[index] ?? {
74070
+ index,
74071
+ key,
74072
+ start: itemStart,
74073
+ size: cachedSize,
74074
+ end: itemStart + cachedSize,
74075
+ lane: 0
74076
+ },
74077
+ delta,
74078
+ this
74079
+ ) : (
74080
+ // Default: adjust scrollTop only when the resize is an above-
74081
+ // viewport item AND we're not actively scrolling backward.
74082
+ // Adjusting during backward scroll fights the user's scroll
74083
+ // direction and produces the "items jump while scrolling up"
74084
+ // jank reported across many issues. Users who want the old
74085
+ // behavior can pass shouldAdjustScrollPositionOnItemSizeChange.
74086
+ itemStart < this.getScrollOffset() + this.scrollAdjustments && this.scrollDirection !== "backward"
74087
+ ));
74088
+ if (this.pendingMin === null || index < this.pendingMin) {
74089
+ this.pendingMin = index;
74090
+ }
74091
+ this.itemSizeCache.set(key, size);
74092
+ this.itemSizeCacheVersion++;
74093
+ if (wasAtEnd) {
74094
+ this.applyScrollAdjustment(this.getTotalSize() - prevTotalSize);
74095
+ } else if (shouldAdjustScroll) {
74096
+ this.applyScrollAdjustment(delta);
73443
74097
  }
73444
- this.pendingMeasuredCacheIndexes.push(item.index);
73445
- this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
73446
74098
  this.notify(false);
73447
74099
  }
73448
74100
  };
@@ -73467,14 +74119,15 @@ focus outline in that case.
73467
74119
  if (measurements.length === 0) {
73468
74120
  return void 0;
73469
74121
  }
73470
- return notUndefined(
73471
- measurements[findNearestBinarySearch(
73472
- 0,
73473
- measurements.length - 1,
73474
- (index) => notUndefined(measurements[index]).start,
73475
- offset
73476
- )]
74122
+ const flat = this._flatMeasurements;
74123
+ const useFlat = this.options.lanes === 1 && flat != null;
74124
+ const idx = findNearestBinarySearch(
74125
+ 0,
74126
+ measurements.length - 1,
74127
+ useFlat ? (i) => flat[i * 2] : (i) => notUndefined(measurements[i]).start,
74128
+ offset
73477
74129
  );
74130
+ return notUndefined(measurements[idx]);
73478
74131
  };
73479
74132
  this.getMaxScrollOffset = () => {
73480
74133
  if (!this.scrollElement) return 0;
@@ -73485,6 +74138,18 @@ focus outline in that case.
73485
74138
  return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
73486
74139
  }
73487
74140
  };
74141
+ this.getVirtualDistanceFromEnd = () => {
74142
+ return Math.max(
74143
+ this.getTotalSize() - this.getSize() - this.getScrollOffset(),
74144
+ 0
74145
+ );
74146
+ };
74147
+ this.getDistanceFromEnd = () => {
74148
+ return Math.max(this.getMaxScrollOffset() - this.getScrollOffset(), 0);
74149
+ };
74150
+ this.isAtEnd = (threshold = this.options.scrollEndThreshold) => {
74151
+ return this.getDistanceFromEnd() <= threshold;
74152
+ };
73488
74153
  this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
73489
74154
  if (!this.scrollElement) return 0;
73490
74155
  const size = this.getSize();
@@ -73574,6 +74239,18 @@ focus outline in that case.
73574
74239
  this._scrollToOffset(offset, { adjustments: void 0, behavior });
73575
74240
  this.scheduleScrollReconcile();
73576
74241
  };
74242
+ this.scrollToEnd = ({ behavior = "auto" } = {}) => {
74243
+ if (this.options.count > 0) {
74244
+ this.scrollToIndex(this.options.count - 1, {
74245
+ align: "end",
74246
+ behavior
74247
+ });
74248
+ return;
74249
+ }
74250
+ this.scrollToOffset(Math.max(this.getTotalSize() - this.getSize(), 0), {
74251
+ behavior
74252
+ });
74253
+ };
73577
74254
  this.getTotalSize = () => {
73578
74255
  var _a;
73579
74256
  const measurements = this.getMeasurements();
@@ -73581,7 +74258,13 @@ focus outline in that case.
73581
74258
  if (measurements.length === 0) {
73582
74259
  end = this.options.paddingStart;
73583
74260
  } else if (this.options.lanes === 1) {
73584
- end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
74261
+ const lastIdx = measurements.length - 1;
74262
+ const flat = this._flatMeasurements;
74263
+ if (flat != null) {
74264
+ end = flat[lastIdx * 2] + flat[lastIdx * 2 + 1];
74265
+ } else {
74266
+ end = ((_a = measurements[lastIdx]) == null ? void 0 : _a.end) ?? 0;
74267
+ }
73585
74268
  } else {
73586
74269
  const endByLane = Array(this.options.lanes).fill(null);
73587
74270
  let endIndex = measurements.length - 1;
@@ -73599,19 +74282,54 @@ focus outline in that case.
73599
74282
  0
73600
74283
  );
73601
74284
  };
74285
+ this.takeSnapshot = () => {
74286
+ const snapshot = [];
74287
+ if (this.itemSizeCache.size === 0) return snapshot;
74288
+ const m = this.getMeasurements();
74289
+ for (const item of m) {
74290
+ if (item && this.itemSizeCache.has(item.key)) {
74291
+ snapshot.push({
74292
+ index: item.index,
74293
+ key: item.key,
74294
+ start: item.start,
74295
+ size: item.size,
74296
+ end: item.end,
74297
+ lane: item.lane
74298
+ });
74299
+ }
74300
+ }
74301
+ return snapshot;
74302
+ };
73602
74303
  this._scrollToOffset = (offset, {
73603
74304
  adjustments,
73604
74305
  behavior
73605
74306
  }) => {
74307
+ this._intendedScrollOffset = offset + (adjustments ?? 0);
73606
74308
  this.options.scrollToFn(offset, { behavior, adjustments }, this);
73607
74309
  };
73608
74310
  this.measure = () => {
73609
- this.itemSizeCache = /* @__PURE__ */ new Map();
73610
- this.laneAssignments = /* @__PURE__ */ new Map();
74311
+ this.pendingMin = null;
74312
+ this.itemSizeCache.clear();
74313
+ this.laneAssignments.clear();
74314
+ this.itemSizeCacheVersion++;
73611
74315
  this.notify(false);
73612
74316
  };
73613
74317
  this.setOptions(opts);
73614
74318
  }
74319
+ applyScrollAdjustment(delta, behavior) {
74320
+ if (delta === 0) return;
74321
+ if (this.options.debug) {
74322
+ console.info("correction", delta);
74323
+ }
74324
+ if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {
74325
+ this._iosDeferredAdjustment += delta;
74326
+ } else {
74327
+ this._scrollToOffset(this.getScrollOffset(), {
74328
+ adjustments: this.scrollAdjustments += delta,
74329
+ behavior
74330
+ });
74331
+ }
74332
+ }
73615
74333
  scheduleScrollReconcile() {
73616
74334
  if (!this.targetWindow) {
73617
74335
  this.scrollState = null;
@@ -73639,17 +74357,28 @@ focus outline in that case.
73639
74357
  if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {
73640
74358
  this.scrollState.stableFrames++;
73641
74359
  if (this.scrollState.stableFrames >= STABLE_FRAMES) {
74360
+ if (this.getScrollOffset() !== targetOffset) {
74361
+ this._scrollToOffset(targetOffset, {
74362
+ adjustments: void 0,
74363
+ behavior: "auto"
74364
+ });
74365
+ }
73642
74366
  this.scrollState = null;
73643
74367
  return;
73644
74368
  }
73645
74369
  } else {
73646
74370
  this.scrollState.stableFrames = 0;
73647
74371
  if (targetChanged) {
74372
+ const viewport = this.getSize() || 600;
74373
+ const distance = Math.abs(targetOffset - this.getScrollOffset());
74374
+ const keepSmooth = this.scrollState.behavior === "smooth" && distance > viewport;
73648
74375
  this.scrollState.lastTargetOffset = targetOffset;
73649
- this.scrollState.behavior = "auto";
74376
+ if (!keepSmooth) {
74377
+ this.scrollState.behavior = "auto";
74378
+ }
73650
74379
  this._scrollToOffset(targetOffset, {
73651
74380
  adjustments: void 0,
73652
- behavior: "auto"
74381
+ behavior: keepSmooth ? "smooth" : "auto"
73653
74382
  });
73654
74383
  }
73655
74384
  }
@@ -73678,25 +74407,22 @@ focus outline in that case.
73678
74407
  measurements,
73679
74408
  outerSize,
73680
74409
  scrollOffset,
73681
- lanes
74410
+ lanes,
74411
+ flat
73682
74412
  }) {
73683
74413
  const lastIndex = measurements.length - 1;
73684
- const getOffset = (index) => measurements[index].start;
74414
+ const getStart = flat ? (index) => flat[index * 2] : (index) => measurements[index].start;
74415
+ const getEnd = flat ? (index) => flat[index * 2] + flat[index * 2 + 1] : (index) => measurements[index].end;
73685
74416
  if (measurements.length <= lanes) {
73686
74417
  return {
73687
74418
  startIndex: 0,
73688
74419
  endIndex: lastIndex
73689
74420
  };
73690
74421
  }
73691
- let startIndex = findNearestBinarySearch(
73692
- 0,
73693
- lastIndex,
73694
- getOffset,
73695
- scrollOffset
73696
- );
74422
+ let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset);
73697
74423
  let endIndex = startIndex;
73698
74424
  if (lanes === 1) {
73699
- while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {
74425
+ while (endIndex < lastIndex && getEnd(endIndex) < scrollOffset + outerSize) {
73700
74426
  endIndex++;
73701
74427
  }
73702
74428
  } else if (lanes > 1) {