ngwr 13.0.0 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +13 -6
  2. package/color-picker/styles/_index.scss +43 -5
  3. package/fesm2022/ngwr-alert.mjs +5 -5
  4. package/fesm2022/ngwr-alert.mjs.map +1 -1
  5. package/fesm2022/ngwr-back-top.mjs +11 -1
  6. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  7. package/fesm2022/ngwr-blur-text.mjs +13 -2
  8. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  9. package/fesm2022/ngwr-border-glow.mjs +12 -3
  10. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  11. package/fesm2022/ngwr-breadcrumbs.mjs +14 -3
  12. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  13. package/fesm2022/ngwr-button.mjs +4 -4
  14. package/fesm2022/ngwr-button.mjs.map +1 -1
  15. package/fesm2022/ngwr-calendar-testing.mjs +15 -0
  16. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  17. package/fesm2022/ngwr-calendar.mjs +51 -5
  18. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  19. package/fesm2022/ngwr-circular-text.mjs +20 -1
  20. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  21. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  22. package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
  23. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  24. package/fesm2022/ngwr-color-picker.mjs +89 -10
  25. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  26. package/fesm2022/ngwr-command-palette.mjs +27 -3
  27. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  28. package/fesm2022/ngwr-context-menu.mjs +13 -3
  29. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  30. package/fesm2022/ngwr-date-adapters-fns.mjs +101 -33
  31. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  32. package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
  33. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  34. package/fesm2022/ngwr-date-picker.mjs +103 -13
  35. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  36. package/fesm2022/ngwr-date.mjs +480 -79
  37. package/fesm2022/ngwr-date.mjs.map +1 -1
  38. package/fesm2022/ngwr-dialog.mjs +22 -16
  39. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  40. package/fesm2022/ngwr-directives.mjs +5 -2
  41. package/fesm2022/ngwr-directives.mjs.map +1 -1
  42. package/fesm2022/ngwr-drag-drop.mjs +30 -2
  43. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  44. package/fesm2022/ngwr-drawer.mjs +24 -18
  45. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  46. package/fesm2022/ngwr-dropdown.mjs +8 -3
  47. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  48. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  49. package/fesm2022/ngwr-event-calendar.mjs +1 -1
  50. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  51. package/fesm2022/ngwr-file-upload.mjs +52 -12
  52. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  53. package/fesm2022/ngwr-fuzzy-text.mjs +21 -4
  54. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  55. package/fesm2022/ngwr-gradient-text.mjs +9 -2
  56. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  57. package/fesm2022/ngwr-i18n-en.mjs +63 -1
  58. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  59. package/fesm2022/ngwr-i18n-ru.mjs +28 -1
  60. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  61. package/fesm2022/ngwr-i18n.mjs +150 -22
  62. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  63. package/fesm2022/ngwr-icon-adapters-feather.mjs +11 -0
  64. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  65. package/fesm2022/ngwr-icon-adapters-lucide.mjs +22 -2
  66. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  67. package/fesm2022/ngwr-icon.mjs +474 -37
  68. package/fesm2022/ngwr-icon.mjs.map +1 -1
  69. package/fesm2022/ngwr-input-number.mjs +3 -3
  70. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  71. package/fesm2022/ngwr-input-otp.mjs +21 -3
  72. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  73. package/fesm2022/ngwr-input.mjs +14 -7
  74. package/fesm2022/ngwr-input.mjs.map +1 -1
  75. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  76. package/fesm2022/ngwr-knob.mjs +20 -2
  77. package/fesm2022/ngwr-knob.mjs.map +1 -1
  78. package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
  79. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
  80. package/fesm2022/ngwr-loading-bar.mjs +21 -32
  81. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  82. package/fesm2022/ngwr-markdown.mjs +63 -11
  83. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  84. package/fesm2022/ngwr-mention.mjs +104 -14
  85. package/fesm2022/ngwr-mention.mjs.map +1 -1
  86. package/fesm2022/ngwr-overlay.mjs +36 -7
  87. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  88. package/fesm2022/ngwr-pagination-testing.mjs +11 -10
  89. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  90. package/fesm2022/ngwr-pagination.mjs +65 -30
  91. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  92. package/fesm2022/ngwr-popconfirm.mjs +3 -2
  93. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  94. package/fesm2022/ngwr-popover.mjs +2 -1
  95. package/fesm2022/ngwr-popover.mjs.map +1 -1
  96. package/fesm2022/ngwr-qr.mjs +38 -1
  97. package/fesm2022/ngwr-qr.mjs.map +1 -1
  98. package/fesm2022/ngwr-select.mjs +93 -34
  99. package/fesm2022/ngwr-select.mjs.map +1 -1
  100. package/fesm2022/ngwr-shiny-text.mjs +10 -3
  101. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  102. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  103. package/fesm2022/ngwr-squircle.mjs +2 -1
  104. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  105. package/fesm2022/ngwr-statistic.mjs +35 -4
  106. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  107. package/fesm2022/ngwr-table.mjs +35 -12
  108. package/fesm2022/ngwr-table.mjs.map +1 -1
  109. package/fesm2022/ngwr-tabs-router.mjs +158 -0
  110. package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
  111. package/fesm2022/ngwr-tabs-testing.mjs +13 -11
  112. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  113. package/fesm2022/ngwr-tabs.mjs +104 -12
  114. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  115. package/fesm2022/ngwr-textarea.mjs +20 -1
  116. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  117. package/fesm2022/ngwr-tour.mjs +1 -1
  118. package/fesm2022/ngwr-tour.mjs.map +1 -1
  119. package/fesm2022/ngwr-transfer.mjs +2 -2
  120. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  121. package/fesm2022/ngwr-tree.mjs +18 -2
  122. package/fesm2022/ngwr-tree.mjs.map +1 -1
  123. package/fesm2022/ngwr-utils.mjs +143 -1
  124. package/fesm2022/ngwr-utils.mjs.map +1 -1
  125. package/fesm2022/ngwr-version.mjs +1 -1
  126. package/fesm2022/ngwr-version.mjs.map +1 -1
  127. package/fesm2022/ngwr-window-testing.mjs +10 -2
  128. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  129. package/fesm2022/ngwr-window.mjs +4 -4
  130. package/fesm2022/ngwr-window.mjs.map +1 -1
  131. package/i18n/en.json +33 -6
  132. package/i18n/ru.json +33 -6
  133. package/llms-full.txt +20 -11
  134. package/llms.txt +47 -16
  135. package/mcp/catalog.js +3 -3
  136. package/mcp/providers.js +11 -0
  137. package/package.json +11 -3
  138. package/schematics/migrations/v13/index.js +101 -0
  139. package/schematics/migrations/v14/index.js +422 -0
  140. package/schematics/migrations.json +10 -0
  141. package/schematics/page/templates.js +1 -1
  142. package/schematics/use/symbol-map.json +1 -0
  143. package/skills/ngwr/SKILL.md +4 -1
  144. package/skills/ngwr/references/catalog.md +2 -0
  145. package/skills/ngwr/references/setup.md +4 -0
  146. package/stepper/styles/_index.scss +19 -1
  147. package/textarea/styles/_index.scss +14 -6
  148. package/toast/styles/_index.scss +12 -4
  149. package/types/ngwr-alert.d.ts +3 -3
  150. package/types/ngwr-blur-text.d.ts +8 -0
  151. package/types/ngwr-breadcrumbs.d.ts +1 -0
  152. package/types/ngwr-button.d.ts +2 -2
  153. package/types/ngwr-calendar-testing.d.ts +21 -4
  154. package/types/ngwr-calendar.d.ts +37 -0
  155. package/types/ngwr-circular-text.d.ts +9 -0
  156. package/types/ngwr-collapse.d.ts +19 -15
  157. package/types/ngwr-color-picker-testing.d.ts +10 -4
  158. package/types/ngwr-color-picker.d.ts +70 -2
  159. package/types/ngwr-command-palette.d.ts +14 -0
  160. package/types/ngwr-context-menu.d.ts +1 -1
  161. package/types/ngwr-date-adapters-fns.d.ts +71 -29
  162. package/types/ngwr-date-picker-testing.d.ts +206 -185
  163. package/types/ngwr-date-picker.d.ts +7 -0
  164. package/types/ngwr-date.d.ts +143 -13
  165. package/types/ngwr-drag-drop.d.ts +19 -0
  166. package/types/ngwr-dropdown.d.ts +1 -1
  167. package/types/ngwr-event-calendar-testing.d.ts +12 -9
  168. package/types/ngwr-file-upload.d.ts +31 -3
  169. package/types/ngwr-fuzzy-text.d.ts +5 -0
  170. package/types/ngwr-i18n.d.ts +89 -7
  171. package/types/ngwr-icon-adapters-feather.d.ts +11 -0
  172. package/types/ngwr-icon.d.ts +42 -1
  173. package/types/ngwr-input-number.d.ts +1 -1
  174. package/types/ngwr-input-otp.d.ts +3 -0
  175. package/types/ngwr-input.d.ts +11 -4
  176. package/types/ngwr-knob-testing.d.ts +8 -4
  177. package/types/ngwr-knob.d.ts +18 -0
  178. package/types/ngwr-loading-bar-router.d.ts +35 -0
  179. package/types/ngwr-loading-bar.d.ts +19 -9
  180. package/types/ngwr-mention.d.ts +13 -0
  181. package/types/ngwr-pagination-testing.d.ts +11 -10
  182. package/types/ngwr-pagination.d.ts +39 -10
  183. package/types/ngwr-popconfirm.d.ts +1 -1
  184. package/types/ngwr-popover.d.ts +1 -1
  185. package/types/ngwr-select.d.ts +65 -10
  186. package/types/ngwr-shiny-text.d.ts +1 -0
  187. package/types/ngwr-splitter-testing.d.ts +9 -4
  188. package/types/ngwr-squircle.d.ts +1 -1
  189. package/types/ngwr-statistic.d.ts +22 -2
  190. package/types/ngwr-table.d.ts +24 -5
  191. package/types/ngwr-tabs-router.d.ts +67 -0
  192. package/types/ngwr-tabs-testing.d.ts +12 -10
  193. package/types/ngwr-tabs.d.ts +103 -6
  194. package/types/ngwr-textarea.d.ts +9 -0
  195. package/types/ngwr-tree.d.ts +7 -0
  196. package/types/ngwr-utils.d.ts +79 -1
  197. package/types/ngwr-version.d.ts +1 -1
  198. package/types/ngwr-window-testing.d.ts +11 -3
  199. package/types/ngwr-window.d.ts +11 -4
  200. package/window/styles/_index.scss +1 -1
@@ -455,11 +455,44 @@ const ESCAPABLE = /[!-/:-@[-`{-~]/;
455
455
  const SCHEME_RE = /^([a-z][a-z0-9+.-]*):/i;
456
456
  const ALLOWED_SCHEMES = new Set(['http', 'https', 'mailto', 'tel', 'ftp']);
457
457
  const DATA_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|avif);base64,[a-z0-9+/=]+$/i;
458
- const AUTOLINK_RE = /^<((?:https?|mailto|tel):[^>\s]+)>/i;
458
+ // `[^<>\s]` and not `[^>\s]`: CommonMark defines autolink content as
459
+ // `[^<>\x00-\x20]*`, so `<` ends it by spec — and admitting it is what made this
460
+ // quadratic. On `<http://a<http://a<…` the scheme matches, the class swallows the
461
+ // rest of the document looking for `>`, then backtracks a character at a time, once
462
+ // per `<`. 160 KB took 1.7 s. `ANGLE_DEST_RE` and `EMAIL_AUTOLINK_RE` beside it
463
+ // already exclude `<`; this one was the outlier. The only input that now parses
464
+ // differently is `<http://a<b>`, which no other parser reads as a link either.
465
+ const AUTOLINK_RE = /^<((?:https?|mailto|tel):[^<>\s]+)>/i;
459
466
  /** `<destination>` — markdown's way of putting a space in a URL. */
460
467
  const ANGLE_DEST_RE = /^<([^<>]*)>(?:\s+["'(](.*)["')])?$/;
461
468
  /** CommonMark's own cap on a link label, which is also what bounds the scan. */
462
469
  const MAX_LABEL_LENGTH = 999;
470
+ /**
471
+ * How deep parentheses may nest inside `[a](…)` before the destination is refused
472
+ * outright — counted from the `(` that opens it, so 31 nested pairs inside.
473
+ *
474
+ * This is a bound on WORK, not on taste, and it is the only thing standing
475
+ * between a paragraph and a frozen tab. The destination scan walks forward for a
476
+ * balancing `)`, and an unclosed destination sends it to the end of the line; one
477
+ * `[a](x` costs nothing, but `'[a](x'.repeat(16384)` — 80 KB on a single line —
478
+ * makes every one of the 16384 openers walk the whole remainder, which measured
479
+ * 936 ms at 80 KB and 3.9 s at 160 KB, synchronously inside a `computed` during
480
+ * change detection. A `~4x` cost per doubling of the input: quadratic, on a
481
+ * component whose documented input is a comment or a model's output.
482
+ *
483
+ * The cap fixes it because a scan can only keep going by NOT finding its closer,
484
+ * and every later `[…](` it walks past contributes an unmatched `(` of its own —
485
+ * so after 32 of them the scan stops, no opener's walk can cover more than the
486
+ * next 32 openers, and the total is linear in the document. (A `)` that would
487
+ * bring the count back down is the closer, and ends the scan anyway.) The number
488
+ * is cmark's: `manual_scan_link_url` refuses at the same depth, for the same
489
+ * reason.
490
+ *
491
+ * What it costs: a destination with 32 or more nested `(` is no longer a link and
492
+ * renders as text. No URL looks like that — the deep end of the real world is a
493
+ * Wikipedia `..._(disambiguation)`, which is one pair.
494
+ */
495
+ const MAX_DESTINATION_NESTING = 32;
463
496
  const BARE_URL_RE = /^https?:\/\/[^\s<>[\]()]*(?:\([^\s<>()]*\)[^\s<>[\]()]*)*/i;
464
497
  const EMAIL_AUTOLINK_RE = /^<([^\s@<>]+@[^\s@<>.]+\.[^\s@<>]+)>/;
465
498
  /**
@@ -538,13 +571,26 @@ function inlines(source, depth, outer) {
538
571
  }
539
572
  }
540
573
  if (char === '\n') {
541
- // Two trailing spaces are markdown's hard break. `endsWith`, not
542
- // `/[ ]{2,}$/.test(text)`: that regex has no start anchor, so it retries
543
- // from every position of the accumulated paragraph, which made paragraph
544
- // parsing quadratic. On a 161 KB document a CPU profile put 3306 ms of 3378
545
- // ms of total self-time in that one test — and it is re-paid on every
546
- // streamed chunk.
547
- const hard = text.endsWith(' ');
574
+ // Two trailing spaces are markdown's hard break, and the question is asked
575
+ // of the SOURCE rather than of `text` — twice now, this one line has been
576
+ // where paragraph parsing went quadratic.
577
+ //
578
+ // `/[ ]{2,}$/.test(text)` was the first version: no start anchor, so it
579
+ // retries from every position of the accumulated paragraph. A CPU profile
580
+ // of a 161 KB document put 3306 ms of 3378 ms of total self-time in it.
581
+ // `text.endsWith(' ')` replaced it and is quadratic for a different
582
+ // reason: `text` is built by `+=`, so it is a rope, and every read of its
583
+ // tail flattens the whole thing — 160,000 short lines cost 1980 ms of
584
+ // copying against 7 ms for the same loop without the test. Ordinary prose
585
+ // reaches that shape; nothing has to be malformed.
586
+ //
587
+ // Reading `source` instead answers the same question in constant time, and
588
+ // it IS the same question: while `text` is non-empty its last character is
589
+ // always `source[i - 1]` (every branch that appends appends exactly the
590
+ // character it consumed), and when it is empty the preceding characters
591
+ // belong to a construct that just closed — none of which can end in a
592
+ // space, since a closing fence, `)`, `>` or emphasis marker is never one.
593
+ const hard = source[i - 1] === ' ' && source[i - 2] === ' ';
548
594
  if (hard) {
549
595
  text = text.replace(/[ ]+$/, '');
550
596
  flush();
@@ -675,12 +721,13 @@ function codeSpanValue(raw) {
675
721
  /**
676
722
  * `[label](href "title")` starting at `source[at] === '['`.
677
723
  *
678
- * Two bounds, both load-bearing. The label scan stops at
724
+ * Three bounds, all load-bearing. The label scan stops at
679
725
  * {@link MAX_LABEL_LENGTH}, which is CommonMark's own limit, and a scan that
680
726
  * reaches the end of the source without meeting a single `]` records the fact in
681
727
  * the context — from then on every later `[` answers in constant time. Without
682
728
  * that, `'['.repeat(100000)` spent 8 seconds on the main thread, inside a
683
- * `computed`.
729
+ * `computed`. The third is {@link MAX_DESTINATION_NESTING}, on the destination
730
+ * scan, and it is the one that makes the whole function linear.
684
731
  */
685
732
  function matchLink(source, at, ctx) {
686
733
  if (at >= ctx.noBracket.from)
@@ -738,8 +785,13 @@ function matchLink(source, at, ctx) {
738
785
  i++;
739
786
  continue;
740
787
  }
741
- if (char === '(')
788
+ if (char === '(') {
742
789
  parens++;
790
+ // Giving up HERE is what makes the scan linear rather than quadratic — see
791
+ // {@link MAX_DESTINATION_NESTING}.
792
+ if (parens > MAX_DESTINATION_NESTING)
793
+ return null;
794
+ }
743
795
  if (char === ')') {
744
796
  parens--;
745
797
  if (parens === 0) {