@ni/spright-components 6.19.0 → 6.19.1

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.
@@ -29158,7 +29158,7 @@ so this becomes the fallback color for the slot */ ''}
29158
29158
  return Fragment.empty;
29159
29159
  if (!Array.isArray(value))
29160
29160
  throw new RangeError("Invalid input for Fragment.fromJSON");
29161
- return new Fragment(value.map(schema.nodeFromJSON));
29161
+ return Fragment.fromArray(value.map(schema.nodeFromJSON));
29162
29162
  }
29163
29163
  /**
29164
29164
  Build a fragment from an array of nodes. Ensures that adjacent
@@ -29392,17 +29392,6 @@ so this becomes the fallback color for the slot */ ''}
29392
29392
  */
29393
29393
  class ReplaceError extends Error {
29394
29394
  }
29395
- /*
29396
- ReplaceError = function(this: any, message: string) {
29397
- let err = Error.call(this, message)
29398
- ;(err as any).__proto__ = ReplaceError.prototype
29399
- return err
29400
- } as any
29401
-
29402
- ReplaceError.prototype = Object.create(Error.prototype)
29403
- ReplaceError.prototype.constructor = ReplaceError
29404
- ReplaceError.prototype.name = "ReplaceError"
29405
- */
29406
29395
  /**
29407
29396
  A slice represents a piece cut out of a larger document. It
29408
29397
  stores not only a fragment, but also the depth up to which nodes on
@@ -29448,7 +29437,7 @@ so this becomes the fallback color for the slot */ ''}
29448
29437
  @internal
29449
29438
  */
29450
29439
  insertAt(pos, fragment) {
29451
- let content = insertInto(this.content, pos + this.openStart, fragment);
29440
+ let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
29452
29441
  return content && new Slice(content, this.openStart, this.openEnd);
29453
29442
  }
29454
29443
  /**
@@ -29522,14 +29511,14 @@ so this becomes the fallback color for the slot */ ''}
29522
29511
  throw new RangeError("Removing non-flat range");
29523
29512
  return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
29524
29513
  }
29525
- function insertInto(content, dist, insert, parent) {
29514
+ function insertInto(content, dist, insert, openStart, openEnd, parent) {
29526
29515
  let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
29527
29516
  if (offset == dist || child.isText) {
29528
- if (parent && !parent.canReplace(index, index, insert))
29517
+ if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert))
29529
29518
  return null;
29530
29519
  return content.cut(0, dist).append(insert).append(content.cut(dist));
29531
29520
  }
29532
- let inner = insertInto(child.content, dist - offset - 1, insert, child);
29521
+ let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
29533
29522
  return inner && content.replaceChild(index, child.copy(inner));
29534
29523
  }
29535
29524
  function replace$1($from, $to, slice) {
@@ -30059,10 +30048,11 @@ so this becomes the fallback color for the slot */ ''}
30059
30048
  */
30060
30049
  forEach(f) { this.content.forEach(f); }
30061
30050
  /**
30062
- Invoke a callback for all descendant nodes recursively between
30051
+ Invoke a callback for all descendant nodes recursively overlapping
30063
30052
  the given two positions that are relative to start of this
30064
- node's content. The callback is invoked with the node, its
30065
- position relative to the original node (method receiver),
30053
+ node's content. This includes all ancestors of the nodes
30054
+ containing the two positions. The callback is invoked with the
30055
+ node, its position relative to the original node (method receiver),
30066
30056
  its parent node, and its child index. When the callback returns
30067
30057
  false for a given node, that node's children will not be
30068
30058
  recursed over. The last parameter can be used to specify a
@@ -32150,6 +32140,8 @@ so this becomes the fallback color for the slot */ ''}
32150
32140
  @internal
32151
32141
  */
32152
32142
  serializeNodeInner(node, options) {
32143
+ if (node.isText)
32144
+ return doc$1(options).createTextNode(node.text);
32153
32145
  let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
32154
32146
  if (contentDOM) {
32155
32147
  if (node.isLeaf)
@@ -32184,6 +32176,9 @@ so this becomes the fallback color for the slot */ ''}
32184
32176
  return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
32185
32177
  }
32186
32178
  static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
32179
+ // Kludge for backwards-compatibility with accidental original behavious
32180
+ if (typeof structure == "string")
32181
+ return { dom: doc.createTextNode(structure) };
32187
32182
  return renderSpec(doc, structure, xmlNS, blockArraysIn);
32188
32183
  }
32189
32184
  /**
@@ -32255,11 +32250,9 @@ so this becomes the fallback color for the slot */ ''}
32255
32250
  return result;
32256
32251
  }
32257
32252
  function renderSpec(doc, structure, xmlNS, blockArraysIn) {
32258
- if (typeof structure == "string")
32259
- return { dom: doc.createTextNode(structure) };
32260
- if (structure.nodeType != null)
32253
+ if (structure.nodeType == 1)
32261
32254
  return { dom: structure };
32262
- if (structure.dom && structure.dom.nodeType != null)
32255
+ if (structure.dom && structure.dom.nodeType == 1)
32263
32256
  return structure;
32264
32257
  let tagName = structure[0], suspicious;
32265
32258
  if (typeof tagName != "string")
@@ -32295,6 +32288,9 @@ so this becomes the fallback color for the slot */ ''}
32295
32288
  throw new RangeError("Content hole must be the only child of its parent node");
32296
32289
  return { dom, contentDOM: dom };
32297
32290
  }
32291
+ else if (typeof child == "string") {
32292
+ dom.appendChild(doc.createTextNode(child));
32293
+ }
32298
32294
  else {
32299
32295
  let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
32300
32296
  dom.appendChild(inner);
@@ -42775,8 +42771,44 @@ so this becomes the fallback color for the slot */ ''}
42775
42771
  }
42776
42772
  return true;
42777
42773
  };
42774
+
42775
+ // src/commands/deleteSelection.ts
42776
+ var hasTextContent = (nodeSpec) => {
42777
+ if (!nodeSpec.content) {
42778
+ return false;
42779
+ }
42780
+ const textRegex = /^text(\*|\+)/;
42781
+ return textRegex.test(nodeSpec.content);
42782
+ };
42783
+ var expandSelectionForSide = ($pos, schema, side) => {
42784
+ if (!$pos.parent.isInline) {
42785
+ return $pos.pos;
42786
+ }
42787
+ if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) {
42788
+ return $pos.pos;
42789
+ }
42790
+ const parentContent = schema.nodes[$pos.parent.type.name].spec;
42791
+ if (!hasTextContent(parentContent)) {
42792
+ return $pos.pos;
42793
+ }
42794
+ return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
42795
+ };
42796
+ var expandSelectionForInlineText = ($from, $to, schema) => {
42797
+ const from = expandSelectionForSide($from, schema, "left");
42798
+ const to = expandSelectionForSide($to, schema, "right");
42799
+ return { from, to };
42800
+ };
42778
42801
  var deleteSelection = () => ({ state, dispatch }) => {
42779
- return deleteSelection$1(state, dispatch);
42802
+ const { $from, $to } = state.selection;
42803
+ if (state.selection.empty) {
42804
+ return false;
42805
+ }
42806
+ const { from, to } = expandSelectionForInlineText($from, $to, state.schema);
42807
+ if (dispatch) {
42808
+ state.tr.deleteRange(from, to).scrollIntoView();
42809
+ dispatch(state.tr);
42810
+ }
42811
+ return true;
42780
42812
  };
42781
42813
 
42782
42814
  // src/commands/enter.ts
@@ -45436,6 +45468,7 @@ so this becomes the fallback color for the slot */ ''}
45436
45468
  });
45437
45469
  extension.name = this.name;
45438
45470
  extension.parent = this.parent;
45471
+ this.child = null;
45439
45472
  return extension;
45440
45473
  }
45441
45474
  extend(extendedConfig = {}) {
@@ -45971,6 +46004,36 @@ so this becomes the fallback color for the slot */ ''}
45971
46004
  })
45972
46005
  );
45973
46006
  }
46007
+ /**
46008
+ * Destroy the extension manager and clean up all extension references
46009
+ * to prevent memory leaks through parent/child extension chains.
46010
+ *
46011
+ * Walks each extension's full parent chain and nulls every forward
46012
+ * `parent.child → current` link where the parent still points to the
46013
+ * current node. This breaks the retention path from module-scope
46014
+ * singleton roots through deep extend() chains.
46015
+ *
46016
+ * Only ancestor `.child` links matching the current chain are cleared.
46017
+ * The `.parent` pointer on ancestors is never touched — extensions
46018
+ * may be shared across live editors, so their own backward references
46019
+ * and non-matching forward links must remain intact.
46020
+ */
46021
+ destroy() {
46022
+ this.extensions.forEach((extension) => {
46023
+ let current = extension;
46024
+ while (current.parent) {
46025
+ const parent = current.parent;
46026
+ if (parent.child === current) {
46027
+ parent.child = null;
46028
+ }
46029
+ current = parent;
46030
+ }
46031
+ });
46032
+ this.extensions = [];
46033
+ this.baseExtensions = [];
46034
+ this.schema = null;
46035
+ this.editor = null;
46036
+ }
45974
46037
  /**
45975
46038
  * Go through all extensions, create extension storages & setup marks
45976
46039
  * & bind editor event listener.
@@ -46384,12 +46447,23 @@ so this becomes the fallback color for the slot */ ''}
46384
46447
  });
46385
46448
  var Tabindex = Extension.create({
46386
46449
  name: "tabindex",
46450
+ addOptions() {
46451
+ return {
46452
+ value: void 0
46453
+ };
46454
+ },
46387
46455
  addProseMirrorPlugins() {
46388
46456
  return [
46389
46457
  new Plugin({
46390
46458
  key: new PluginKey("tabindex"),
46391
46459
  props: {
46392
- attributes: () => this.editor.isEditable ? { tabindex: "0" } : {}
46460
+ attributes: () => {
46461
+ var _a;
46462
+ if (!this.editor.isEditable && this.options.value === void 0) {
46463
+ return {};
46464
+ }
46465
+ return { tabindex: (_a = this.options.value) != null ? _a : "0" };
46466
+ }
46393
46467
  }
46394
46468
  })
46395
46469
  ];
@@ -46728,6 +46802,7 @@ img.ProseMirror-separator {
46728
46802
  this.className = "tiptap";
46729
46803
  this.editorView = null;
46730
46804
  this.isFocused = false;
46805
+ this.destroyed = false;
46731
46806
  /**
46732
46807
  * The editor is considered initialized after the `create` event has been emitted.
46733
46808
  */
@@ -47019,7 +47094,7 @@ img.ProseMirror-separator {
47019
47094
  * Creates an extension manager.
47020
47095
  */
47021
47096
  createExtensionManager() {
47022
- var _a, _b;
47097
+ var _a, _b, _c, _d;
47023
47098
  const coreExtensions = this.options.enableCoreExtensions ? [
47024
47099
  Editable,
47025
47100
  ClipboardTextSerializer.configure({
@@ -47028,7 +47103,9 @@ img.ProseMirror-separator {
47028
47103
  Commands,
47029
47104
  FocusEvents,
47030
47105
  Keymap,
47031
- Tabindex,
47106
+ Tabindex.configure({
47107
+ value: (_d = (_c = this.options.coreExtensionOptions) == null ? void 0 : _c.tabindex) == null ? void 0 : _d.value
47108
+ }),
47032
47109
  Drop,
47033
47110
  Paste,
47034
47111
  Delete,
@@ -47265,9 +47342,18 @@ img.ProseMirror-separator {
47265
47342
  * Destroy the editor.
47266
47343
  */
47267
47344
  destroy() {
47345
+ if (this.destroyed) {
47346
+ return;
47347
+ }
47348
+ this.destroyed = true;
47268
47349
  this.emit("destroy");
47269
47350
  this.unmount();
47270
47351
  this.removeAllListeners();
47352
+ this.extensionManager.destroy();
47353
+ this.extensionManager = null;
47354
+ this.schema = null;
47355
+ this.commandManager = null;
47356
+ this.extensionStorage = {};
47271
47357
  }
47272
47358
  /**
47273
47359
  * Check if the editor is already destroyed.
@@ -47286,7 +47372,8 @@ img.ProseMirror-separator {
47286
47372
  }
47287
47373
  $pos(pos) {
47288
47374
  const $pos = this.state.doc.resolve(pos);
47289
- return new NodePos($pos, this);
47375
+ const node = pos > 0 && $pos.nodeAfter && !$pos.nodeAfter.isText ? $pos.nodeAfter : null;
47376
+ return new NodePos($pos, this, false, node);
47290
47377
  }
47291
47378
  get $doc() {
47292
47379
  return this.$pos(0);
@@ -49884,6 +49971,15 @@ ${indentedChild}`;
49884
49971
  function decodeHTML(str, mode = DecodingMode.Legacy) {
49885
49972
  return htmlDecoder(str, mode);
49886
49973
  }
49974
+ /**
49975
+ * Decodes an HTML string, requiring all entities to be terminated by a semicolon.
49976
+ *
49977
+ * @param str The string to decode.
49978
+ * @returns The decoded string.
49979
+ */
49980
+ function decodeHTMLStrict(str) {
49981
+ return htmlDecoder(str, DecodingMode.Strict);
49982
+ }
49887
49983
 
49888
49984
  // Utilities
49889
49985
  //
@@ -50063,6 +50159,10 @@ ${indentedChild}`;
50063
50159
  return P.test(ch) || regex.test(ch)
50064
50160
  }
50065
50161
 
50162
+ function isPunctCharCode (code) {
50163
+ return isPunctChar(fromCodePoint(code))
50164
+ }
50165
+
50066
50166
  // Markdown ASCII punctuation characters.
50067
50167
  //
50068
50168
  // !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~
@@ -50124,6 +50224,7 @@ ${indentedChild}`;
50124
50224
  // (remove this when node v10 is no longer supported).
50125
50225
  //
50126
50226
  if ('ẞ'.toLowerCase() === 'Ṿ') {
50227
+ /* c8 ignore next 2 */
50127
50228
  str = str.replace(/ẞ/g, 'ß');
50128
50229
  }
50129
50230
 
@@ -50162,6 +50263,28 @@ ${indentedChild}`;
50162
50263
  return str.toLowerCase().toUpperCase()
50163
50264
  }
50164
50265
 
50266
+ function isAsciiTrimmable (c) {
50267
+ return c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d
50268
+ }
50269
+
50270
+ // "Light" .trim() for blocks (headers, paragraphs), where unicode spaces
50271
+ // should be preserved.
50272
+ function asciiTrim (str) {
50273
+ let start = 0;
50274
+ for (; start < str.length; start++) {
50275
+ if (!isAsciiTrimmable(str.charCodeAt(start))) {
50276
+ break
50277
+ }
50278
+ }
50279
+ let end = str.length - 1;
50280
+ for (; end >= start; end--) {
50281
+ if (!isAsciiTrimmable(str.charCodeAt(end))) {
50282
+ break
50283
+ }
50284
+ }
50285
+ return str.slice(start, end + 1)
50286
+ }
50287
+
50165
50288
  // Re-export libraries commonly used in both markdown-it and its plugins,
50166
50289
  // so plugins won't have to depend on them explicitly, which reduces their
50167
50290
  // bundled size (e.g. a browser build).
@@ -50171,6 +50294,7 @@ ${indentedChild}`;
50171
50294
  var utils = /*#__PURE__*/Object.freeze({
50172
50295
  __proto__: null,
50173
50296
  arrayReplaceAt: arrayReplaceAt,
50297
+ asciiTrim: asciiTrim,
50174
50298
  assign: assign$1,
50175
50299
  escapeHtml: escapeHtml,
50176
50300
  escapeRE: escapeRE$1,
@@ -50178,6 +50302,7 @@ ${indentedChild}`;
50178
50302
  has: has,
50179
50303
  isMdAsciiPunct: isMdAsciiPunct,
50180
50304
  isPunctChar: isPunctChar,
50305
+ isPunctCharCode: isPunctCharCode,
50181
50306
  isSpace: isSpace,
50182
50307
  isString: isString$1,
50183
50308
  isValidEntityCode: isValidEntityCode,
@@ -51541,14 +51666,36 @@ ${indentedChild}`;
51541
51666
  const QUOTE_RE = /['"]/g;
51542
51667
  const APOSTROPHE$1 = '\u2019'; /* ’ */
51543
51668
 
51544
- function replaceAt (str, index, ch) {
51545
- return str.slice(0, index) + ch + str.slice(index + 1)
51669
+ function addReplacement (replacements, tokenIdx, pos, ch) {
51670
+ if (!replacements[tokenIdx]) {
51671
+ replacements[tokenIdx] = [];
51672
+ }
51673
+
51674
+ replacements[tokenIdx].push({ pos, ch });
51675
+ }
51676
+
51677
+ function applyReplacements (str, replacements) {
51678
+ let result = '';
51679
+ let lastPos = 0;
51680
+
51681
+ replacements.sort((a, b) => a.pos - b.pos);
51682
+
51683
+ for (let i = 0; i < replacements.length; i++) {
51684
+ const replacement = replacements[i];
51685
+
51686
+ result += str.slice(lastPos, replacement.pos) + replacement.ch;
51687
+ lastPos = replacement.pos + 1;
51688
+ }
51689
+
51690
+ return result + str.slice(lastPos)
51546
51691
  }
51547
51692
 
51548
51693
  function process_inlines (tokens, state) {
51549
51694
  let j;
51550
51695
 
51551
51696
  const stack = [];
51697
+ // token index -> list of replacements in the original token content
51698
+ const replacements = {};
51552
51699
 
51553
51700
  for (let i = 0; i < tokens.length; i++) {
51554
51701
  const token = tokens[i];
@@ -51562,9 +51709,9 @@ ${indentedChild}`;
51562
51709
 
51563
51710
  if (token.type !== 'text') { continue }
51564
51711
 
51565
- let text = token.content;
51712
+ const text = token.content;
51566
51713
  let pos = 0;
51567
- let max = text.length;
51714
+ const max = text.length;
51568
51715
 
51569
51716
  /* eslint no-labels:0,block-scoped-var:0 */
51570
51717
  OUTER:
@@ -51612,8 +51759,8 @@ ${indentedChild}`;
51612
51759
  }
51613
51760
  }
51614
51761
 
51615
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
51616
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
51762
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
51763
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
51617
51764
 
51618
51765
  const isLastWhiteSpace = isWhiteSpace(lastChar);
51619
51766
  const isNextWhiteSpace = isWhiteSpace(nextChar);
@@ -51656,7 +51803,7 @@ ${indentedChild}`;
51656
51803
  if (!canOpen && !canClose) {
51657
51804
  // middle of word
51658
51805
  if (isSingle) {
51659
- token.content = replaceAt(token.content, t.index, APOSTROPHE$1);
51806
+ addReplacement(replacements, i, t.index, APOSTROPHE$1);
51660
51807
  }
51661
51808
  continue
51662
51809
  }
@@ -51679,18 +51826,8 @@ ${indentedChild}`;
51679
51826
  closeQuote = state.md.options.quotes[1];
51680
51827
  }
51681
51828
 
51682
- // replace token.content *before* tokens[item.token].content,
51683
- // because, if they are pointing at the same token, replaceAt
51684
- // could mess up indices when quote length != 1
51685
- token.content = replaceAt(token.content, t.index, closeQuote);
51686
- tokens[item.token].content = replaceAt(
51687
- tokens[item.token].content, item.pos, openQuote);
51688
-
51689
- pos += closeQuote.length - 1;
51690
- if (item.token === i) { pos += openQuote.length - 1; }
51691
-
51692
- text = token.content;
51693
- max = text.length;
51829
+ addReplacement(replacements, i, t.index, closeQuote);
51830
+ addReplacement(replacements, item.token, item.pos, openQuote);
51694
51831
 
51695
51832
  stack.length = j;
51696
51833
  continue OUTER
@@ -51706,10 +51843,14 @@ ${indentedChild}`;
51706
51843
  level: thisLevel
51707
51844
  });
51708
51845
  } else if (canClose && isSingle) {
51709
- token.content = replaceAt(token.content, t.index, APOSTROPHE$1);
51846
+ addReplacement(replacements, i, t.index, APOSTROPHE$1);
51710
51847
  }
51711
51848
  }
51712
51849
  }
51850
+
51851
+ Object.keys(replacements).forEach(function (tokenIdx) {
51852
+ tokens[tokenIdx].content = applyReplacements(tokens[tokenIdx].content, replacements[tokenIdx]);
51853
+ });
51713
51854
  }
51714
51855
 
51715
51856
  function smartquotes (state) {
@@ -53313,11 +53454,22 @@ ${indentedChild}`;
53313
53454
 
53314
53455
  let nextLine = startLine + 1;
53315
53456
 
53457
+ // Block types 6 and 7 (the only ones whose end condition is a blank line)
53458
+ // have `/^$/` as their closing regexp. For all other types (1-5, e.g.
53459
+ // `<!--` comments), a blank line is regular content and must not terminate
53460
+ // the block - it ends only when its closing sequence is found.
53461
+ const endsOnBlankLine = HTML_SEQUENCES[i][1].test('');
53462
+
53316
53463
  // If we are here - we detected HTML block.
53317
53464
  // Let's roll down till block end.
53318
53465
  if (!HTML_SEQUENCES[i][1].test(lineText)) {
53319
53466
  for (; nextLine < endLine; nextLine++) {
53320
- if (state.sCount[nextLine] < state.blkIndent) { break }
53467
+ if (state.sCount[nextLine] < state.blkIndent) {
53468
+ // An outdented blank line shouldn't end a block that doesn't end on a
53469
+ // blank line (e.g. a `<!--` comment inside a list item). Such blocks
53470
+ // must continue until their closing sequence regardless of indent.
53471
+ if (endsOnBlankLine || !state.isEmpty(nextLine)) { break }
53472
+ }
53321
53473
 
53322
53474
  pos = state.bMarks[nextLine] + state.tShift[nextLine];
53323
53475
  max = state.eMarks[nextLine];
@@ -53380,7 +53532,7 @@ ${indentedChild}`;
53380
53532
  token_o.map = [startLine, state.line];
53381
53533
 
53382
53534
  const token_i = state.push('inline', '', 0);
53383
- token_i.content = state.src.slice(pos, max).trim();
53535
+ token_i.content = asciiTrim(state.src.slice(pos, max));
53384
53536
  token_i.map = [startLine, state.line];
53385
53537
  token_i.children = [];
53386
53538
 
@@ -53392,6 +53544,7 @@ ${indentedChild}`;
53392
53544
 
53393
53545
  // lheading (---, ===)
53394
53546
 
53547
+
53395
53548
  function lheading (state, startLine, endLine/*, silent */) {
53396
53549
  const terminatorRules = state.md.block.ruler.getRules('paragraph');
53397
53550
 
@@ -53449,10 +53602,11 @@ ${indentedChild}`;
53449
53602
 
53450
53603
  if (!level) {
53451
53604
  // Didn't find valid underline
53605
+ state.parentType = oldParentType;
53452
53606
  return false
53453
53607
  }
53454
53608
 
53455
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
53609
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
53456
53610
 
53457
53611
  state.line = nextLine + 1;
53458
53612
 
@@ -53475,6 +53629,7 @@ ${indentedChild}`;
53475
53629
 
53476
53630
  // Paragraph
53477
53631
 
53632
+
53478
53633
  function paragraph (state, startLine, endLine) {
53479
53634
  const terminatorRules = state.md.block.ruler.getRules('paragraph');
53480
53635
  const oldParentType = state.parentType;
@@ -53501,7 +53656,7 @@ ${indentedChild}`;
53501
53656
  if (terminate) { break }
53502
53657
  }
53503
53658
 
53504
- const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();
53659
+ const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
53505
53660
 
53506
53661
  state.line = nextLine;
53507
53662
 
@@ -53728,8 +53883,30 @@ ${indentedChild}`;
53728
53883
  const max = this.posMax;
53729
53884
  const marker = this.src.charCodeAt(start);
53730
53885
 
53731
- // treat beginning of the line as a whitespace
53732
- const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20;
53886
+ // Astral characters below are combined manually, because .codePointAt()
53887
+ // does not guarantee numeric type output. And we don't wish JIT cache issues.
53888
+ // The broken surrogate pairs are evaluated as U+FFFD to prevent possible
53889
+ // crashes.
53890
+
53891
+ let lastChar;
53892
+ if (start === 0) {
53893
+ // treat beginning of the line as a whitespace
53894
+ lastChar = 0x20;
53895
+ } else if (start === 1) {
53896
+ lastChar = this.src.charCodeAt(0);
53897
+ if ((lastChar & 0xF800) === 0xD800) { lastChar = 0xFFFD; }
53898
+ } else {
53899
+ lastChar = this.src.charCodeAt(start - 1);
53900
+ if ((lastChar & 0xFC00) === 0xDC00) {
53901
+ // low surrogate => add high one, replace broken pair with U+FFFD
53902
+ const highSurr = this.src.charCodeAt(start - 2);
53903
+ lastChar = (highSurr & 0xFC00) === 0xD800
53904
+ ? 0x10000 + ((highSurr - 0xD800) << 10) + (lastChar - 0xDC00)
53905
+ : 0xFFFD;
53906
+ } else if ((lastChar & 0xFC00) === 0xD800) {
53907
+ lastChar = 0xFFFD;
53908
+ }
53909
+ }
53733
53910
 
53734
53911
  let pos = start;
53735
53912
  while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }
@@ -53737,10 +53914,19 @@ ${indentedChild}`;
53737
53914
  const count = pos - start;
53738
53915
 
53739
53916
  // treat end of the line as a whitespace
53740
- const nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
53917
+ let nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
53918
+ if ((nextChar & 0xFC00) === 0xD800) {
53919
+ // high surrogate => add low one, replace broken pair with U+FFFD
53920
+ const lowSurr = this.src.charCodeAt(pos + 1);
53921
+ nextChar = (lowSurr & 0xFC00) === 0xDC00
53922
+ ? 0x10000 + ((nextChar - 0xD800) << 10) + (lowSurr - 0xDC00)
53923
+ : 0xFFFD;
53924
+ } else if ((nextChar & 0xFC00) === 0xDC00) {
53925
+ nextChar = 0xFFFD;
53926
+ }
53741
53927
 
53742
- const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
53743
- const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
53928
+ const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
53929
+ const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
53744
53930
 
53745
53931
  const isLastWhiteSpace = isWhiteSpace(lastChar);
53746
53932
  const isNextWhiteSpace = isWhiteSpace(nextChar);
@@ -54767,7 +54953,7 @@ ${indentedChild}`;
54767
54953
  } else {
54768
54954
  const match = state.src.slice(pos).match(NAMED_RE);
54769
54955
  if (match) {
54770
- const decoded = decodeHTML(match[0]);
54956
+ const decoded = decodeHTMLStrict(match[0]);
54771
54957
  if (decoded !== match[0]) {
54772
54958
  if (!silent) {
54773
54959
  const token = state.push('text_special', '', 0);
@@ -55429,11 +55615,6 @@ ${indentedChild}`;
55429
55615
  // DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead
55430
55616
  const tlds_default = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|');
55431
55617
 
55432
- function resetScanCache (self) {
55433
- self.__index__ = -1;
55434
- self.__text_cache__ = '';
55435
- }
55436
-
55437
55618
  function createValidator (re) {
55438
55619
  return function (text, pos) {
55439
55620
  const tail = text.slice(pos);
@@ -55472,8 +55653,11 @@ ${indentedChild}`;
55472
55653
  function untpl (tpl) { return tpl.replace('%TLDS%', re.src_tlds) }
55473
55654
 
55474
55655
  re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), 'i');
55656
+ re.email_fuzzy_global = RegExp(untpl(re.tpl_email_fuzzy), 'ig');
55475
55657
  re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), 'i');
55658
+ re.link_fuzzy_global = RegExp(untpl(re.tpl_link_fuzzy), 'ig');
55476
55659
  re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'i');
55660
+ re.link_no_ip_fuzzy_global = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'ig');
55477
55661
  re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), 'i');
55478
55662
 
55479
55663
  //
@@ -55567,12 +55751,6 @@ ${indentedChild}`;
55567
55751
  '(' + self.re.schema_test.source + ')|(' + self.re.host_fuzzy_test.source + ')|@',
55568
55752
  'i'
55569
55753
  );
55570
-
55571
- //
55572
- // Cleanup
55573
- //
55574
-
55575
- resetScanCache(self);
55576
55754
  }
55577
55755
 
55578
55756
  /**
@@ -55580,55 +55758,45 @@ ${indentedChild}`;
55580
55758
  *
55581
55759
  * Match result. Single element of array, returned by [[LinkifyIt#match]]
55582
55760
  **/
55583
- function Match (self, shift) {
55584
- const start = self.__index__;
55585
- const end = self.__last_index__;
55586
- const text = self.__text_cache__.slice(start, end);
55761
+ function Match (text, schema, index, lastIndex) {
55762
+ const raw = text.slice(index, lastIndex);
55587
55763
 
55588
55764
  /**
55589
55765
  * Match#schema -> String
55590
55766
  *
55591
55767
  * Prefix (protocol) for matched string.
55592
55768
  **/
55593
- this.schema = self.__schema__.toLowerCase();
55769
+ this.schema = schema.toLowerCase();
55594
55770
  /**
55595
55771
  * Match#index -> Number
55596
55772
  *
55597
55773
  * First position of matched string.
55598
55774
  **/
55599
- this.index = start + shift;
55775
+ this.index = index;
55600
55776
  /**
55601
55777
  * Match#lastIndex -> Number
55602
55778
  *
55603
55779
  * Next position after matched string.
55604
55780
  **/
55605
- this.lastIndex = end + shift;
55781
+ this.lastIndex = lastIndex;
55606
55782
  /**
55607
55783
  * Match#raw -> String
55608
55784
  *
55609
55785
  * Matched string.
55610
55786
  **/
55611
- this.raw = text;
55787
+ this.raw = raw;
55612
55788
  /**
55613
55789
  * Match#text -> String
55614
55790
  *
55615
55791
  * Notmalized text of matched string.
55616
55792
  **/
55617
- this.text = text;
55793
+ this.text = raw;
55618
55794
  /**
55619
55795
  * Match#url -> String
55620
55796
  *
55621
55797
  * Normalized url of matched string.
55622
55798
  **/
55623
- this.url = text;
55624
- }
55625
-
55626
- function createMatch (self, shift) {
55627
- const match = new Match(self, shift);
55628
-
55629
- self.__compiled__[match.schema].normalize(match, self);
55630
-
55631
- return match
55799
+ this.url = raw;
55632
55800
  }
55633
55801
 
55634
55802
  /**
@@ -55683,12 +55851,6 @@ ${indentedChild}`;
55683
55851
 
55684
55852
  this.__opts__ = assign({}, defaultOptions, options);
55685
55853
 
55686
- // Cache last tested result. Used to skip repeating steps on next `match` call.
55687
- this.__index__ = -1;
55688
- this.__last_index__ = -1; // Next scan position
55689
- this.__schema__ = '';
55690
- this.__text_cache__ = '';
55691
-
55692
55854
  this.__schemas__ = assign({}, defaultSchemas, schemas);
55693
55855
  this.__compiled__ = {};
55694
55856
 
@@ -55730,69 +55892,38 @@ ${indentedChild}`;
55730
55892
  * Searches linkifiable pattern and returns `true` on success or `false` on fail.
55731
55893
  **/
55732
55894
  LinkifyIt.prototype.test = function test (text) {
55733
- // Reset scan cache
55734
- this.__text_cache__ = text;
55735
- this.__index__ = -1;
55736
-
55737
55895
  if (!text.length) { return false }
55738
55896
 
55739
- let m, ml, me, len, shift, next, re, tld_pos, at_pos;
55897
+ let m, re;
55740
55898
 
55741
55899
  // try to scan for link with schema - that's the most simple rule
55742
55900
  if (this.re.schema_test.test(text)) {
55743
55901
  re = this.re.schema_search;
55744
55902
  re.lastIndex = 0;
55745
55903
  while ((m = re.exec(text)) !== null) {
55746
- len = this.testSchemaAt(text, m[2], re.lastIndex);
55747
- if (len) {
55748
- this.__schema__ = m[2];
55749
- this.__index__ = m.index + m[1].length;
55750
- this.__last_index__ = m.index + m[0].length + len;
55751
- break
55752
- }
55904
+ if (this.testSchemaAt(text, m[2], re.lastIndex)) { return true }
55753
55905
  }
55754
55906
  }
55755
55907
 
55756
55908
  if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {
55757
55909
  // guess schemaless links
55758
- tld_pos = text.search(this.re.host_fuzzy_test);
55759
- if (tld_pos >= 0) {
55760
- // if tld is located after found link - no need to check fuzzy pattern
55761
- if (this.__index__ < 0 || tld_pos < this.__index__) {
55762
- if ((ml = text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) {
55763
- shift = ml.index + ml[1].length;
55764
-
55765
- if (this.__index__ < 0 || shift < this.__index__) {
55766
- this.__schema__ = '';
55767
- this.__index__ = shift;
55768
- this.__last_index__ = ml.index + ml[0].length;
55769
- }
55770
- }
55910
+ if (text.search(this.re.host_fuzzy_test) >= 0) {
55911
+ if (text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy) !== null) {
55912
+ return true
55771
55913
  }
55772
55914
  }
55773
55915
  }
55774
55916
 
55775
55917
  if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {
55776
55918
  // guess schemaless emails
55777
- at_pos = text.indexOf('@');
55778
- if (at_pos >= 0) {
55919
+ if (text.indexOf('@') >= 0) {
55779
55920
  // We can't skip this check, because this cases are possible:
55780
55921
  // 192.168.1.1@gmail.com, my.in@example.com
55781
- if ((me = text.match(this.re.email_fuzzy)) !== null) {
55782
- shift = me.index + me[1].length;
55783
- next = me.index + me[0].length;
55784
-
55785
- if (this.__index__ < 0 || shift < this.__index__ ||
55786
- (shift === this.__index__ && next > this.__last_index__)) {
55787
- this.__schema__ = 'mailto:';
55788
- this.__index__ = shift;
55789
- this.__last_index__ = next;
55790
- }
55791
- }
55922
+ if (text.match(this.re.email_fuzzy) !== null) { return true }
55792
55923
  }
55793
55924
  }
55794
55925
 
55795
- return this.__index__ >= 0
55926
+ return false
55796
55927
  };
55797
55928
 
55798
55929
  /**
@@ -55841,23 +55972,88 @@ ${indentedChild}`;
55841
55972
  **/
55842
55973
  LinkifyIt.prototype.match = function match (text) {
55843
55974
  const result = [];
55844
- let shift = 0;
55975
+ const type_schemed = [];
55976
+ const type_fuzzy_link = [];
55977
+ const type_fuzzy_email = [];
55978
+ let m, len, re;
55845
55979
 
55846
- // Try to take previous element from cache, if .test() called before
55847
- if (this.__index__ >= 0 && this.__text_cache__ === text) {
55848
- result.push(createMatch(this, shift));
55849
- shift = this.__last_index__;
55980
+ function choose (a, b) {
55981
+ if (!a) { return b }
55982
+ if (!b) { return a }
55983
+ if (a.index !== b.index) { return a.index < b.index ? a : b }
55984
+ return a.lastIndex >= b.lastIndex ? a : b
55850
55985
  }
55851
55986
 
55852
- // Cut head if cache was used
55853
- let tail = shift ? text.slice(shift) : text;
55987
+ if (!text.length) { return null }
55854
55988
 
55855
- // Scan string until end reached
55856
- while (this.test(tail)) {
55857
- result.push(createMatch(this, shift));
55989
+ // scan for links with schema
55990
+ if (this.re.schema_test.test(text)) {
55991
+ re = this.re.schema_search;
55992
+ re.lastIndex = 0;
55993
+ while ((m = re.exec(text)) !== null) {
55994
+ len = this.testSchemaAt(text, m[2], re.lastIndex);
55995
+ if (len) {
55996
+ type_schemed.push({
55997
+ schema: m[2],
55998
+ index: m.index + m[1].length,
55999
+ lastIndex: m.index + m[0].length + len
56000
+ });
56001
+ }
56002
+ }
56003
+ }
55858
56004
 
55859
- tail = tail.slice(this.__last_index__);
55860
- shift += this.__last_index__;
56005
+ if (this.__opts__.fuzzyLink && this.__compiled__['http:']) {
56006
+ re = this.__opts__.fuzzyIP ? this.re.link_fuzzy_global : this.re.link_no_ip_fuzzy_global;
56007
+ re.lastIndex = 0;
56008
+ while ((m = re.exec(text)) !== null) {
56009
+ type_fuzzy_link.push({
56010
+ schema: '',
56011
+ index: m.index + m[1].length,
56012
+ lastIndex: m.index + m[0].length
56013
+ });
56014
+ }
56015
+ }
56016
+
56017
+ if (this.__opts__.fuzzyEmail && this.__compiled__['mailto:']) {
56018
+ re = this.re.email_fuzzy_global;
56019
+ re.lastIndex = 0;
56020
+ while ((m = re.exec(text)) !== null) {
56021
+ type_fuzzy_email.push({
56022
+ schema: 'mailto:',
56023
+ index: m.index + m[1].length,
56024
+ lastIndex: m.index + m[0].length
56025
+ });
56026
+ }
56027
+ }
56028
+
56029
+ const indexes = [0, 0, 0];
56030
+ let lastIndex = 0;
56031
+
56032
+ for (;;) {
56033
+ const candidates = [
56034
+ type_schemed[indexes[0]],
56035
+ type_fuzzy_email[indexes[1]],
56036
+ type_fuzzy_link[indexes[2]]
56037
+ ];
56038
+
56039
+ const candidate = choose(choose(candidates[0], candidates[1]), candidates[2]);
56040
+
56041
+ if (!candidate) { break }
56042
+
56043
+ if (candidate === candidates[0]) {
56044
+ indexes[0]++;
56045
+ } else if (candidate === candidates[1]) {
56046
+ indexes[1]++;
56047
+ } else {
56048
+ indexes[2]++;
56049
+ }
56050
+
56051
+ if (candidate.index < lastIndex) { continue }
56052
+
56053
+ const match = new Match(text, candidate.schema, candidate.index, candidate.lastIndex);
56054
+ this.__compiled__[match.schema].normalize(match, this);
56055
+ result.push(match);
56056
+ lastIndex = candidate.lastIndex;
55861
56057
  }
55862
56058
 
55863
56059
  if (result.length) {
@@ -55874,10 +56070,6 @@ ${indentedChild}`;
55874
56070
  * of the string, and null otherwise.
55875
56071
  **/
55876
56072
  LinkifyIt.prototype.matchAtStart = function matchAtStart (text) {
55877
- // Reset scan cache
55878
- this.__text_cache__ = text;
55879
- this.__index__ = -1;
55880
-
55881
56073
  if (!text.length) return null
55882
56074
 
55883
56075
  const m = this.re.schema_at_start.exec(text);
@@ -55886,11 +56078,10 @@ ${indentedChild}`;
55886
56078
  const len = this.testSchemaAt(text, m[2], m[0].length);
55887
56079
  if (!len) return null
55888
56080
 
55889
- this.__schema__ = m[2];
55890
- this.__index__ = m.index + m[1].length;
55891
- this.__last_index__ = m.index + m[0].length + len;
56081
+ const match = new Match(text, m[2], m.index + m[1].length, m.index + m[0].length + len);
55892
56082
 
55893
- return createMatch(this, 0)
56083
+ this.__compiled__[match.schema].normalize(match, this);
56084
+ return match
55894
56085
  };
55895
56086
 
55896
56087
  /** chainable
@@ -56942,7 +57133,7 @@ ${indentedChild}`;
56942
57133
  * ```javascript
56943
57134
  * var md = require('markdown-it')()
56944
57135
  * .set({ html: true, breaks: true })
56945
- * .set({ typographer, true });
57136
+ * .set({ typographer: true });
56946
57137
  * ```
56947
57138
  *
56948
57139
  * __Note:__ To achieve the best possible performance, don't modify a
@@ -58890,7 +59081,7 @@ ${indentedChild}`;
58890
59081
  // THIS FILE IS AUTOMATICALLY GENERATED DO NOT EDIT DIRECTLY
58891
59082
  // See update-tlds.js for encoding/decoding format
58892
59083
  // https://data.iana.org/TLD/tlds-alpha-by-domain.txt
58893
- const encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';
59084
+ const encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2odyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rck0msd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2oodside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';
58894
59085
  // Internationalized domain names containing non-ASCII
58895
59086
  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';
58896
59087
 
@@ -60282,11 +60473,6 @@ ${indentedChild}`;
60282
60473
  tt(Email$1, DOT, EmailDomainDot);
60283
60474
  tt(Email$1, HYPHEN, EmailDomainHyphen);
60284
60475
 
60285
- // Final possible email states
60286
- const EmailColon = tt(Email$1, COLON); // URL followed by colon (potential port number here)
60287
- /*const EmailColonPort = */
60288
- ta(EmailColon, groups.numeric, Email); // URL followed by colon and port number
60289
-
60290
60476
  // Account for dots and hyphens. Hyphens are usually parts of domain names
60291
60477
  // (but not TLDs)
60292
60478
  const DomainHyphen = tt(Domain, HYPHEN); // domain followed by hyphen
@@ -60369,16 +60555,18 @@ ${indentedChild}`;
60369
60555
  // Continue not accepting for open brackets
60370
60556
  tt(UrlNonaccept, OPEN, UrlOpen);
60371
60557
 
60372
- // Closing bracket component. This character WILL be included in the URL
60373
- tt(UrlOpen, CLOSE, Url$1);
60374
-
60375
- // URL that beings with an opening bracket, followed by a symbols.
60558
+ // URL that begins with an opening bracket, followed by a symbols.
60376
60559
  // Note that the final state can still be `UrlOpen` (if the URL has a
60377
60560
  // single opening bracket for some reason).
60378
60561
  const UrlOpenQ = makeState(Url);
60379
60562
  ta(UrlOpen, qsAccepting, UrlOpenQ);
60380
60563
  const UrlOpenSyms = makeState(); // UrlOpen followed by some symbols it cannot end it
60381
- ta(UrlOpen, qsNonAccepting);
60564
+ ta(UrlOpen, qsNonAccepting, UrlOpenSyms);
60565
+
60566
+ // Closing bracket component. This character WILL be included in the URL.
60567
+ // Must come after qsNonAccepting (which includes all close-bracket tokens)
60568
+ // so that CLOSE -> Url wins over CLOSE -> UrlOpenSyms.
60569
+ tt(UrlOpen, CLOSE, Url$1);
60382
60570
 
60383
60571
  // URL that begins with an opening bracket, followed by some symbols
60384
60572
  ta(UrlOpenQ, qsAccepting, UrlOpenQ);
@@ -61132,6 +61320,25 @@ ${indentedChild}`;
61132
61320
  return [inputRule];
61133
61321
  }
61134
61322
  });
61323
+ function isSameLineOrderedListToken(token) {
61324
+ var _a, _b;
61325
+ const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0];
61326
+ return Boolean(
61327
+ token.text && ((_b = token.tokens) == null ? void 0 : _b.length) === 1 && (nestedToken == null ? void 0 : nestedToken.type) === "list" && nestedToken.ordered && nestedToken.raw === token.text
61328
+ );
61329
+ }
61330
+ function parseSameLineOrderedListText(text, helpers) {
61331
+ if (helpers.tokenizeInline) {
61332
+ return helpers.parseInline(helpers.tokenizeInline(text));
61333
+ }
61334
+ return helpers.parseInline([
61335
+ {
61336
+ type: "text",
61337
+ raw: text,
61338
+ text
61339
+ }
61340
+ ]);
61341
+ }
61135
61342
  var ListItem = Node3.create({
61136
61343
  name: "listItem",
61137
61344
  addOptions() {
@@ -61162,6 +61369,17 @@ ${indentedChild}`;
61162
61369
  const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
61163
61370
  let content = [];
61164
61371
  if (token.tokens && token.tokens.length > 0) {
61372
+ if (isSameLineOrderedListToken(token)) {
61373
+ return {
61374
+ type: "listItem",
61375
+ content: [
61376
+ {
61377
+ type: "paragraph",
61378
+ content: parseSameLineOrderedListText(token.text || "", helpers)
61379
+ }
61380
+ ]
61381
+ };
61382
+ }
61165
61383
  const hasParagraphTokens = token.tokens.some((t) => t.type === "paragraph");
61166
61384
  if (hasParagraphTokens) {
61167
61385
  content = parseBlockChildren(token.tokens);
@@ -63805,6 +64023,7 @@ ${indentedChild}`;
63805
64023
  addOptions() {
63806
64024
  return {
63807
64025
  limit: null,
64026
+ autoTrim: true,
63808
64027
  mode: "textSize",
63809
64028
  textCounter: (text) => text.length,
63810
64029
  wordCounter: (text) => text.split(" ").filter((word) => word !== "").length
@@ -63842,7 +64061,8 @@ ${indentedChild}`;
63842
64061
  return;
63843
64062
  }
63844
64063
  const limit = this.options.limit;
63845
- if (limit === null || limit === void 0 || limit === 0) {
64064
+ const autoTrim = this.options.autoTrim;
64065
+ if (limit === null || limit === void 0 || limit === 0 || autoTrim === false) {
63846
64066
  initialEvaluationDone = true;
63847
64067
  return;
63848
64068
  }
@@ -63985,10 +64205,114 @@ ${indentedChild}`;
63985
64205
  };
63986
64206
  }
63987
64207
  });
64208
+ function createPlaceholderDecoration(options) {
64209
+ const {
64210
+ editor,
64211
+ placeholder,
64212
+ dataAttribute,
64213
+ pos,
64214
+ node,
64215
+ isEmptyDoc,
64216
+ hasAnchor,
64217
+ classes: { emptyNode, emptyEditor }
64218
+ } = options;
64219
+ const classes = [emptyNode];
64220
+ if (isEmptyDoc) {
64221
+ classes.push(emptyEditor);
64222
+ }
64223
+ return Decoration.node(pos, pos + node.nodeSize, {
64224
+ class: classes.join(" "),
64225
+ [dataAttribute]: typeof placeholder === "function" ? placeholder({
64226
+ editor,
64227
+ node,
64228
+ pos,
64229
+ hasAnchor
64230
+ }) : placeholder
64231
+ });
64232
+ }
64233
+
64234
+ // src/placeholder/utils/findScrollParent.ts
64235
+ function isScrollable(el) {
64236
+ const style = getComputedStyle(el);
64237
+ const overflow = `${style.overflow} ${style.overflowY} ${style.overflowX}`;
64238
+ return /auto|scroll|overlay/.test(overflow);
64239
+ }
64240
+ function findScrollParent(element) {
64241
+ let el = element;
64242
+ while (el) {
64243
+ if (isScrollable(el)) {
64244
+ return el;
64245
+ }
64246
+ const parent = el.parentElement;
64247
+ if (!parent) {
64248
+ const root = el.getRootNode();
64249
+ if (root instanceof ShadowRoot) {
64250
+ el = root.host;
64251
+ continue;
64252
+ }
64253
+ return window;
64254
+ }
64255
+ el = parent;
64256
+ }
64257
+ return window;
64258
+ }
64259
+
64260
+ // src/placeholder/utils/getViewportBoundaryPositions.ts
64261
+ function getContainerRect(container) {
64262
+ if (container === window) {
64263
+ return { top: 0, bottom: window.innerHeight };
64264
+ }
64265
+ return container.getBoundingClientRect();
64266
+ }
64267
+ function getViewportBoundaryPositions({
64268
+ doc,
64269
+ view,
64270
+ scrollContainer
64271
+ }) {
64272
+ const editorRect = view.dom.getBoundingClientRect();
64273
+ const containerRect = scrollContainer ? getContainerRect(scrollContainer) : { top: 0, bottom: window.innerHeight };
64274
+ const visibleTop = Math.max(editorRect.top, containerRect.top);
64275
+ const visibleBottom = Math.min(editorRect.bottom, containerRect.bottom);
64276
+ if (visibleTop >= visibleBottom) {
64277
+ return { top: 0, bottom: doc.content.size };
64278
+ }
64279
+ const isRTL = getComputedStyle(view.dom).direction === "rtl";
64280
+ const x = isRTL ? Math.max(editorRect.right - 2, editorRect.left + 2) : editorRect.left + 2;
64281
+ const topPos = view.posAtCoords({ left: x, top: visibleTop + 2 });
64282
+ const bottomPos = view.posAtCoords({ left: x, top: visibleBottom - 2 });
64283
+ return {
64284
+ top: topPos ? topPos.pos : 0,
64285
+ bottom: bottomPos ? bottomPos.pos : doc.content.size
64286
+ };
64287
+ }
64288
+
64289
+ // src/placeholder/utils/throttle.ts
64290
+ function throttle(fn, delay) {
64291
+ let timer = null;
64292
+ const call = ((...args) => {
64293
+ if (timer) {
64294
+ return;
64295
+ }
64296
+ fn(...args);
64297
+ timer = setTimeout(() => {
64298
+ timer = null;
64299
+ }, delay);
64300
+ });
64301
+ const cancel = () => {
64302
+ if (timer) {
64303
+ clearTimeout(timer);
64304
+ timer = null;
64305
+ }
64306
+ };
64307
+ return { call, cancel };
64308
+ }
64309
+
64310
+ // src/placeholder/placeholder.ts
63988
64311
  var DEFAULT_DATA_ATTRIBUTE = "placeholder";
63989
64312
  function preparePlaceholderAttribute(attr) {
63990
64313
  return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase();
63991
64314
  }
64315
+ var PLUGIN_KEY = new PluginKey("tiptap__placeholder");
63992
64316
  var Placeholder = Extension.create({
63993
64317
  name: "placeholder",
63994
64318
  addOptions() {
@@ -64006,40 +64330,124 @@ ${indentedChild}`;
64006
64330
  const dataAttribute = this.options.dataAttribute ? `data-${preparePlaceholderAttribute(this.options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;
64007
64331
  return [
64008
64332
  new Plugin({
64009
- key: new PluginKey("placeholder"),
64333
+ state: {
64334
+ init() {
64335
+ return {
64336
+ // null means "no viewport info yet" — decoration callback falls
64337
+ // back to full document scan until the scroll handler fires.
64338
+ topPos: null,
64339
+ bottomPos: null
64340
+ };
64341
+ },
64342
+ apply(tr, prev) {
64343
+ const meta = tr.getMeta(PLUGIN_KEY);
64344
+ if (meta == null ? void 0 : meta.positions) {
64345
+ return {
64346
+ topPos: meta.positions.top,
64347
+ bottomPos: meta.positions.bottom
64348
+ };
64349
+ }
64350
+ if (!tr.docChanged) {
64351
+ return prev;
64352
+ }
64353
+ return {
64354
+ topPos: prev.topPos !== null ? tr.mapping.map(prev.topPos) : null,
64355
+ bottomPos: prev.bottomPos !== null ? tr.mapping.map(prev.bottomPos) : null
64356
+ };
64357
+ }
64358
+ },
64359
+ key: PLUGIN_KEY,
64360
+ view(view) {
64361
+ const scrollContainer = findScrollParent(view.dom);
64362
+ const computeAndDispatch = () => {
64363
+ const positions = getViewportBoundaryPositions({
64364
+ view,
64365
+ doc: view.state.doc,
64366
+ scrollContainer
64367
+ });
64368
+ const prev = PLUGIN_KEY.getState(view.state);
64369
+ if (prev.topPos === positions.top && prev.bottomPos === positions.bottom) {
64370
+ return;
64371
+ }
64372
+ const tr = view.state.tr.setMeta(PLUGIN_KEY, { positions }).setMeta("tiptap__viewportUpdate", true);
64373
+ view.dispatch(tr);
64374
+ };
64375
+ const { call: throttledUpdate, cancel: cancelThrottle } = throttle(computeAndDispatch, 250);
64376
+ const scrollParent = scrollContainer;
64377
+ scrollParent.addEventListener("scroll", throttledUpdate, { passive: true });
64378
+ computeAndDispatch();
64379
+ return {
64380
+ update(_, prevState) {
64381
+ if (view.state.doc.content.size !== prevState.doc.content.size) {
64382
+ computeAndDispatch();
64383
+ }
64384
+ },
64385
+ destroy: () => {
64386
+ cancelThrottle();
64387
+ scrollParent.removeEventListener("scroll", throttledUpdate);
64388
+ }
64389
+ };
64390
+ },
64010
64391
  props: {
64011
64392
  decorations: ({ doc, selection }) => {
64393
+ var _a, _b;
64012
64394
  const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;
64013
- const { anchor } = selection;
64014
- const decorations = [];
64015
64395
  if (!active) {
64016
64396
  return null;
64017
64397
  }
64398
+ const { anchor } = selection;
64399
+ const decorations = [];
64018
64400
  const isEmptyDoc = this.editor.isEmpty;
64019
- doc.descendants((node, pos) => {
64020
- const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
64021
- const isEmpty = !node.isLeaf && isNodeEmpty(node);
64022
- if (!node.type.isTextblock) {
64023
- return this.options.includeChildren;
64401
+ const useResolvedPath = this.options.showOnlyCurrent && !this.options.includeChildren;
64402
+ if (useResolvedPath) {
64403
+ const resolved = doc.resolve(anchor);
64404
+ if (resolved.depth > 0) {
64405
+ const node = resolved.node(1);
64406
+ const nodeStart = resolved.before(1);
64407
+ if (node.type.isTextblock && isNodeEmpty(node)) {
64408
+ const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize;
64409
+ const decoration = createPlaceholderDecoration({
64410
+ node,
64411
+ dataAttribute,
64412
+ hasAnchor,
64413
+ placeholder: this.options.placeholder,
64414
+ classes: {
64415
+ emptyEditor: this.options.emptyEditorClass,
64416
+ emptyNode: this.options.emptyNodeClass
64417
+ },
64418
+ editor: this.editor,
64419
+ isEmptyDoc,
64420
+ pos: resolved.before(1)
64421
+ });
64422
+ decorations.push(decoration);
64423
+ }
64024
64424
  }
64025
- if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
64026
- const classes = [this.options.emptyNodeClass];
64027
- if (isEmptyDoc) {
64028
- classes.push(this.options.emptyEditorClass);
64425
+ } else {
64426
+ const pluginState = PLUGIN_KEY.getState(this.editor.state);
64427
+ const from = (_a = pluginState.topPos) != null ? _a : 0;
64428
+ const to = (_b = pluginState.bottomPos) != null ? _b : doc.content.size;
64429
+ doc.nodesBetween(from, to, (node, pos) => {
64430
+ const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
64431
+ const isEmpty = !node.isLeaf && isNodeEmpty(node);
64432
+ if (!node.type.isTextblock) {
64433
+ return this.options.includeChildren;
64029
64434
  }
64030
- const decoration = Decoration.node(pos, pos + node.nodeSize, {
64031
- class: classes.join(" "),
64032
- [dataAttribute]: typeof this.options.placeholder === "function" ? this.options.placeholder({
64435
+ if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
64436
+ const decoration = createPlaceholderDecoration({
64437
+ classes: { emptyEditor: this.options.emptyEditorClass, emptyNode: this.options.emptyNodeClass },
64033
64438
  editor: this.editor,
64439
+ isEmptyDoc,
64440
+ dataAttribute,
64441
+ hasAnchor,
64442
+ placeholder: this.options.placeholder,
64034
64443
  node,
64035
- pos,
64036
- hasAnchor
64037
- }) : this.options.placeholder
64038
- });
64039
- decorations.push(decoration);
64040
- }
64041
- return this.options.includeChildren;
64042
- });
64444
+ pos
64445
+ });
64446
+ decorations.push(decoration);
64447
+ }
64448
+ return this.options.includeChildren;
64449
+ });
64450
+ }
64043
64451
  return DecorationSet.create(doc, decorations);
64044
64452
  }
64045
64453
  }
@@ -72776,24 +73184,56 @@ focus outline in that case.
72776
73184
  </template>
72777
73185
  `;
72778
73186
 
73187
+ function createLazyMeasurementsView(count, flat, getItemKey) {
73188
+ const cache = new Array(count);
73189
+ return new Proxy(cache, {
73190
+ get(target, prop, receiver) {
73191
+ if (typeof prop === "string") {
73192
+ const c = prop.charCodeAt(0);
73193
+ if (c >= 48 && c <= 57) {
73194
+ const i = +prop;
73195
+ if (Number.isInteger(i) && i >= 0 && i < count) {
73196
+ let v = target[i];
73197
+ if (!v) {
73198
+ const s = flat[i * 2];
73199
+ v = target[i] = {
73200
+ index: i,
73201
+ key: getItemKey(i),
73202
+ start: s,
73203
+ size: flat[i * 2 + 1],
73204
+ end: s + flat[i * 2 + 1],
73205
+ lane: 0
73206
+ };
73207
+ }
73208
+ return v;
73209
+ }
73210
+ }
73211
+ if (prop === "length") return count;
73212
+ }
73213
+ return Reflect.get(target, prop, receiver);
73214
+ }
73215
+ });
73216
+ }
73217
+
72779
73218
  function memo(getDeps, fn, opts) {
72780
73219
  let deps = opts.initialDeps ?? [];
72781
73220
  let result;
72782
73221
  let isInitial = true;
72783
73222
  function memoizedFunction() {
72784
- var _a, _b, _c;
72785
- let depTime;
72786
- if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();
73223
+ var _a;
73224
+ const debugEnabled = !!opts.key && !!((_a = opts.debug) == null ? void 0 : _a.call(opts));
73225
+ let depTime = 0;
73226
+ if (debugEnabled) depTime = Date.now();
72787
73227
  const newDeps = getDeps();
72788
73228
  const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);
72789
73229
  if (!depsChanged) {
72790
73230
  return result;
72791
73231
  }
72792
73232
  deps = newDeps;
72793
- let resultTime;
72794
- if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();
73233
+ let resultTime = 0;
73234
+ if (debugEnabled) resultTime = Date.now();
72795
73235
  result = fn(...newDeps);
72796
- if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {
73236
+ if (debugEnabled) {
72797
73237
  const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
72798
73238
  const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
72799
73239
  const resultFpsPercentage = resultEndTime / 16;
@@ -72843,6 +73283,14 @@ focus outline in that case.
72843
73283
  };
72844
73284
  };
72845
73285
 
73286
+ let _isIOSResult;
73287
+ const isIOSWebKit = () => {
73288
+ if (_isIOSResult !== void 0) return _isIOSResult;
73289
+ if (typeof navigator === "undefined") return _isIOSResult = false;
73290
+ if (/iP(hone|od|ad)/.test(navigator.userAgent)) return _isIOSResult = true;
73291
+ const mtp = navigator.maxTouchPoints;
73292
+ return _isIOSResult = navigator.platform === "MacIntel" && mtp !== void 0 && mtp > 0;
73293
+ };
72846
73294
  const getRect = (element) => {
72847
73295
  const { offsetWidth, offsetHeight } = element;
72848
73296
  return { width: offsetWidth, height: offsetHeight };
@@ -72851,9 +73299,10 @@ focus outline in that case.
72851
73299
  const defaultRangeExtractor = (range) => {
72852
73300
  const start = Math.max(range.startIndex - range.overscan, 0);
72853
73301
  const end = Math.min(range.endIndex + range.overscan, range.count - 1);
72854
- const arr = [];
72855
- for (let i = start; i <= end; i++) {
72856
- arr.push(i);
73302
+ const len = end - start + 1;
73303
+ const arr = new Array(len);
73304
+ for (let i = 0; i < len; i++) {
73305
+ arr[i] = start + i;
72857
73306
  }
72858
73307
  return arr;
72859
73308
  };
@@ -72898,7 +73347,7 @@ focus outline in that case.
72898
73347
  passive: true
72899
73348
  };
72900
73349
  const supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
72901
- const observeElementOffset = (instance, cb) => {
73350
+ const observeOffset = (instance, cb, readOffset) => {
72902
73351
  const element = instance.scrollElement;
72903
73352
  if (!element) {
72904
73353
  return;
@@ -72907,24 +73356,21 @@ focus outline in that case.
72907
73356
  if (!targetWindow) {
72908
73357
  return;
72909
73358
  }
73359
+ const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
72910
73360
  let offset = 0;
72911
- const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(
73361
+ const fallback = registerScrollendEvent ? null : debounce(
72912
73362
  targetWindow,
72913
- () => {
72914
- cb(offset, false);
72915
- },
73363
+ () => cb(offset, false),
72916
73364
  instance.options.isScrollingResetDelay
72917
73365
  );
72918
73366
  const createHandler = (isScrolling) => () => {
72919
- const { horizontal, isRtl } = instance.options;
72920
- offset = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
72921
- fallback();
73367
+ offset = readOffset(element);
73368
+ fallback == null ? void 0 : fallback();
72922
73369
  cb(offset, isScrolling);
72923
73370
  };
72924
73371
  const handler = createHandler(true);
72925
73372
  const endHandler = createHandler(false);
72926
73373
  element.addEventListener("scroll", handler, addEventListenerOptions);
72927
- const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
72928
73374
  if (registerScrollendEvent) {
72929
73375
  element.addEventListener("scrollend", endHandler, addEventListenerOptions);
72930
73376
  }
@@ -72935,6 +73381,10 @@ focus outline in that case.
72935
73381
  }
72936
73382
  };
72937
73383
  };
73384
+ const observeElementOffset = (instance, cb) => observeOffset(instance, cb, (el) => {
73385
+ const { horizontal, isRtl } = instance.options;
73386
+ return horizontal ? el.scrollLeft * (isRtl && -1 || 1) : el.scrollTop;
73387
+ });
72938
73388
  const measureElement = (element, entry, instance) => {
72939
73389
  if (entry == null ? void 0 : entry.borderBoxSize) {
72940
73390
  const box = entry.borderBoxSize[0];
@@ -72947,17 +73397,17 @@ focus outline in that case.
72947
73397
  }
72948
73398
  return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
72949
73399
  };
72950
- const elementScroll = (offset, {
73400
+ const scrollWithAdjustments = (offset, {
72951
73401
  adjustments = 0,
72952
73402
  behavior
72953
73403
  }, instance) => {
72954
73404
  var _a, _b;
72955
- const toOffset = offset + adjustments;
72956
73405
  (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {
72957
- [instance.options.horizontal ? "left" : "top"]: toOffset,
73406
+ [instance.options.horizontal ? "left" : "top"]: offset + adjustments,
72958
73407
  behavior
72959
73408
  });
72960
73409
  };
73410
+ const elementScroll = scrollWithAdjustments;
72961
73411
  let Virtualizer$1 = class Virtualizer {
72962
73412
  constructor(opts) {
72963
73413
  this.unsubs = [];
@@ -72966,16 +73416,24 @@ focus outline in that case.
72966
73416
  this.isScrolling = false;
72967
73417
  this.scrollState = null;
72968
73418
  this.measurementsCache = [];
73419
+ this._flatMeasurements = null;
72969
73420
  this.itemSizeCache = /* @__PURE__ */ new Map();
73421
+ this.itemSizeCacheVersion = 0;
72970
73422
  this.laneAssignments = /* @__PURE__ */ new Map();
72971
- this.pendingMeasuredCacheIndexes = [];
73423
+ this.pendingMin = null;
72972
73424
  this.prevLanes = void 0;
72973
73425
  this.lanesChangedFlag = false;
72974
73426
  this.lanesSettling = false;
73427
+ this.pendingScrollAnchor = null;
72975
73428
  this.scrollRect = null;
72976
73429
  this.scrollOffset = null;
72977
73430
  this.scrollDirection = null;
72978
73431
  this.scrollAdjustments = 0;
73432
+ this._iosDeferredAdjustment = 0;
73433
+ this._iosTouching = false;
73434
+ this._iosJustTouchEnded = false;
73435
+ this._iosTouchEndTimerId = null;
73436
+ this._intendedScrollOffset = null;
72979
73437
  this.elementsCache = /* @__PURE__ */ new Map();
72980
73438
  this.now = () => {
72981
73439
  var _a, _b, _c;
@@ -72997,6 +73455,12 @@ focus outline in that case.
72997
73455
  const index = this.indexFromElement(node);
72998
73456
  if (!node.isConnected) {
72999
73457
  this.observer.unobserve(node);
73458
+ for (const [cacheKey, cachedNode] of this.elementsCache) {
73459
+ if (cachedNode === node) {
73460
+ this.elementsCache.delete(cacheKey);
73461
+ break;
73462
+ }
73463
+ }
73000
73464
  return;
73001
73465
  }
73002
73466
  if (this.shouldMeasureDuringScroll(index)) {
@@ -73028,10 +73492,8 @@ focus outline in that case.
73028
73492
  })();
73029
73493
  this.range = null;
73030
73494
  this.setOptions = (opts2) => {
73031
- Object.entries(opts2).forEach(([key, value]) => {
73032
- if (typeof value === "undefined") delete opts2[key];
73033
- });
73034
- this.options = {
73495
+ var _a, _b;
73496
+ const merged = {
73035
73497
  debug: false,
73036
73498
  initialOffset: 0,
73037
73499
  overscan: 1,
@@ -73051,14 +73513,50 @@ focus outline in that case.
73051
73513
  indexAttribute: "data-index",
73052
73514
  initialMeasurementsCache: [],
73053
73515
  lanes: 1,
73516
+ anchorTo: "start",
73517
+ followOnAppend: false,
73518
+ scrollEndThreshold: 1,
73054
73519
  isScrollingResetDelay: 150,
73055
73520
  enabled: true,
73056
73521
  isRtl: false,
73057
73522
  useScrollendEvent: false,
73058
73523
  useAnimationFrameWithResizeObserver: false,
73059
- laneAssignmentMode: "estimate",
73060
- ...opts2
73524
+ laneAssignmentMode: "estimate"
73061
73525
  };
73526
+ for (const key in opts2) {
73527
+ const v = opts2[key];
73528
+ if (v !== void 0) merged[key] = v;
73529
+ }
73530
+ const prevOptions = this.options;
73531
+ let anchor = null;
73532
+ let followOnAppend = null;
73533
+ if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && merged.anchorTo === "end" && this.scrollElement !== null) {
73534
+ const prevCount = prevOptions.count;
73535
+ const nextCount = merged.count;
73536
+ const measurements = this.getMeasurements();
73537
+ const prevFirstKey = prevCount > 0 ? ((_a = measurements[0]) == null ? void 0 : _a.key) ?? prevOptions.getItemKey(0) : null;
73538
+ const prevLastKey = prevCount > 0 ? ((_b = measurements[prevCount - 1]) == null ? void 0 : _b.key) ?? prevOptions.getItemKey(prevCount - 1) : null;
73539
+ const didCountChange = nextCount !== prevCount;
73540
+ const didEdgeKeysChange = didCountChange || prevCount > 0 && nextCount > 0 && (merged.getItemKey(0) !== prevFirstKey || merged.getItemKey(nextCount - 1) !== prevLastKey);
73541
+ if (didEdgeKeysChange) {
73542
+ const item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;
73543
+ if (item) {
73544
+ anchor = [item.key, this.getScrollOffset() - item.start];
73545
+ }
73546
+ const behavior = merged.followOnAppend === true ? "auto" : merged.followOnAppend || null;
73547
+ if (behavior && nextCount > prevCount && this.isAtEnd(prevOptions.scrollEndThreshold) && (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)) {
73548
+ followOnAppend = behavior;
73549
+ }
73550
+ }
73551
+ }
73552
+ this.options = merged;
73553
+ if (anchor || followOnAppend) {
73554
+ this.pendingScrollAnchor = [
73555
+ (anchor == null ? void 0 : anchor[0]) ?? null,
73556
+ (anchor == null ? void 0 : anchor[1]) ?? 0,
73557
+ followOnAppend
73558
+ ];
73559
+ }
73062
73560
  };
73063
73561
  this.notify = (sync) => {
73064
73562
  var _a, _b;
@@ -73129,21 +73627,104 @@ focus outline in that case.
73129
73627
  );
73130
73628
  this.unsubs.push(
73131
73629
  this.options.observeElementOffset(this, (offset, isScrolling) => {
73630
+ if (this._intendedScrollOffset !== null && Math.abs(offset - this._intendedScrollOffset) < 1.5) {
73631
+ offset = this._intendedScrollOffset;
73632
+ }
73633
+ this._intendedScrollOffset = null;
73132
73634
  this.scrollAdjustments = 0;
73133
73635
  this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null;
73134
73636
  this.scrollOffset = offset;
73135
73637
  this.isScrolling = isScrolling;
73638
+ this._flushIosDeferredIfReady();
73136
73639
  if (this.scrollState) {
73137
73640
  this.scheduleScrollReconcile();
73138
73641
  }
73139
73642
  this.maybeNotify();
73140
73643
  })
73141
73644
  );
73645
+ if ("addEventListener" in this.scrollElement) {
73646
+ const scrollEl = this.scrollElement;
73647
+ const onTouchStart = () => {
73648
+ this._iosTouching = true;
73649
+ this._iosJustTouchEnded = false;
73650
+ if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
73651
+ this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
73652
+ this._iosTouchEndTimerId = null;
73653
+ }
73654
+ };
73655
+ const onTouchEnd = () => {
73656
+ this._iosTouching = false;
73657
+ if (!isIOSWebKit() || this.targetWindow == null) {
73658
+ return;
73659
+ }
73660
+ this._iosJustTouchEnded = true;
73661
+ this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => {
73662
+ this._iosJustTouchEnded = false;
73663
+ this._iosTouchEndTimerId = null;
73664
+ this._flushIosDeferredIfReady();
73665
+ }, 150);
73666
+ };
73667
+ scrollEl.addEventListener(
73668
+ "touchstart",
73669
+ onTouchStart,
73670
+ addEventListenerOptions
73671
+ );
73672
+ scrollEl.addEventListener(
73673
+ "touchend",
73674
+ onTouchEnd,
73675
+ addEventListenerOptions
73676
+ );
73677
+ this.unsubs.push(() => {
73678
+ scrollEl.removeEventListener("touchstart", onTouchStart);
73679
+ scrollEl.removeEventListener("touchend", onTouchEnd);
73680
+ if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
73681
+ this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
73682
+ this._iosTouchEndTimerId = null;
73683
+ }
73684
+ });
73685
+ }
73142
73686
  this._scrollToOffset(this.getScrollOffset(), {
73143
73687
  adjustments: void 0,
73144
73688
  behavior: void 0
73145
73689
  });
73146
73690
  }
73691
+ const anchor = this.pendingScrollAnchor;
73692
+ this.pendingScrollAnchor = null;
73693
+ if (anchor && this.scrollElement && this.options.enabled) {
73694
+ const [key, offset, followOnAppend] = anchor;
73695
+ if (key !== null) {
73696
+ const { count, getItemKey } = this.options;
73697
+ let index = 0;
73698
+ while (index < count && getItemKey(index) !== key) {
73699
+ index++;
73700
+ }
73701
+ const item = index < count ? this.getMeasurements()[index] : void 0;
73702
+ if (item) {
73703
+ const delta = item.start + offset - this.getScrollOffset();
73704
+ if (!approxEqual(delta, 0)) {
73705
+ this.applyScrollAdjustment(delta);
73706
+ }
73707
+ }
73708
+ }
73709
+ if (followOnAppend) {
73710
+ this.scrollToEnd({ behavior: followOnAppend });
73711
+ }
73712
+ }
73713
+ };
73714
+ this._flushIosDeferredIfReady = () => {
73715
+ if (this._iosDeferredAdjustment === 0) return;
73716
+ if (this.isScrolling) return;
73717
+ if (this._iosTouching) return;
73718
+ if (this._iosJustTouchEnded) return;
73719
+ const cur = this.getScrollOffset();
73720
+ const max = this.getMaxScrollOffset();
73721
+ if (cur < 0 || cur > max) return;
73722
+ const delta = this._iosDeferredAdjustment;
73723
+ this._iosDeferredAdjustment = 0;
73724
+ this._scrollToOffset(cur, {
73725
+ adjustments: this.scrollAdjustments += delta,
73726
+ behavior: void 0
73727
+ });
73147
73728
  };
73148
73729
  this.rafId = null;
73149
73730
  this.getSize = () => {
@@ -73205,7 +73786,7 @@ focus outline in that case.
73205
73786
  this.lanesChangedFlag = true;
73206
73787
  }
73207
73788
  this.prevLanes = lanes;
73208
- this.pendingMeasuredCacheIndexes = [];
73789
+ this.pendingMin = null;
73209
73790
  return {
73210
73791
  count,
73211
73792
  paddingStart,
@@ -73221,7 +73802,7 @@ focus outline in that case.
73221
73802
  }
73222
73803
  );
73223
73804
  this.getMeasurements = memo(
73224
- () => [this.getMeasurementOptions(), this.itemSizeCache],
73805
+ () => [this.getMeasurementOptions(), this.itemSizeCacheVersion],
73225
73806
  ({
73226
73807
  count,
73227
73808
  paddingStart,
@@ -73230,7 +73811,8 @@ focus outline in that case.
73230
73811
  enabled,
73231
73812
  lanes,
73232
73813
  laneAssignmentMode
73233
- }, itemSizeCache) => {
73814
+ }, _itemSizeCacheVersion) => {
73815
+ const itemSizeCache = this.itemSizeCache;
73234
73816
  if (!enabled) {
73235
73817
  this.measurementsCache = [];
73236
73818
  this.itemSizeCache.clear();
@@ -73250,7 +73832,7 @@ focus outline in that case.
73250
73832
  this.measurementsCache = [];
73251
73833
  this.itemSizeCache.clear();
73252
73834
  this.laneAssignments.clear();
73253
- this.pendingMeasuredCacheIndexes = [];
73835
+ this.pendingMin = null;
73254
73836
  }
73255
73837
  if (this.measurementsCache.length === 0 && !this.lanesSettling) {
73256
73838
  this.measurementsCache = this.options.initialMeasurementsCache;
@@ -73258,11 +73840,40 @@ focus outline in that case.
73258
73840
  this.itemSizeCache.set(item.key, item.size);
73259
73841
  });
73260
73842
  }
73261
- const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
73262
- this.pendingMeasuredCacheIndexes = [];
73843
+ const min = this.lanesSettling ? 0 : this.pendingMin ?? 0;
73844
+ this.pendingMin = null;
73263
73845
  if (this.lanesSettling && this.measurementsCache.length === count) {
73264
73846
  this.lanesSettling = false;
73265
73847
  }
73848
+ if (lanes === 1) {
73849
+ const gap = this.options.gap;
73850
+ const need = count * 2;
73851
+ let flat = this._flatMeasurements;
73852
+ if (!flat || flat.length < need) {
73853
+ const next = new Float64Array(need);
73854
+ if (flat && min > 0) next.set(flat.subarray(0, min * 2));
73855
+ flat = next;
73856
+ this._flatMeasurements = flat;
73857
+ }
73858
+ let runningStart;
73859
+ if (min === 0) {
73860
+ runningStart = paddingStart + scrollMargin;
73861
+ } else {
73862
+ const prevIdx = min - 1;
73863
+ runningStart = flat[prevIdx * 2] + flat[prevIdx * 2 + 1] + gap;
73864
+ }
73865
+ for (let i = min; i < count; i++) {
73866
+ const key = getItemKey(i);
73867
+ const measuredSize = itemSizeCache.get(key);
73868
+ const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
73869
+ flat[i * 2] = runningStart;
73870
+ flat[i * 2 + 1] = size;
73871
+ runningStart += size + gap;
73872
+ }
73873
+ const view = createLazyMeasurementsView(count, flat, getItemKey);
73874
+ this.measurementsCache = view;
73875
+ return view;
73876
+ }
73266
73877
  const measurements = this.measurementsCache.slice(0, min);
73267
73878
  const laneLastIndex = new Array(lanes).fill(
73268
73879
  void 0
@@ -73325,7 +73936,11 @@ focus outline in that case.
73325
73936
  measurements,
73326
73937
  outerSize,
73327
73938
  scrollOffset,
73328
- lanes
73939
+ lanes,
73940
+ // Pass the typed array so binary search + forward-walk can
73941
+ // read start/end directly from Float64Array, skipping the
73942
+ // Proxy traps that materialize a full VirtualItem per probe.
73943
+ flat: lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null
73329
73944
  }) : null;
73330
73945
  },
73331
73946
  {
@@ -73420,23 +74035,60 @@ focus outline in that case.
73420
74035
  }
73421
74036
  };
73422
74037
  this.resizeItem = (index, size) => {
73423
- var _a;
73424
- const item = this.measurementsCache[index];
73425
- if (!item) return;
73426
- const itemSize = this.itemSizeCache.get(item.key) ?? item.size;
74038
+ var _a, _b;
74039
+ if (index < 0 || index >= this.options.count) return;
74040
+ let cachedSize;
74041
+ let itemStart;
74042
+ let key;
74043
+ const flat = this._flatMeasurements;
74044
+ if (this.options.lanes === 1 && flat !== null) {
74045
+ key = this.options.getItemKey(index);
74046
+ itemStart = flat[index * 2];
74047
+ cachedSize = flat[index * 2 + 1];
74048
+ } else {
74049
+ const item = this.measurementsCache[index];
74050
+ if (!item) return;
74051
+ key = item.key;
74052
+ itemStart = item.start;
74053
+ cachedSize = item.size;
74054
+ }
74055
+ const itemSize = this.itemSizeCache.get(key) ?? cachedSize;
73427
74056
  const delta = size - itemSize;
73428
74057
  if (delta !== 0) {
73429
- 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)) {
73430
- if (this.options.debug) {
73431
- console.info("correction", delta);
73432
- }
73433
- this._scrollToOffset(this.getScrollOffset(), {
73434
- adjustments: this.scrollAdjustments += delta,
73435
- behavior: void 0
73436
- });
74058
+ const wasAtEnd = this.options.anchorTo === "end" && ((_a = this.scrollState) == null ? void 0 : _a.behavior) !== "smooth" && this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold;
74059
+ const prevTotalSize = wasAtEnd ? this.getTotalSize() : 0;
74060
+ const shouldAdjustScroll = ((_b = this.scrollState) == null ? void 0 : _b.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(
74061
+ // The callback expects a VirtualItem; build one lazily only
74062
+ // when the consumer actually supplied a custom predicate.
74063
+ this.measurementsCache[index] ?? {
74064
+ index,
74065
+ key,
74066
+ start: itemStart,
74067
+ size: cachedSize,
74068
+ end: itemStart + cachedSize,
74069
+ lane: 0
74070
+ },
74071
+ delta,
74072
+ this
74073
+ ) : (
74074
+ // Default: adjust scrollTop only when the resize is an above-
74075
+ // viewport item AND we're not actively scrolling backward.
74076
+ // Adjusting during backward scroll fights the user's scroll
74077
+ // direction and produces the "items jump while scrolling up"
74078
+ // jank reported across many issues. Users who want the old
74079
+ // behavior can pass shouldAdjustScrollPositionOnItemSizeChange.
74080
+ itemStart < this.getScrollOffset() + this.scrollAdjustments && this.scrollDirection !== "backward"
74081
+ ));
74082
+ if (this.pendingMin === null || index < this.pendingMin) {
74083
+ this.pendingMin = index;
74084
+ }
74085
+ this.itemSizeCache.set(key, size);
74086
+ this.itemSizeCacheVersion++;
74087
+ if (wasAtEnd) {
74088
+ this.applyScrollAdjustment(this.getTotalSize() - prevTotalSize);
74089
+ } else if (shouldAdjustScroll) {
74090
+ this.applyScrollAdjustment(delta);
73437
74091
  }
73438
- this.pendingMeasuredCacheIndexes.push(item.index);
73439
- this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
73440
74092
  this.notify(false);
73441
74093
  }
73442
74094
  };
@@ -73461,14 +74113,15 @@ focus outline in that case.
73461
74113
  if (measurements.length === 0) {
73462
74114
  return void 0;
73463
74115
  }
73464
- return notUndefined(
73465
- measurements[findNearestBinarySearch(
73466
- 0,
73467
- measurements.length - 1,
73468
- (index) => notUndefined(measurements[index]).start,
73469
- offset
73470
- )]
74116
+ const flat = this._flatMeasurements;
74117
+ const useFlat = this.options.lanes === 1 && flat != null;
74118
+ const idx = findNearestBinarySearch(
74119
+ 0,
74120
+ measurements.length - 1,
74121
+ useFlat ? (i) => flat[i * 2] : (i) => notUndefined(measurements[i]).start,
74122
+ offset
73471
74123
  );
74124
+ return notUndefined(measurements[idx]);
73472
74125
  };
73473
74126
  this.getMaxScrollOffset = () => {
73474
74127
  if (!this.scrollElement) return 0;
@@ -73479,6 +74132,18 @@ focus outline in that case.
73479
74132
  return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
73480
74133
  }
73481
74134
  };
74135
+ this.getVirtualDistanceFromEnd = () => {
74136
+ return Math.max(
74137
+ this.getTotalSize() - this.getSize() - this.getScrollOffset(),
74138
+ 0
74139
+ );
74140
+ };
74141
+ this.getDistanceFromEnd = () => {
74142
+ return Math.max(this.getMaxScrollOffset() - this.getScrollOffset(), 0);
74143
+ };
74144
+ this.isAtEnd = (threshold = this.options.scrollEndThreshold) => {
74145
+ return this.getDistanceFromEnd() <= threshold;
74146
+ };
73482
74147
  this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
73483
74148
  if (!this.scrollElement) return 0;
73484
74149
  const size = this.getSize();
@@ -73568,6 +74233,18 @@ focus outline in that case.
73568
74233
  this._scrollToOffset(offset, { adjustments: void 0, behavior });
73569
74234
  this.scheduleScrollReconcile();
73570
74235
  };
74236
+ this.scrollToEnd = ({ behavior = "auto" } = {}) => {
74237
+ if (this.options.count > 0) {
74238
+ this.scrollToIndex(this.options.count - 1, {
74239
+ align: "end",
74240
+ behavior
74241
+ });
74242
+ return;
74243
+ }
74244
+ this.scrollToOffset(Math.max(this.getTotalSize() - this.getSize(), 0), {
74245
+ behavior
74246
+ });
74247
+ };
73571
74248
  this.getTotalSize = () => {
73572
74249
  var _a;
73573
74250
  const measurements = this.getMeasurements();
@@ -73575,7 +74252,13 @@ focus outline in that case.
73575
74252
  if (measurements.length === 0) {
73576
74253
  end = this.options.paddingStart;
73577
74254
  } else if (this.options.lanes === 1) {
73578
- end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
74255
+ const lastIdx = measurements.length - 1;
74256
+ const flat = this._flatMeasurements;
74257
+ if (flat != null) {
74258
+ end = flat[lastIdx * 2] + flat[lastIdx * 2 + 1];
74259
+ } else {
74260
+ end = ((_a = measurements[lastIdx]) == null ? void 0 : _a.end) ?? 0;
74261
+ }
73579
74262
  } else {
73580
74263
  const endByLane = Array(this.options.lanes).fill(null);
73581
74264
  let endIndex = measurements.length - 1;
@@ -73593,19 +74276,54 @@ focus outline in that case.
73593
74276
  0
73594
74277
  );
73595
74278
  };
74279
+ this.takeSnapshot = () => {
74280
+ const snapshot = [];
74281
+ if (this.itemSizeCache.size === 0) return snapshot;
74282
+ const m = this.getMeasurements();
74283
+ for (const item of m) {
74284
+ if (item && this.itemSizeCache.has(item.key)) {
74285
+ snapshot.push({
74286
+ index: item.index,
74287
+ key: item.key,
74288
+ start: item.start,
74289
+ size: item.size,
74290
+ end: item.end,
74291
+ lane: item.lane
74292
+ });
74293
+ }
74294
+ }
74295
+ return snapshot;
74296
+ };
73596
74297
  this._scrollToOffset = (offset, {
73597
74298
  adjustments,
73598
74299
  behavior
73599
74300
  }) => {
74301
+ this._intendedScrollOffset = offset + (adjustments ?? 0);
73600
74302
  this.options.scrollToFn(offset, { behavior, adjustments }, this);
73601
74303
  };
73602
74304
  this.measure = () => {
73603
- this.itemSizeCache = /* @__PURE__ */ new Map();
73604
- this.laneAssignments = /* @__PURE__ */ new Map();
74305
+ this.pendingMin = null;
74306
+ this.itemSizeCache.clear();
74307
+ this.laneAssignments.clear();
74308
+ this.itemSizeCacheVersion++;
73605
74309
  this.notify(false);
73606
74310
  };
73607
74311
  this.setOptions(opts);
73608
74312
  }
74313
+ applyScrollAdjustment(delta, behavior) {
74314
+ if (delta === 0) return;
74315
+ if (this.options.debug) {
74316
+ console.info("correction", delta);
74317
+ }
74318
+ if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {
74319
+ this._iosDeferredAdjustment += delta;
74320
+ } else {
74321
+ this._scrollToOffset(this.getScrollOffset(), {
74322
+ adjustments: this.scrollAdjustments += delta,
74323
+ behavior
74324
+ });
74325
+ }
74326
+ }
73609
74327
  scheduleScrollReconcile() {
73610
74328
  if (!this.targetWindow) {
73611
74329
  this.scrollState = null;
@@ -73633,17 +74351,28 @@ focus outline in that case.
73633
74351
  if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {
73634
74352
  this.scrollState.stableFrames++;
73635
74353
  if (this.scrollState.stableFrames >= STABLE_FRAMES) {
74354
+ if (this.getScrollOffset() !== targetOffset) {
74355
+ this._scrollToOffset(targetOffset, {
74356
+ adjustments: void 0,
74357
+ behavior: "auto"
74358
+ });
74359
+ }
73636
74360
  this.scrollState = null;
73637
74361
  return;
73638
74362
  }
73639
74363
  } else {
73640
74364
  this.scrollState.stableFrames = 0;
73641
74365
  if (targetChanged) {
74366
+ const viewport = this.getSize() || 600;
74367
+ const distance = Math.abs(targetOffset - this.getScrollOffset());
74368
+ const keepSmooth = this.scrollState.behavior === "smooth" && distance > viewport;
73642
74369
  this.scrollState.lastTargetOffset = targetOffset;
73643
- this.scrollState.behavior = "auto";
74370
+ if (!keepSmooth) {
74371
+ this.scrollState.behavior = "auto";
74372
+ }
73644
74373
  this._scrollToOffset(targetOffset, {
73645
74374
  adjustments: void 0,
73646
- behavior: "auto"
74375
+ behavior: keepSmooth ? "smooth" : "auto"
73647
74376
  });
73648
74377
  }
73649
74378
  }
@@ -73672,25 +74401,22 @@ focus outline in that case.
73672
74401
  measurements,
73673
74402
  outerSize,
73674
74403
  scrollOffset,
73675
- lanes
74404
+ lanes,
74405
+ flat
73676
74406
  }) {
73677
74407
  const lastIndex = measurements.length - 1;
73678
- const getOffset = (index) => measurements[index].start;
74408
+ const getStart = flat ? (index) => flat[index * 2] : (index) => measurements[index].start;
74409
+ const getEnd = flat ? (index) => flat[index * 2] + flat[index * 2 + 1] : (index) => measurements[index].end;
73679
74410
  if (measurements.length <= lanes) {
73680
74411
  return {
73681
74412
  startIndex: 0,
73682
74413
  endIndex: lastIndex
73683
74414
  };
73684
74415
  }
73685
- let startIndex = findNearestBinarySearch(
73686
- 0,
73687
- lastIndex,
73688
- getOffset,
73689
- scrollOffset
73690
- );
74416
+ let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset);
73691
74417
  let endIndex = startIndex;
73692
74418
  if (lanes === 1) {
73693
- while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {
74419
+ while (endIndex < lastIndex && getEnd(endIndex) < scrollOffset + outerSize) {
73694
74420
  endIndex++;
73695
74421
  }
73696
74422
  } else if (lanes > 1) {