postext 0.3.6 → 0.3.8

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 (137) hide show
  1. package/dist/__tests__/exports.test.js +3 -0
  2. package/dist/__tests__/exports.test.js.map +1 -1
  3. package/dist/canvas-backend/blockRender.d.ts +3 -0
  4. package/dist/canvas-backend/blockRender.d.ts.map +1 -0
  5. package/dist/canvas-backend/blockRender.js +176 -0
  6. package/dist/canvas-backend/blockRender.js.map +1 -0
  7. package/dist/canvas-backend/decorations.d.ts +6 -0
  8. package/dist/canvas-backend/decorations.d.ts.map +1 -0
  9. package/dist/canvas-backend/decorations.js +106 -0
  10. package/dist/canvas-backend/decorations.js.map +1 -0
  11. package/dist/{canvas-backend.d.ts → canvas-backend/index.d.ts} +2 -2
  12. package/dist/canvas-backend/index.d.ts.map +1 -0
  13. package/dist/canvas-backend/index.js +66 -0
  14. package/dist/canvas-backend/index.js.map +1 -0
  15. package/dist/defaults/index.d.ts +1 -0
  16. package/dist/defaults/index.d.ts.map +1 -1
  17. package/dist/defaults/index.js +9 -0
  18. package/dist/defaults/index.js.map +1 -1
  19. package/dist/defaults/pdfGeneration.d.ts +5 -0
  20. package/dist/defaults/pdfGeneration.d.ts.map +1 -0
  21. package/dist/defaults/pdfGeneration.js +37 -0
  22. package/dist/defaults/pdfGeneration.js.map +1 -0
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/knuthPlass/breakpoints.d.ts +6 -0
  28. package/dist/knuthPlass/breakpoints.d.ts.map +1 -0
  29. package/dist/knuthPlass/breakpoints.js +284 -0
  30. package/dist/knuthPlass/breakpoints.js.map +1 -0
  31. package/dist/knuthPlass/constants.d.ts +8 -0
  32. package/dist/knuthPlass/constants.d.ts.map +1 -0
  33. package/dist/knuthPlass/constants.js +8 -0
  34. package/dist/knuthPlass/constants.js.map +1 -0
  35. package/dist/knuthPlass/index.d.ts +12 -0
  36. package/dist/knuthPlass/index.d.ts.map +1 -0
  37. package/dist/knuthPlass/index.js +11 -0
  38. package/dist/knuthPlass/index.js.map +1 -0
  39. package/dist/knuthPlass/pretextAdapter.d.ts +12 -0
  40. package/dist/knuthPlass/pretextAdapter.d.ts.map +1 -0
  41. package/dist/knuthPlass/pretextAdapter.js +178 -0
  42. package/dist/knuthPlass/pretextAdapter.js.map +1 -0
  43. package/dist/knuthPlass/richAdapter.d.ts +26 -0
  44. package/dist/knuthPlass/richAdapter.d.ts.map +1 -0
  45. package/dist/knuthPlass/richAdapter.js +189 -0
  46. package/dist/knuthPlass/richAdapter.js.map +1 -0
  47. package/dist/{knuthPlass.d.ts → knuthPlass/types.d.ts} +1 -31
  48. package/dist/knuthPlass/types.d.ts.map +1 -0
  49. package/dist/knuthPlass/types.js +5 -0
  50. package/dist/knuthPlass/types.js.map +1 -0
  51. package/dist/knuthPlass/utils.d.ts +2 -0
  52. package/dist/knuthPlass/utils.d.ts.map +1 -0
  53. package/dist/knuthPlass/utils.js +4 -0
  54. package/dist/knuthPlass/utils.js.map +1 -0
  55. package/dist/measure/cache.d.ts +5 -0
  56. package/dist/measure/cache.d.ts.map +1 -0
  57. package/dist/measure/cache.js +38 -0
  58. package/dist/measure/cache.js.map +1 -0
  59. package/dist/measure/canvas.d.ts +8 -0
  60. package/dist/measure/canvas.d.ts.map +1 -0
  61. package/dist/measure/canvas.js +30 -0
  62. package/dist/measure/canvas.js.map +1 -0
  63. package/dist/measure/font.d.ts +19 -0
  64. package/dist/measure/font.d.ts.map +1 -0
  65. package/dist/measure/font.js +34 -0
  66. package/dist/measure/font.js.map +1 -0
  67. package/dist/measure/index.d.ts +7 -0
  68. package/dist/measure/index.d.ts.map +1 -0
  69. package/dist/measure/index.js +6 -0
  70. package/dist/measure/index.js.map +1 -0
  71. package/dist/measure/plain.d.ts +13 -0
  72. package/dist/measure/plain.d.ts.map +1 -0
  73. package/dist/measure/plain.js +167 -0
  74. package/dist/measure/plain.js.map +1 -0
  75. package/dist/measure/rich.d.ts +25 -0
  76. package/dist/measure/rich.d.ts.map +1 -0
  77. package/dist/measure/rich.js +246 -0
  78. package/dist/measure/rich.js.map +1 -0
  79. package/dist/measure/types.d.ts +28 -0
  80. package/dist/measure/types.d.ts.map +1 -0
  81. package/dist/measure/types.js +2 -0
  82. package/dist/measure/types.js.map +1 -0
  83. package/dist/parse/blockParser.d.ts +28 -0
  84. package/dist/parse/blockParser.d.ts.map +1 -0
  85. package/dist/parse/blockParser.js +302 -0
  86. package/dist/parse/blockParser.js.map +1 -0
  87. package/dist/parse/index.d.ts +4 -0
  88. package/dist/parse/index.d.ts.map +1 -0
  89. package/dist/parse/index.js +3 -0
  90. package/dist/parse/index.js.map +1 -0
  91. package/dist/parse/inlineFormatting.d.ts +12 -0
  92. package/dist/parse/inlineFormatting.d.ts.map +1 -0
  93. package/dist/parse/inlineFormatting.js +90 -0
  94. package/dist/parse/inlineFormatting.js.map +1 -0
  95. package/dist/parse/inlineMath.d.ts +29 -0
  96. package/dist/parse/inlineMath.d.ts.map +1 -0
  97. package/dist/parse/inlineMath.js +141 -0
  98. package/dist/parse/inlineMath.js.map +1 -0
  99. package/dist/parse/sourceMapping.d.ts +12 -0
  100. package/dist/parse/sourceMapping.d.ts.map +1 -0
  101. package/dist/parse/sourceMapping.js +130 -0
  102. package/dist/parse/sourceMapping.js.map +1 -0
  103. package/dist/{parse.d.ts → parse/types.d.ts} +2 -25
  104. package/dist/parse/types.d.ts.map +1 -0
  105. package/dist/parse/types.js +2 -0
  106. package/dist/parse/types.js.map +1 -0
  107. package/dist/pipeline/build.d.ts.map +1 -1
  108. package/dist/pipeline/build.js +34 -276
  109. package/dist/pipeline/build.js.map +1 -1
  110. package/dist/pipeline/buildBlockKind.d.ts +33 -0
  111. package/dist/pipeline/buildBlockKind.d.ts.map +1 -0
  112. package/dist/pipeline/buildBlockKind.js +82 -0
  113. package/dist/pipeline/buildBlockKind.js.map +1 -0
  114. package/dist/pipeline/buildHelpers.d.ts +47 -0
  115. package/dist/pipeline/buildHelpers.d.ts.map +1 -0
  116. package/dist/pipeline/buildHelpers.js +169 -0
  117. package/dist/pipeline/buildHelpers.js.map +1 -0
  118. package/dist/pipeline/buildMeasurement.d.ts +27 -0
  119. package/dist/pipeline/buildMeasurement.d.ts.map +1 -0
  120. package/dist/pipeline/buildMeasurement.js +49 -0
  121. package/dist/pipeline/buildMeasurement.js.map +1 -0
  122. package/dist/types.d.ts +15 -0
  123. package/dist/types.d.ts.map +1 -1
  124. package/package.json +1 -1
  125. package/dist/canvas-backend.d.ts.map +0 -1
  126. package/dist/canvas-backend.js +0 -370
  127. package/dist/canvas-backend.js.map +0 -1
  128. package/dist/knuthPlass.d.ts.map +0 -1
  129. package/dist/knuthPlass.js +0 -665
  130. package/dist/knuthPlass.js.map +0 -1
  131. package/dist/measure.d.ts +0 -61
  132. package/dist/measure.d.ts.map +0 -1
  133. package/dist/measure.js +0 -512
  134. package/dist/measure.js.map +0 -1
  135. package/dist/parse.d.ts.map +0 -1
  136. package/dist/parse.js +0 -653
  137. package/dist/parse.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAE1M,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAsEniC,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAE1M,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAyE1nC,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core Knuth-Plass dynamic-programming breakpoint selection.
3
+ */
4
+ import type { KPItem, KPOptions } from './types';
5
+ export declare function computeBreakpoints(items: KPItem[], options: KPOptions): number[];
6
+ //# sourceMappingURL=breakpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/breakpoints.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAa,MAAM,SAAS,CAAC;AA4C5D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,GAAG,MAAM,EAAE,CAyShF"}
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Core Knuth-Plass dynamic-programming breakpoint selection.
3
+ */
4
+ import { BADNESS_CAP, DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT, DEFAULT_FITNESS_CLASS_DEMERIT, KP_INFINITY, } from './constants';
5
+ function classifyFitness(r) {
6
+ if (r < -0.5)
7
+ return 0; // tight
8
+ if (r < 0.5)
9
+ return 1; // normal
10
+ if (r < 1.0)
11
+ return 2; // loose
12
+ return 3; // very loose
13
+ }
14
+ function computeBadness(r) {
15
+ const absR = Math.abs(r);
16
+ const b = Math.round(100 * absR * absR * absR);
17
+ return Math.min(b, BADNESS_CAP);
18
+ }
19
+ export function computeBreakpoints(items, options) {
20
+ const { lineWidth, consecutiveHyphenDemerit = DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT, fitnessClassDemerit = DEFAULT_FITNESS_CLASS_DEMERIT, runtPenalty = 0, runtMinWidth = 0, } = options;
21
+ const terminalBreakPosition = items.length - 1;
22
+ // Running totals up to current item
23
+ let sumWidth = 0;
24
+ let sumStretch = 0;
25
+ let sumShrink = 0;
26
+ // Prefix sums: sumWidthAt[i] = sum of widths of items 0..i-1
27
+ // We build these incrementally and store for the range computations.
28
+ const sumWidthAt = [0];
29
+ const sumStretchAt = [0];
30
+ const sumShrinkAt = [0];
31
+ for (const item of items) {
32
+ if (item.type === 'box') {
33
+ sumWidth += item.width;
34
+ }
35
+ else if (item.type === 'glue') {
36
+ sumWidth += item.width;
37
+ sumStretch += item.stretch;
38
+ sumShrink += item.shrink;
39
+ }
40
+ // Penalties don't contribute to running width/stretch/shrink
41
+ sumWidthAt.push(sumWidth);
42
+ sumStretchAt.push(sumStretch);
43
+ sumShrinkAt.push(sumShrink);
44
+ }
45
+ // Seed active node list with a "start of paragraph" sentinel
46
+ let activeNodes = [{
47
+ position: -1,
48
+ line: 0,
49
+ fitnessClass: 1,
50
+ totalWidth: 0,
51
+ totalStretch: 0,
52
+ totalShrink: 0,
53
+ totalDemerits: 0,
54
+ previous: null,
55
+ }];
56
+ for (let i = 0; i < items.length; i++) {
57
+ const item = items[i];
58
+ // Determine if this position is a legal breakpoint
59
+ let isLegalBreak = false;
60
+ if (item.type === 'glue') {
61
+ // Glue breaks if preceded by a box
62
+ if (i > 0 && items[i - 1].type === 'box') {
63
+ isLegalBreak = true;
64
+ }
65
+ }
66
+ else if (item.type === 'penalty') {
67
+ if (item.penalty < KP_INFINITY) {
68
+ isLegalBreak = true;
69
+ }
70
+ }
71
+ if (!isLegalBreak)
72
+ continue;
73
+ // Width contribution of breaking at this item
74
+ const breakWidth = item.type === 'penalty' ? item.width : 0;
75
+ const isFlagged = item.type === 'penalty' && item.flagged;
76
+ // For glue breakpoints, the line content goes up to (but excluding) this glue.
77
+ // For penalty breakpoints, the line content goes up to this penalty.
78
+ // The content width from after active node a to break at i:
79
+ // If glue: sumWidthAt[i] - a.totalWidth (excludes glue itself)
80
+ // If penalty: sumWidthAt[i] - a.totalWidth (sumWidthAt doesn't include penalty width)
81
+ // Plus breakWidth for penalties.
82
+ // Compute the content width from the items between a.position and i.
83
+ // After the break at active node a.position:
84
+ // - If a.position was a glue break, the next line starts at the item AFTER the glue
85
+ // - If a.position was a penalty break, the next line starts at the item AFTER the penalty
86
+ // - For the sentinel (-1), the line starts at item 0
87
+ // Total width from start to just before item i (excluding this glue/penalty's own width):
88
+ // For a glue at i: line content = sumWidthAt[i] (which includes all box+glue widths before i)
89
+ // but we need to subtract the width of glues/boxes after the previous break.
90
+ // Actually sumWidthAt[i] already accounts for that.
91
+ // We subtract a.totalWidth which is sumWidthAt at the point right after a's break.
92
+ const newNodes = [];
93
+ const toDeactivate = new Set();
94
+ for (let ai = 0; ai < activeNodes.length; ai++) {
95
+ const a = activeNodes[ai];
96
+ // Line content width: width of boxes and glues from after a's break to this break.
97
+ // For glue break: content is items from (a.position+1) to (i-1) inclusive + breakWidth
98
+ // = sumWidthAt[i] - a.totalWidth
99
+ // For penalty break: content is items from (a.position+1) to (i-1) inclusive + penalty.width
100
+ // = sumWidthAt[i] - a.totalWidth + breakWidth
101
+ // Note: sumWidthAt[i] does NOT include item i if it's a penalty.
102
+ // sumWidthAt[i] includes item i's width only for box/glue through the push.
103
+ // Wait — re-examine: sumWidthAt[i] is the prefix sum BEFORE item i is processed.
104
+ // Actually, sumWidthAt has length items.length + 1. sumWidthAt[0] = 0, sumWidthAt[k+1] includes item k.
105
+ // So sumWidthAt[i] includes items 0..i-1, and sumWidthAt[i+1] includes items 0..i.
106
+ // For a glue break at position i:
107
+ // The line goes from after a's break to just before this glue.
108
+ // Content width = sumWidthAt[i] - a.totalWidth
109
+ // (sumWidthAt[i] includes items 0..i-1, which covers everything up to but not including the glue)
110
+ //
111
+ // For a penalty break at position i:
112
+ // The line includes everything up to but not including the penalty, plus breakWidth
113
+ // Content width = sumWidthAt[i] - a.totalWidth + breakWidth
114
+ const contentWidth = sumWidthAt[i] - a.totalWidth + breakWidth;
115
+ const available = lineWidth(a.line);
116
+ const slack = available - contentWidth;
117
+ // Stretch/shrink from the items on this line
118
+ const lineStretch = sumStretchAt[i] - a.totalStretch;
119
+ const lineShrink = sumShrinkAt[i] - a.totalShrink;
120
+ let r;
121
+ if (slack >= 0) {
122
+ r = lineStretch > 0 ? slack / lineStretch : KP_INFINITY;
123
+ }
124
+ else {
125
+ r = lineShrink > 0 ? slack / lineShrink : -KP_INFINITY;
126
+ }
127
+ // Deactivate nodes that are too far behind (line too wide, can't shrink enough)
128
+ if (r < -1) {
129
+ toDeactivate.add(ai);
130
+ continue;
131
+ }
132
+ // Feasibility: don't allow extreme stretching
133
+ // We allow r up to a generous threshold; the demerits will naturally penalize loose lines
134
+ if (r > KP_INFINITY) {
135
+ // Infeasible — too few items to fill the line
136
+ continue;
137
+ }
138
+ const badness = computeBadness(r);
139
+ const pen = item.type === 'penalty' ? item.penalty : 0;
140
+ // Runt: when this break closes the paragraph with a too-short final
141
+ // line, inject `runtPenalty` as equivalent badness — so it enters the
142
+ // squared demerit formula alongside `badness`, on the same scale as
143
+ // hyphen penalties. Applied linearly (old behavior) it was dwarfed by
144
+ // badness² (up to 10001² ≈ 1e8) from any stretched alternative.
145
+ const isRunt = runtPenalty > 0 &&
146
+ i === terminalBreakPosition &&
147
+ contentWidth > 0 &&
148
+ contentWidth < runtMinWidth;
149
+ const effectiveBadness = isRunt ? badness + runtPenalty : badness;
150
+ let d;
151
+ if (pen >= 0) {
152
+ d = (1 + effectiveBadness + pen) * (1 + effectiveBadness + pen);
153
+ }
154
+ else if (pen > -KP_INFINITY) {
155
+ d = (1 + effectiveBadness) * (1 + effectiveBadness) - pen * pen;
156
+ }
157
+ else {
158
+ d = (1 + effectiveBadness) * (1 + effectiveBadness);
159
+ }
160
+ // Consecutive hyphen demerit
161
+ const prevIsFlagged = a.position >= 0 &&
162
+ items[a.position].type === 'penalty' &&
163
+ items[a.position].flagged;
164
+ if (isFlagged && prevIsFlagged) {
165
+ d += consecutiveHyphenDemerit;
166
+ }
167
+ // Fitness class demerit
168
+ const fc = classifyFitness(r);
169
+ if (Math.abs(fc - a.fitnessClass) > 1) {
170
+ d += fitnessClassDemerit;
171
+ }
172
+ const totalDemerits = a.totalDemerits + d;
173
+ // The total width/stretch/shrink after this break:
174
+ // After a glue break: the glue is consumed. Next line starts at item i+1.
175
+ // totalWidth = sumWidthAt[i+1] (includes the glue's width — but we DON'T want it on the next line)
176
+ // Actually, for the "totalWidth" tracked in active nodes, it represents the cumulative
177
+ // width at the START of the next line. After a glue break at i, the next line starts at i+1.
178
+ // So totalWidth should be sumWidthAt[i+1], which includes the glue.
179
+ // When computing content width for the next line: sumWidthAt[j] - totalWidth
180
+ // This correctly excludes the consumed glue.
181
+ //
182
+ // After a penalty break: the penalty is not consumed as content on the next line.
183
+ // totalWidth = sumWidthAt[i+1] (which for penalties is same as sumWidthAt[i] since penalties
184
+ // don't add to sumWidth). Wait — let me re-check: penalties don't contribute to sumWidth,
185
+ // so sumWidthAt[i+1] == sumWidthAt[i] for a penalty at position i.
186
+ // But the next line starts at i+1. So totalWidth = sumWidthAt[i+1].
187
+ const newTotalWidth = sumWidthAt[i + 1];
188
+ const newTotalStretch = sumStretchAt[i + 1];
189
+ const newTotalShrink = sumShrinkAt[i + 1];
190
+ newNodes.push({
191
+ position: i,
192
+ line: a.line + 1,
193
+ fitnessClass: fc,
194
+ totalWidth: newTotalWidth,
195
+ totalStretch: newTotalStretch,
196
+ totalShrink: newTotalShrink,
197
+ totalDemerits: totalDemerits,
198
+ previous: a,
199
+ });
200
+ }
201
+ // Remove deactivated nodes
202
+ if (toDeactivate.size > 0) {
203
+ activeNodes = activeNodes.filter((_, idx) => !toDeactivate.has(idx));
204
+ }
205
+ // Deduplicate new nodes by (line, fitnessClass): keep best demerits.
206
+ // Different breakpoint positions must NOT be merged — only nodes at the
207
+ // same position (which all newNodes share) can be compared.
208
+ const deduped = [];
209
+ for (const node of newNodes) {
210
+ const key = node.line * 4 + node.fitnessClass;
211
+ let found = false;
212
+ for (let di = 0; di < deduped.length; di++) {
213
+ const existing = deduped[di];
214
+ if (existing.line * 4 + existing.fitnessClass === key) {
215
+ if (node.totalDemerits < existing.totalDemerits) {
216
+ deduped[di] = node;
217
+ }
218
+ found = true;
219
+ break;
220
+ }
221
+ }
222
+ if (!found) {
223
+ deduped.push(node);
224
+ }
225
+ }
226
+ // Append all deduplicated nodes to the active set
227
+ for (const node of deduped) {
228
+ activeNodes.push(node);
229
+ }
230
+ // Forced breaks: when penalty = -INFINITY, remove all active nodes that
231
+ // are NOT at this position. The break is mandatory — no line can skip it.
232
+ if (item.type === 'penalty' && item.penalty <= -KP_INFINITY) {
233
+ activeNodes = activeNodes.filter((a) => a.position === i);
234
+ }
235
+ // Emergency fallback: if active set is empty, force a break here
236
+ if (activeNodes.length === 0) {
237
+ activeNodes.push({
238
+ position: i,
239
+ line: 1, // We lost track — start fresh
240
+ fitnessClass: 1,
241
+ totalWidth: sumWidthAt[i + 1],
242
+ totalStretch: sumStretchAt[i + 1],
243
+ totalShrink: sumShrinkAt[i + 1],
244
+ totalDemerits: 0,
245
+ previous: null,
246
+ });
247
+ }
248
+ }
249
+ // Find best final node: only consider nodes at the last breakpoint position
250
+ // (the forced penalty at the end of the paragraph).
251
+ const lastBreakPosition = items.length - 1;
252
+ let best = null;
253
+ for (const a of activeNodes) {
254
+ if (a.position !== lastBreakPosition)
255
+ continue;
256
+ if (best === null || a.totalDemerits < best.totalDemerits) {
257
+ best = a;
258
+ }
259
+ }
260
+ // Fallback: if no node reached the final position, take any node with the
261
+ // highest position (nearest to the end).
262
+ if (!best) {
263
+ for (const a of activeNodes) {
264
+ if (a.position < 0)
265
+ continue;
266
+ if (best === null || a.position > best.position ||
267
+ (a.position === best.position && a.totalDemerits < best.totalDemerits)) {
268
+ best = a;
269
+ }
270
+ }
271
+ }
272
+ if (!best)
273
+ return [];
274
+ // Traceback
275
+ const breaks = [];
276
+ let node = best;
277
+ while (node !== null && node.position >= 0) {
278
+ breaks.push(node.position);
279
+ node = node.previous;
280
+ }
281
+ breaks.reverse();
282
+ return breaks;
283
+ }
284
+ //# sourceMappingURL=breakpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.js","sourceRoot":"","sources":["../../src/knuthPlass/breakpoints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const KP_INFINITY = 10000;
2
+ export declare const HYPHEN_PENALTY = 50;
3
+ export declare const DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT = 3000;
4
+ export declare const DEFAULT_FITNESS_CLASS_DEMERIT = 100;
5
+ export declare const BADNESS_CAP = 10000;
6
+ export declare const MAX_STRETCH: number;
7
+ export declare const SOFT_HYPHEN = "\u00AD";
8
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,kCAAkC,OAAO,CAAC;AACvD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,WAAW,QAA0B,CAAC;AAEnD,eAAO,MAAM,WAAW,WAAW,CAAC"}
@@ -0,0 +1,8 @@
1
+ export const KP_INFINITY = 10000;
2
+ export const HYPHEN_PENALTY = 50;
3
+ export const DEFAULT_CONSECUTIVE_HYPHEN_DEMERIT = 3000;
4
+ export const DEFAULT_FITNESS_CLASS_DEMERIT = 100;
5
+ export const BADNESS_CAP = 10000;
6
+ export const MAX_STRETCH = Number.MAX_SAFE_INTEGER;
7
+ export const SOFT_HYPHEN = '\u00AD';
8
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/knuthPlass/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,kCAAkC,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Knuth-Plass optimal paragraph line-breaking algorithm.
3
+ *
4
+ * Replaces the greedy first-fit line breaker with a dynamic-programming
5
+ * approach that minimizes total demerits across all lines of a paragraph,
6
+ * producing more even word-spacing and fewer "loose" lines.
7
+ */
8
+ export type { KPBox, KPGlue, KPPenalty, KPItem, KPOptions, RichTokenMeta, } from './types';
9
+ export { computeBreakpoints } from './breakpoints';
10
+ export { pretextSegmentsToItems, reconstructPretextLines } from './pretextAdapter';
11
+ export { richTokensToItems, reconstructRichLines } from './richAdapter';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,KAAK,EACL,MAAM,EACN,SAAS,EACT,MAAM,EACN,SAAS,EACT,aAAa,GACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Knuth-Plass optimal paragraph line-breaking algorithm.
3
+ *
4
+ * Replaces the greedy first-fit line breaker with a dynamic-programming
5
+ * approach that minimizes total demerits across all lines of a paragraph,
6
+ * producing more even word-spacing and fewer "loose" lines.
7
+ */
8
+ export { computeBreakpoints } from './breakpoints';
9
+ export { pretextSegmentsToItems, reconstructPretextLines } from './pretextAdapter';
10
+ export { richTokensToItems, reconstructRichLines } from './richAdapter';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/knuthPlass/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Adapter between @chenglou/pretext `PreparedTextWithSegments` and the
3
+ * Knuth-Plass item stream, plus reconstruction of VDT lines from the
4
+ * optimal breakpoint sequence.
5
+ */
6
+ import type { PreparedTextWithSegments } from '@chenglou/pretext';
7
+ import type { VDTLine } from '../vdt';
8
+ import type { TextAlign } from '../types';
9
+ import type { KPItem } from './types';
10
+ export declare function pretextSegmentsToItems(prepared: PreparedTextWithSegments, normalSpaceWidth: number, maxStretchRatio: number, minShrinkRatio: number): KPItem[];
11
+ export declare function reconstructPretextLines(items: KPItem[], breaks: number[], prepared: PreparedTextWithSegments, lineHeightPx: number, lineWidthFn: (lineIndex: number) => number, lineIndentFn: (lineIndex: number) => number, normalSpaceWidth: number, textAlign: TextAlign): VDTLine[];
12
+ //# sourceMappingURL=pretextAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pretextAdapter.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/pretextAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,QAAQ,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAItC,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,wBAAwB,EAClC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CAmFV;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,wBAAwB,EAClC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC1C,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC3C,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,SAAS,GACnB,OAAO,EAAE,CAoGX"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Adapter between @chenglou/pretext `PreparedTextWithSegments` and the
3
+ * Knuth-Plass item stream, plus reconstruction of VDT lines from the
4
+ * optimal breakpoint sequence.
5
+ */
6
+ import { createBoundingBox } from '../vdt';
7
+ import { HYPHEN_PENALTY, KP_INFINITY, MAX_STRETCH, SOFT_HYPHEN } from './constants';
8
+ import { cleanSoftHyphens } from './utils';
9
+ export function pretextSegmentsToItems(prepared, normalSpaceWidth, maxStretchRatio, minShrinkRatio) {
10
+ const items = [];
11
+ const segments = prepared.segments;
12
+ const widths = prepared.widths;
13
+ const kinds = prepared.kinds;
14
+ const discretionaryHyphenWidth = prepared.discretionaryHyphenWidth;
15
+ const stretchPerSpace = normalSpaceWidth * (maxStretchRatio - 1);
16
+ const shrinkPerSpace = normalSpaceWidth * (1 - minShrinkRatio);
17
+ for (let i = 0; i < segments.length; i++) {
18
+ const kind = kinds[i];
19
+ const w = widths[i];
20
+ switch (kind) {
21
+ case 'text':
22
+ items.push({ type: 'box', width: w, sourceIndex: i });
23
+ break;
24
+ case 'space':
25
+ case 'glue':
26
+ items.push({
27
+ type: 'glue',
28
+ width: w,
29
+ stretch: stretchPerSpace,
30
+ shrink: shrinkPerSpace,
31
+ sourceIndex: i,
32
+ });
33
+ break;
34
+ case 'soft-hyphen':
35
+ items.push({
36
+ type: 'penalty',
37
+ width: discretionaryHyphenWidth,
38
+ penalty: HYPHEN_PENALTY,
39
+ flagged: true,
40
+ sourceIndex: i,
41
+ });
42
+ break;
43
+ case 'hard-break':
44
+ items.push({
45
+ type: 'penalty',
46
+ width: 0,
47
+ penalty: -KP_INFINITY,
48
+ flagged: false,
49
+ sourceIndex: i,
50
+ });
51
+ break;
52
+ case 'zero-width-break':
53
+ items.push({
54
+ type: 'penalty',
55
+ width: 0,
56
+ penalty: 0,
57
+ flagged: false,
58
+ sourceIndex: i,
59
+ });
60
+ break;
61
+ case 'preserved-space':
62
+ case 'tab':
63
+ items.push({ type: 'box', width: w, sourceIndex: i });
64
+ break;
65
+ default:
66
+ items.push({ type: 'box', width: w, sourceIndex: i });
67
+ break;
68
+ }
69
+ }
70
+ // Final-line glue (infinite stretch) + forced break
71
+ items.push({
72
+ type: 'glue',
73
+ width: 0,
74
+ stretch: MAX_STRETCH,
75
+ shrink: 0,
76
+ sourceIndex: -1,
77
+ });
78
+ items.push({
79
+ type: 'penalty',
80
+ width: 0,
81
+ penalty: -KP_INFINITY,
82
+ flagged: false,
83
+ sourceIndex: -1,
84
+ });
85
+ return items;
86
+ }
87
+ export function reconstructPretextLines(items, breaks, prepared, lineHeightPx, lineWidthFn, lineIndentFn, normalSpaceWidth, textAlign) {
88
+ const segments = prepared.segments;
89
+ const widths = prepared.widths;
90
+ const discretionaryHyphenWidth = prepared.discretionaryHyphenWidth;
91
+ const lines = [];
92
+ let lineStart = 0; // item index where current line content starts
93
+ for (let li = 0; li < breaks.length; li++) {
94
+ const breakAt = breaks[li];
95
+ const isLastLine = li === breaks.length - 1;
96
+ const lineIndent = lineIndentFn(li);
97
+ const lineMaxWidth = lineWidthFn(li);
98
+ // Determine if this break is at a penalty (hyphenation)
99
+ const breakItem = items[breakAt];
100
+ const hyphenated = breakItem.type === 'penalty' && breakItem.flagged;
101
+ // Collect segments for this line: items from lineStart to breakAt
102
+ // For glue breaks: line content is items lineStart..breakAt-1 (exclude the breaking glue)
103
+ // For penalty breaks: line content is items lineStart..breakAt-1 (exclude the penalty itself)
104
+ const contentEnd = breakItem.type === 'glue' ? breakAt : breakAt;
105
+ const lineSegments = [];
106
+ const textParts = [];
107
+ for (let j = lineStart; j < contentEnd; j++) {
108
+ const it = items[j];
109
+ if (it.sourceIndex < 0)
110
+ continue; // skip synthetic items
111
+ if (it.type === 'box') {
112
+ const seg = segments[it.sourceIndex];
113
+ const w = widths[it.sourceIndex];
114
+ if (seg === SOFT_HYPHEN)
115
+ continue;
116
+ const cleanText = cleanSoftHyphens(seg);
117
+ lineSegments.push({ kind: 'text', text: cleanText, width: w });
118
+ textParts.push(cleanText);
119
+ }
120
+ else if (it.type === 'glue') {
121
+ const seg = segments[it.sourceIndex];
122
+ const w = widths[it.sourceIndex];
123
+ lineSegments.push({ kind: 'space', text: seg, width: w });
124
+ textParts.push(seg);
125
+ }
126
+ // Penalties within the line are skipped (they're just potential break points)
127
+ }
128
+ // Trim trailing spaces
129
+ while (lineSegments.length > 0 && lineSegments[lineSegments.length - 1].kind === 'space') {
130
+ lineSegments.pop();
131
+ textParts.pop();
132
+ }
133
+ // If hyphenated, append '-' to the last text segment
134
+ if (hyphenated && lineSegments.length > 0) {
135
+ const lastIdx = lineSegments.length - 1;
136
+ const last = lineSegments[lastIdx];
137
+ if (last.kind === 'text') {
138
+ lineSegments[lastIdx] = {
139
+ kind: 'text',
140
+ text: last.text + '-',
141
+ width: last.width + discretionaryHyphenWidth,
142
+ };
143
+ textParts[textParts.length - 1] = last.text + '-';
144
+ }
145
+ }
146
+ const lineText = textParts.join('');
147
+ const contentWidth = lineSegments.reduce((s, seg) => s + seg.width, 0);
148
+ // Compute justifiedSpaceRatio
149
+ let justifiedSpaceRatio;
150
+ if (textAlign === 'justify' && !isLastLine && normalSpaceWidth > 0) {
151
+ let wordWidth = 0;
152
+ let spaceCount = 0;
153
+ for (const seg of lineSegments) {
154
+ if (seg.kind === 'space')
155
+ spaceCount++;
156
+ else
157
+ wordWidth += seg.width;
158
+ }
159
+ if (spaceCount > 0) {
160
+ const justifiedSpaceWidth = (lineMaxWidth - wordWidth) / spaceCount;
161
+ justifiedSpaceRatio = justifiedSpaceWidth / normalSpaceWidth;
162
+ }
163
+ }
164
+ lines.push({
165
+ text: lineText,
166
+ bbox: createBoundingBox(lineIndent, li * lineHeightPx, contentWidth, lineHeightPx),
167
+ baseline: li * lineHeightPx + lineHeightPx * 0.8,
168
+ hyphenated,
169
+ segments: lineSegments,
170
+ isLastLine,
171
+ ...(justifiedSpaceRatio !== undefined ? { justifiedSpaceRatio } : {}),
172
+ });
173
+ // Next line starts after the break
174
+ lineStart = breakAt + 1;
175
+ }
176
+ return lines;
177
+ }
178
+ //# sourceMappingURL=pretextAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pretextAdapter.js","sourceRoot":"","sources":["../../src/knuthPlass/pretextAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Adapter between the bold/italic/math-aware "rich token" stream produced
3
+ * by the measure pipeline and the Knuth-Plass item stream, plus
4
+ * reconstruction of VDT lines from the optimal breakpoint sequence.
5
+ */
6
+ import type { VDTLine } from '../vdt';
7
+ import type { TextAlign } from '../types';
8
+ import type { KPItem } from './types';
9
+ interface RichBreakPoint {
10
+ charIndex: number;
11
+ widthBefore: number;
12
+ }
13
+ interface RichToken {
14
+ text: string;
15
+ bold: boolean;
16
+ italic: boolean;
17
+ kind: 'text' | 'space';
18
+ width: number;
19
+ breakPoints?: RichBreakPoint[];
20
+ hyphenWidth?: number;
21
+ mathRender?: import('../math/types').MathRender;
22
+ }
23
+ export declare function richTokensToItems(tokens: RichToken[], normalSpaceWidth: number, maxStretchRatio: number, minShrinkRatio: number): KPItem[];
24
+ export declare function reconstructRichLines(items: KPItem[], breaks: number[], tokens: RichToken[], lineHeightPx: number, lineWidthFn: (lineIndex: number) => number, lineIndentFn: (lineIndex: number) => number, normalSpaceWidth: number, textAlign: TextAlign): VDTLine[];
25
+ export {};
26
+ //# sourceMappingURL=richAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"richAdapter.d.ts","sourceRoot":"","sources":["../../src/knuthPlass/richAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,QAAQ,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,SAAS,CAAC;AAIrD,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,eAAe,EAAE,UAAU,CAAC;CACjD;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EAAE,EACnB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CA4FV;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,MAAM,EAAE,SAAS,EAAE,EACnB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC1C,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAC3C,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,SAAS,GACnB,OAAO,EAAE,CAuGX"}