@miliastry/quasar 1.0.6 → 1.1.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 (273) hide show
  1. package/dist/Visuals/lyne.css +117 -6
  2. package/dist/Visuals/osu.css +36 -5
  3. package/dist/index.js +9664 -3282
  4. package/dist/index.mjs +9535 -3283
  5. package/dist/types/Analysis/Contracts/AnalysisReport.d.ts +22 -0
  6. package/dist/types/Analysis/Contracts/Contribution.d.ts +68 -0
  7. package/dist/types/Analysis/Contracts/Pass.d.ts +59 -0
  8. package/dist/types/Analysis/Contracts/PipelineContext.d.ts +34 -0
  9. package/dist/types/Analysis/Passes/Analysis/ColorUsageAnalyzer.d.ts +56 -0
  10. package/dist/types/Analysis/Passes/Analysis/GradientAnalyzer.d.ts +111 -0
  11. package/dist/types/Analysis/Passes/Analysis/MergeableColorAnalyzer.d.ts +26 -0
  12. package/dist/types/Analysis/Passes/Analysis/RainbowAnalyzer.d.ts +47 -0
  13. package/dist/types/Analysis/Passes/Analysis/SymbolAnalyzer.d.ts +89 -0
  14. package/dist/types/Analysis/Passes/Analysis/WaveAnalyzer.d.ts +44 -0
  15. package/dist/types/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.d.ts +4 -0
  16. package/dist/types/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.d.ts +4 -0
  17. package/dist/types/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.d.ts +4 -0
  18. package/dist/types/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.d.ts +4 -0
  19. package/dist/types/Analysis/Passes/Decision/DefaultDecision.d.ts +30 -0
  20. package/dist/types/Analysis/Passes/Decision/PaletteRemapDecision.d.ts +169 -0
  21. package/dist/types/Analysis/Passes/Decision/__tests__/DefaultDecision.test.d.ts +4 -0
  22. package/dist/types/Analysis/Passes/Transform/CollapseGradientTransform.d.ts +37 -0
  23. package/dist/types/Analysis/Passes/Transform/MergeColorsTransform.d.ts +28 -0
  24. package/dist/types/Analysis/Passes/Transform/RainbowCollapseTransform.d.ts +19 -0
  25. package/dist/types/Analysis/Passes/Transform/WaveCollapseTransform.d.ts +20 -0
  26. package/dist/types/Analysis/Passes/Utility/CharacterCountAnalyzer.d.ts +19 -0
  27. package/dist/types/Analysis/Pipeline/Pipeline.d.ts +69 -0
  28. package/dist/types/Analysis/Pipeline/PipelineBuilder.d.ts +31 -0
  29. package/dist/types/Analysis/Pipeline/PipelineStage.d.ts +17 -0
  30. package/dist/types/Analysis/Utils/color-utils.d.ts +60 -0
  31. package/dist/types/Analysis/__tests__/Integration.test.d.ts +8 -0
  32. package/dist/types/Analysis/__tests__/PaletteRemap.test.d.ts +14 -0
  33. package/dist/types/Analysis/__tests__/Pipeline.test.d.ts +10 -0
  34. package/dist/types/Analysis/__tests__/RoundTrip.test.d.ts +30 -0
  35. package/dist/types/Analysis/__tests__/SymbolAnalyzer.test.d.ts +11 -0
  36. package/dist/types/Analysis/index.d.ts +40 -0
  37. package/dist/types/BBCode/BBCodeDocumentModel.d.ts +92 -0
  38. package/dist/types/BBCode/BBCodeToGreenNode.d.ts +111 -0
  39. package/dist/types/BBCode/Parser.d.ts +78 -0
  40. package/dist/types/BBCode/index.d.ts +4 -0
  41. package/dist/types/Collab/positions.d.ts +55 -0
  42. package/dist/types/Commands/Command.d.ts +37 -0
  43. package/dist/types/Commands/CommandRegistry.d.ts +48 -0
  44. package/dist/types/Commands/DeleteNode.d.ts +7 -0
  45. package/dist/types/Commands/InsertText.d.ts +8 -0
  46. package/dist/types/Commands/SplitMerge.d.ts +9 -0
  47. package/dist/types/Commands/WrapInTag.d.ts +8 -0
  48. package/dist/types/Commands/index.d.ts +6 -0
  49. package/dist/types/Diff/TreeDiffer.d.ts +52 -0
  50. package/dist/types/Diff/__tests__/TreeDiffer.test.d.ts +1 -0
  51. package/dist/types/Diff/index.d.ts +2 -0
  52. package/dist/types/Edits/EditPlan.d.ts +144 -0
  53. package/dist/types/Edits/Optimizer.d.ts +78 -0
  54. package/dist/types/Edits/Rules/Rule.d.ts +91 -0
  55. package/dist/types/Edits/Rules/dropEmptyTags.d.ts +40 -0
  56. package/dist/types/Edits/Rules/dropRedundantNesting.d.ts +59 -0
  57. package/dist/types/Edits/Rules/index.d.ts +9 -0
  58. package/dist/types/Edits/Rules/mergeAdjacent.d.ts +93 -0
  59. package/dist/types/Edits/Rules/reorderWrappers.d.ts +42 -0
  60. package/dist/types/Edits/Rules/shortenHex.d.ts +30 -0
  61. package/dist/types/Edits/Rules/tagValue.d.ts +56 -0
  62. package/dist/types/Edits/Rules/unwrapInvisibleColor.d.ts +47 -0
  63. package/dist/types/Edits/applyEdits.d.ts +36 -0
  64. package/dist/types/Edits/index.d.ts +6 -0
  65. package/dist/types/Events/EventBus.d.ts +103 -0
  66. package/dist/types/Events/index.d.ts +2 -0
  67. package/dist/types/Formatter/Formatter.d.ts +32 -0
  68. package/dist/types/Formatter/index.d.ts +2 -0
  69. package/dist/types/HTML/HTMLDocumentModel.d.ts +13 -0
  70. package/dist/types/HTML/HTMLToGreenNode.d.ts +4 -0
  71. package/dist/types/Incremental/BracketIndex.d.ts +101 -0
  72. package/dist/types/Incremental/ChangeTracker.d.ts +69 -0
  73. package/dist/types/Incremental/IncrementalParser.d.ts +246 -0
  74. package/dist/types/Incremental/__tests__/BracketIndex.test.d.ts +1 -0
  75. package/dist/types/Incremental/__tests__/IncrementalParser.test.d.ts +1 -0
  76. package/dist/types/Incremental/index.d.ts +4 -0
  77. package/dist/types/Lexer/BBCodeLexer.d.ts +74 -0
  78. package/dist/types/Lexer/Lexer.d.ts +54 -0
  79. package/dist/types/Lexer/index.d.ts +4 -0
  80. package/dist/types/Linter/Linter.d.ts +58 -0
  81. package/dist/types/Linter/index.d.ts +2 -0
  82. package/dist/types/Markdown/MarkdownAST.d.ts +122 -0
  83. package/dist/types/Markdown/MarkdownDocumentModel.d.ts +15 -0
  84. package/dist/types/Markdown/MarkdownLexer.d.ts +155 -0
  85. package/dist/types/Markdown/MarkdownParser.d.ts +42 -0
  86. package/dist/types/Markdown/MarkdownToGreenNode.d.ts +6 -0
  87. package/dist/types/MilHibri/MilHibriDocumentModel.d.ts +21 -0
  88. package/dist/types/Model/DocumentModel.d.ts +318 -0
  89. package/dist/types/Model/NodeFactory.d.ts +29 -0
  90. package/dist/types/Model/TagRegistry.d.ts +165 -0
  91. package/dist/types/Model/index.d.ts +5 -0
  92. package/dist/types/Plugins/PluginAPI.d.ts +44 -0
  93. package/dist/types/Plugins/PluginRegistry.d.ts +81 -0
  94. package/dist/types/Plugins/index.d.ts +3 -0
  95. package/dist/types/Queries/QueryEngine.d.ts +32 -0
  96. package/dist/types/Queries/index.d.ts +1 -0
  97. package/dist/types/Reconciler/SurgicalReconciler.d.ts +23 -0
  98. package/dist/types/RenderPipeline/RenderPipeline.d.ts +46 -0
  99. package/dist/types/RenderPipeline/RenderTree.d.ts +55 -0
  100. package/dist/types/RenderPipeline/index.d.ts +4 -0
  101. package/dist/types/Repair/NestingRepair.d.ts +48 -0
  102. package/dist/types/Repair/index.d.ts +1 -0
  103. package/dist/types/Semantic/SemanticAnalyzer.d.ts +321 -0
  104. package/dist/types/Semantic/index.d.ts +2 -0
  105. package/dist/types/Symbols/SymbolTable.d.ts +47 -0
  106. package/dist/types/Symbols/index.d.ts +1 -0
  107. package/dist/types/Syntax/GreenNode.d.ts +154 -0
  108. package/dist/types/Syntax/GreenNodePool.d.ts +134 -0
  109. package/dist/types/Syntax/NodeMatcher.d.ts +75 -0
  110. package/dist/types/Syntax/RedNode.d.ts +280 -0
  111. package/dist/types/Syntax/RedNodeStore.d.ts +116 -0
  112. package/dist/types/Syntax/TreeBuilder.d.ts +54 -0
  113. package/dist/types/Syntax/__tests__/GreenNode.test.d.ts +1 -0
  114. package/dist/types/Syntax/__tests__/RedNode.test.d.ts +1 -0
  115. package/dist/types/Syntax/__tests__/RedNodeStore.test.d.ts +1 -0
  116. package/dist/types/Syntax/greenEdit.d.ts +64 -0
  117. package/dist/types/Syntax/hash.d.ts +17 -0
  118. package/dist/types/Syntax/index.d.ts +8 -0
  119. package/dist/types/Syntax/nodeAttr.d.ts +63 -0
  120. package/dist/types/Syntax/partition.d.ts +67 -0
  121. package/dist/types/Syntax/preserveNodeIds.d.ts +47 -0
  122. package/dist/types/Tokens/TokenResolver.d.ts +25 -0
  123. package/dist/types/Tokens/index.d.ts +1 -0
  124. package/dist/types/Transactions/Transaction.d.ts +36 -0
  125. package/dist/types/Transactions/UndoManager.d.ts +63 -0
  126. package/dist/types/Transactions/index.d.ts +3 -0
  127. package/dist/types/Transformers/ASTOptimizer.d.ts +34 -0
  128. package/dist/types/Transformers/GradientTransformer.d.ts +18 -0
  129. package/dist/types/Transformers/GrowTransformer.d.ts +16 -0
  130. package/dist/types/Transformers/RainbowTransformer.d.ts +17 -0
  131. package/dist/types/Transformers/SineWaveTransformer.d.ts +17 -0
  132. package/dist/types/Transformers/Transformer.d.ts +17 -0
  133. package/dist/types/Types/core.d.ts +104 -0
  134. package/dist/types/Types/diagnostics.d.ts +85 -0
  135. package/dist/types/Types/index.d.ts +11 -0
  136. package/dist/types/Types/operations.d.ts +109 -0
  137. package/dist/types/Types/queries.d.ts +67 -0
  138. package/dist/types/Types/symbols.d.ts +42 -0
  139. package/dist/types/Types/tokens.d.ts +75 -0
  140. package/dist/types/Utils/BBCodeGenerator.d.ts +21 -0
  141. package/dist/types/Utils/ColorMath.d.ts +92 -0
  142. package/dist/types/Utils/EffectMath.d.ts +643 -0
  143. package/dist/types/Utils/TagVocabulary.d.ts +104 -0
  144. package/dist/types/Utils/TagVocabulary.test.d.ts +1 -0
  145. package/dist/types/Utils/color.d.ts +29 -0
  146. package/dist/types/Utils/dom-to-svg.d.ts +28 -0
  147. package/dist/types/Utils/dom-to-svg.test.d.ts +1 -0
  148. package/dist/types/Utils/treeTransformers.d.ts +160 -0
  149. package/dist/types/Visitors/BBBlocksExporter.d.ts +27 -0
  150. package/dist/types/Visitors/BBCodeExporter.d.ts +90 -0
  151. package/dist/types/Visitors/BlockPatcher.d.ts +91 -0
  152. package/dist/types/Visitors/DOMMorpher.d.ts +13 -0
  153. package/dist/types/Visitors/HTMLRenderer.d.ts +380 -0
  154. package/dist/types/Visitors/JSONExporter.d.ts +42 -0
  155. package/dist/types/Visitors/MarkdownExporter.d.ts +28 -0
  156. package/dist/types/Visitors/SVGRenderer.d.ts +16 -0
  157. package/dist/types/Visitors/TiptapExporter.d.ts +40 -0
  158. package/dist/types/Visitors/Visitor.d.ts +35 -0
  159. package/dist/types/Visitors/index.d.ts +9 -0
  160. package/dist/types/Visuals/BoxDrawer.d.ts +49 -0
  161. package/dist/types/Visuals/index.d.ts +38 -0
  162. package/dist/types/index.d.ts +154 -0
  163. package/package.json +14 -10
  164. package/src/Analysis/Passes/Analysis/ColorUsageAnalyzer.ts +103 -0
  165. package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +294 -20
  166. package/src/Analysis/Passes/Analysis/SymbolAnalyzer.ts +257 -0
  167. package/src/Analysis/Passes/Decision/PaletteRemapDecision.ts +425 -0
  168. package/src/Analysis/Pipeline/Pipeline.ts +15 -2
  169. package/src/Analysis/index.ts +8 -2
  170. package/src/BBCode/BBCodeDocumentModel.ts +3 -0
  171. package/src/BBCode/BBCodeToGreenNode.ts +18 -12
  172. package/src/BBCode/Parser.ts +38 -1
  173. package/src/Edits/EditPlan.ts +290 -0
  174. package/src/Edits/Optimizer.ts +185 -0
  175. package/src/Edits/Rules/Rule.ts +145 -0
  176. package/src/Edits/Rules/dropEmptyTags.ts +110 -0
  177. package/src/Edits/Rules/dropRedundantNesting.ts +120 -0
  178. package/src/Edits/Rules/index.ts +28 -0
  179. package/src/Edits/Rules/mergeAdjacent.ts +224 -0
  180. package/src/Edits/Rules/reorderWrappers.ts +154 -0
  181. package/src/Edits/Rules/shortenHex.ts +79 -0
  182. package/src/Edits/Rules/tagValue.ts +105 -0
  183. package/src/Edits/Rules/unwrapInvisibleColor.ts +93 -0
  184. package/src/Edits/applyEdits.ts +54 -0
  185. package/src/Edits/index.ts +22 -0
  186. package/src/Events/EventBus.ts +18 -0
  187. package/src/HTML/HTMLToGreenNode.ts +185 -37
  188. package/src/Incremental/BracketIndex.ts +249 -0
  189. package/src/Incremental/IncrementalParser.ts +464 -41
  190. package/src/Lexer/BBCodeLexer.ts +25 -3
  191. package/src/Lexer/index.ts +1 -1
  192. package/src/Markdown/MarkdownAST.ts +65 -2
  193. package/src/Markdown/MarkdownLexer.ts +69 -14
  194. package/src/Markdown/MarkdownParser.ts +749 -62
  195. package/src/Markdown/MarkdownToGreenNode.ts +148 -27
  196. package/src/MilHibri/MilHibriDocumentModel.ts +56 -0
  197. package/src/Model/DocumentModel.ts +138 -5
  198. package/src/Model/TagRegistry.ts +129 -134
  199. package/src/Reconciler/SurgicalReconciler.ts +460 -0
  200. package/src/Repair/NestingRepair.ts +116 -0
  201. package/src/Repair/index.ts +1 -0
  202. package/src/Semantic/SemanticAnalyzer.ts +1802 -65
  203. package/src/Syntax/GreenNodePool.ts +12 -12
  204. package/src/Syntax/RedNode.ts +17 -3
  205. package/src/Syntax/RedNodeStore.ts +9 -1
  206. package/src/Syntax/nodeAttr.ts +172 -0
  207. package/src/Tokens/TokenResolver.ts +55 -0
  208. package/src/Tokens/index.ts +1 -0
  209. package/src/Types/core.ts +15 -0
  210. package/src/Utils/ColorMath.ts +276 -55
  211. package/src/Utils/EffectMath.ts +2462 -0
  212. package/src/Utils/TagVocabulary.ts +141 -0
  213. package/src/Utils/dom-to-svg.ts +28 -12
  214. package/src/Visitors/BBBlocksExporter.ts +15 -1
  215. package/src/Visitors/BBCodeExporter.ts +319 -32
  216. package/src/Visitors/BlockPatcher.ts +87 -11
  217. package/src/Visitors/DOMMorpher.ts +15 -5
  218. package/src/Visitors/HTMLRenderer.ts +374 -151
  219. package/src/Visitors/MarkdownExporter.ts +98 -41
  220. package/src/Visitors/TiptapExporter.ts +1 -0
  221. package/src/Visuals/index.ts +7 -4
  222. package/src/Visuals/lyne.css +117 -6
  223. package/src/Visuals/osu.css +36 -5
  224. package/src/index.ts +172 -5
  225. package/dist/index.d.mts +0 -4612
  226. package/dist/index.d.ts +0 -4612
  227. package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +0 -135
  228. package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +0 -84
  229. package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +0 -99
  230. package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +0 -119
  231. package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +0 -179
  232. package/src/Analysis/__tests__/Integration.test.ts +0 -162
  233. package/src/Analysis/__tests__/Pipeline.test.ts +0 -133
  234. package/src/Diff/__tests__/TreeDiffer.test.ts +0 -65
  235. package/src/Incremental/__tests__/IncrementalParser.test.ts +0 -164
  236. package/src/Syntax/__tests__/GreenNode.test.ts +0 -33
  237. package/src/Syntax/__tests__/RedNode.test.ts +0 -81
  238. package/src/Syntax/__tests__/RedNodeStore.test.ts +0 -104
  239. package/src/Tests/ASTOptimizerIdempotence.test.ts +0 -77
  240. package/src/Tests/BlockPatcher.test.ts +0 -437
  241. package/src/Tests/BlockPatcherWindowed.test.ts +0 -364
  242. package/src/Tests/BoxDrawer.test.ts +0 -217
  243. package/src/Tests/BoxRichTitle.test.ts +0 -105
  244. package/src/Tests/Chars500kBenchmark.test.ts +0 -151
  245. package/src/Tests/Chars500kEdits.test.ts +0 -321
  246. package/src/Tests/CollabPositions.test.ts +0 -146
  247. package/src/Tests/CompilerPathProfiling.test.ts +0 -186
  248. package/src/Tests/DOMMorpher.test.ts +0 -142
  249. package/src/Tests/DomPatchPerf.test.ts +0 -60
  250. package/src/Tests/EffectSegments.snapshot.json +0 -616
  251. package/src/Tests/EffectSegments.test.ts +0 -68
  252. package/src/Tests/FindNodeAtOffset.test.ts +0 -65
  253. package/src/Tests/Fuzzer.test.ts +0 -166
  254. package/src/Tests/GreenNodePool.test.ts +0 -153
  255. package/src/Tests/Lexer.test.ts +0 -238
  256. package/src/Tests/LyneMode.test.ts +0 -291
  257. package/src/Tests/ModelCoherence.test.ts +0 -180
  258. package/src/Tests/Partition.test.ts +0 -238
  259. package/src/Tests/PluginTags.test.ts +0 -150
  260. package/src/Tests/ProblematicSection.test.ts +0 -46
  261. package/src/Tests/ProblematicSectionHTML.test.ts +0 -58
  262. package/src/Tests/RedReuse.test.ts +0 -134
  263. package/src/Tests/ReproDelete20k.test.ts +0 -62
  264. package/src/Tests/SemanticValidators.test.ts +0 -136
  265. package/src/Tests/StableNodeIds.test.ts +0 -210
  266. package/src/Tests/StudioColorBloat.test.ts +0 -25
  267. package/src/Tests/StudioDebugText.test.ts +0 -27
  268. package/src/Tests/StudioTrailingChar.test.ts +0 -25
  269. package/src/Tests/StudioValidText.test.ts +0 -25
  270. package/src/Tests/UrlImgBug.test.ts +0 -23
  271. package/src/Tests/VisualBuilderFidelity.test.ts +0 -105
  272. package/src/Tests/referenceDocument.ts +0 -119
  273. package/src/Utils/dom-to-svg.test.ts +0 -86
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Quasar Analysis Framework — Palette Remap Decision
3
+ *
4
+ * Turns an AnalysisReport into a plan for restyling a document with a
5
+ * different palette: recolour its colour tags, swap its decorative glyphs,
6
+ * replace its divider lines.
7
+ *
8
+ * ## The plan is applied by range, not by rebuilding the tree
9
+ *
10
+ * Every other DecisionPass in this framework feeds a TransformPass that
11
+ * returns a new Green Tree, which is then serialized. That is the wrong shape
12
+ * for restyling a document someone already wrote: `BBCodeExporter` rebuilds
13
+ * BBCode from node kinds and metadata rather than replaying source bytes, so
14
+ * re-exporting a whole document also rewrites the parts nobody asked to
15
+ * change — `[B]` becomes `[b]`, `[color = #F00]` loses its spacing, CRLF
16
+ * becomes LF.
17
+ *
18
+ * So the actions here carry a `range` and a literal `replacement` string, and
19
+ * are meant to be applied directly to the source text. Everything outside
20
+ * those ranges is never re-serialized and therefore cannot drift. The Decision
21
+ * stage is still the right home — it consumes a report and describes intended
22
+ * mutations without touching the tree — but no TransformPass consumes it.
23
+ *
24
+ * Apply the actions **last range first**. They are emitted in source order,
25
+ * and rewriting front to back invalidates every offset that follows.
26
+ *
27
+ * ## What each kind of thing becomes
28
+ *
29
+ * **Colours inside a gradient** keep the gradient's shape. Each member tag is
30
+ * recoloured by sampling the new palette at the member's own position along
31
+ * the ramp, passed through the easing the original gradient was detected with.
32
+ * The result reads as the same gradient wearing a different palette, rather
33
+ * than as a new gradient.
34
+ *
35
+ * **Standalone colours** map to their nearest palette entry by perceptual
36
+ * distance in OKLab, so a pink stays the palette's pink rather than becoming
37
+ * whichever colour happens to be first.
38
+ *
39
+ * **Symbols** are substituted glyph for glyph, and **separators** wholesale.
40
+ * Both substitutions are stable across the document: a given source glyph
41
+ * always maps to the same palette glyph, so a document that used `✧` as its
42
+ * motif comes out using one motif rather than a scatter.
43
+ *
44
+ * @see ColorUsageAnalyzer — supplies the per-tag offsets this pass edits
45
+ * @see GradientAnalyzer — supplies the ramp shape those tags belong to
46
+ * @see SymbolAnalyzer — supplies the glyph runs
47
+ */
48
+ import type { DecisionPass, TransformationPlan, TransformAction } from '../../Contracts/Pass';
49
+ import type { AnalysisReport } from '../../Contracts/AnalysisReport';
50
+ import type { PipelineContext } from '../../Contracts/PipelineContext';
51
+ /**
52
+ * The palette to restyle towards.
53
+ *
54
+ * Structural, not imported: Quasar has no dependency on the application's
55
+ * theme catalogue, and any object with these three lists satisfies it.
56
+ */
57
+ export interface Palette {
58
+ /** Hex colours, ordered as a ramp from first to last. */
59
+ readonly colors: readonly string[];
60
+ /** Decorative glyphs, in preference order. */
61
+ readonly symbols: readonly string[];
62
+ /** Whole divider lines. */
63
+ readonly separators: readonly string[];
64
+ }
65
+ export interface PaletteRemapOptions {
66
+ /**
67
+ * Below this confidence an action is still emitted, but marked
68
+ * `recommended: false`.
69
+ *
70
+ * Nothing is dropped. A caller that hides low-confidence findings can never
71
+ * offer them, and the glyphs that land down here — `≈` in a sum, `→` in a
72
+ * sentence — are exactly the ones a person should get to look at before
73
+ * they are rewritten. Filtering is the caller's decision; this pass only
74
+ * says which side of the line each action falls on.
75
+ */
76
+ readonly minConfidence?: number;
77
+ }
78
+ /** Every action this pass emits shares one shape. */
79
+ export interface RemapAction extends TransformAction {
80
+ readonly kind: 'recolor' | 'resymbol' | 'reseparator';
81
+ readonly payload: {
82
+ /** Source span to overwrite. */
83
+ readonly range: {
84
+ readonly start: number;
85
+ readonly end: number;
86
+ };
87
+ /** Literal text to write in its place. */
88
+ readonly replacement: string;
89
+ /** What is there now, for previewing the change. */
90
+ readonly from: string;
91
+ /** What it becomes. */
92
+ readonly to: string;
93
+ readonly confidence: number;
94
+ readonly recommended: boolean;
95
+ /** Only on `recolor`: whether the tag belonged to a detected gradient. */
96
+ readonly gradient?: boolean;
97
+ };
98
+ }
99
+ export declare class PaletteRemapDecision implements DecisionPass {
100
+ readonly id = "palette-remap";
101
+ private readonly palette;
102
+ private readonly minConfidence;
103
+ /**
104
+ * Substitution tables, rebuilt per `run` so the pass stays reusable and
105
+ * every run over the same report produces the same plan.
106
+ */
107
+ private symbolMap;
108
+ private separatorMap;
109
+ constructor(palette: Palette, options?: PaletteRemapOptions);
110
+ run(report: AnalysisReport, _context: PipelineContext): TransformationPlan;
111
+ private planColors;
112
+ /**
113
+ * Where this tag sits along its gradient, resampled onto the new palette.
114
+ *
115
+ * Position comes from the tag's ordinal among the gradient's members rather
116
+ * than from its offset, because the members are evenly spaced *as tags* — a
117
+ * gradient over `Hello` has five of them regardless of how wide each tag's
118
+ * text is.
119
+ */
120
+ private gradientColorFor;
121
+ /**
122
+ * Sample the palette as a continuous ramp, interpolating in OKLab.
123
+ *
124
+ * `ColorMath.mixMultiple` does the same walk in RGB, which darkens and
125
+ * desaturates through the middle of a blend — the reason the gradient
126
+ * analyzers work in OKLab in the first place. Sampling rather than mapping
127
+ * palette entries one-to-one is what preserves the original stop count: a
128
+ * three-stop gradient stays three stops when restyled with a five-colour
129
+ * palette, instead of gaining two.
130
+ */
131
+ private samplePalette;
132
+ /**
133
+ * The palette entry that looks most like the colour already there.
134
+ *
135
+ * Perceptual distance rather than index order: a document's pink should come
136
+ * back as the palette's pink, not as whichever colour the palette happens to
137
+ * list first.
138
+ */
139
+ private nearestPaletteColor;
140
+ private planSymbols;
141
+ private planSeparators;
142
+ /**
143
+ * Assign a replacement for `source`, remembering it.
144
+ *
145
+ * Distinct sources are handed palette entries in first-seen order.
146
+ * Recording the choice is what keeps the document coherent: every later `✧`
147
+ * gets the same replacement as the first one, so a motif stays a motif.
148
+ *
149
+ * Entries already spoken for are skipped — including the identities
150
+ * `reserveIdentities` claimed before this ran — so distinct sources keep
151
+ * distinct replacements for as long as the palette has them. Once it runs
152
+ * out the assignment wraps, and glyphs begin to share.
153
+ */
154
+ private substitute;
155
+ /**
156
+ * Let everything the palette already contains keep its own place, before
157
+ * anything else is handed out.
158
+ *
159
+ * This has to happen up front rather than as each source is reached.
160
+ * Assignment follows document order, so in `✧ then ✿` the unowned `✧` would
161
+ * otherwise claim `✿` first and the real `✿` would arrive to find its own
162
+ * identity taken — displacing it onto a glyph the document never used.
163
+ *
164
+ * Holding identities fixed is what makes restyling idempotent: a second pass
165
+ * with the same theme finds every glyph already in place and changes
166
+ * nothing.
167
+ */
168
+ private reserveIdentities;
169
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Tests for DefaultDecision
3
+ */
4
+ export {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Quasar Analysis Framework — Collapse Gradient Transform
3
+ *
4
+ * Applies `collapse-gradient` actions from a TransformationPlan.
5
+ * Each action targets a sequence of adjacent [color] nodes and replaces
6
+ * them with a single [gradient] node containing all text children.
7
+ *
8
+ * The transform operates on the Green Tree and returns a new tree —
9
+ * it NEVER mutates the original.
10
+ *
11
+ * @example
12
+ * Before:
13
+ * [color=#FF0000]H[/color][color=#EE1100]e[/color][color=#DD2200]l[/color]
14
+ * After:
15
+ * [gradient=#FF0000,#EE1100,#DD2200]Hello[/gradient]
16
+ *
17
+ * @see TransformPass
18
+ */
19
+ import type { TransformPass, TransformationPlan } from '../../Contracts/Pass';
20
+ import type { PipelineContext } from '../../Contracts/PipelineContext';
21
+ import type { GreenNode } from '../../../Syntax/GreenNode';
22
+ export declare class CollapseGradientTransform implements TransformPass {
23
+ readonly id = "collapse-gradient";
24
+ run(tree: GreenNode, plan: TransformationPlan, _context: PipelineContext): GreenNode;
25
+ /**
26
+ * Walk the tree and collapse any sequences that fall within our ranges.
27
+ */
28
+ private transformNode;
29
+ /**
30
+ * Rebuild a node with the same kind/text/range but new children.
31
+ */
32
+ private rebuildNode;
33
+ /**
34
+ * Extract hex colour from a color node's text.
35
+ */
36
+ private extractHex;
37
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Quasar Analysis Framework — Merge Colors Transform
3
+ *
4
+ * Applies `merge-colors` actions from a TransformationPlan.
5
+ * Each action targets a sequence of identical consecutive [color=#HEX]
6
+ * nodes and merges them into a single `[color]` wrapper with combined text.
7
+ *
8
+ * The transform operates on the Green Tree and returns a new tree —
9
+ * it NEVER mutates the original.
10
+ *
11
+ * @example
12
+ * Before:
13
+ * [color=#FF0000]H[/color][color=#FF0000]e[/color][color=#FF0000]l[/color]
14
+ * After:
15
+ * [color=#FF0000]Hel[/color]
16
+ *
17
+ * @see TransformPass
18
+ */
19
+ import type { TransformPass, TransformationPlan } from '../../Contracts/Pass';
20
+ import type { PipelineContext } from '../../Contracts/PipelineContext';
21
+ import type { GreenNode } from '../../../Syntax/GreenNode';
22
+ export declare class MergeColorsTransform implements TransformPass {
23
+ readonly id = "merge-colors";
24
+ run(tree: GreenNode, plan: TransformationPlan, _context: PipelineContext): GreenNode;
25
+ private transformNode;
26
+ private rebuildNode;
27
+ private extractHex;
28
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Quasar Analysis Framework — Rainbow Collapse Transform
3
+ *
4
+ * Applies `collapse-rainbow` actions from a TransformationPlan.
5
+ * Replaces sequences of [color] nodes forming a hue-rotation pattern
6
+ * with a single [rainbow] node containing all text children.
7
+ *
8
+ * @example
9
+ * Before: [color=#FF0000]R[/color][color=#FFFF00]O[/color][color=#00FF00]Y[/color]
10
+ * After: [rainbow]ROY[/rainbow]
11
+ */
12
+ import type { TransformPass, TransformationPlan } from '../../Contracts/Pass';
13
+ import type { PipelineContext } from '../../Contracts/PipelineContext';
14
+ import type { GreenNode } from '../../../Syntax/GreenNode';
15
+ export declare class RainbowCollapseTransform implements TransformPass {
16
+ readonly id = "rainbow-collapse";
17
+ run(tree: GreenNode, plan: TransformationPlan, _context: PipelineContext): GreenNode;
18
+ private transformNode;
19
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Quasar Analysis Framework — Wave Collapse Transform
3
+ *
4
+ * Applies `collapse-wave` actions from a TransformationPlan.
5
+ * Replaces sequences of [size=N] nodes forming a sinusoidal pattern
6
+ * with a single [grow] node containing all text children and the
7
+ * detected size range in metadata.
8
+ *
9
+ * @example
10
+ * Before: [size=90]A[/size][size=150]B[/size][size=90]C[/size]
11
+ * After: [grow]ABC[/grow] (with metadata: min=90, max=150)
12
+ */
13
+ import type { TransformPass, TransformationPlan } from '../../Contracts/Pass';
14
+ import type { PipelineContext } from '../../Contracts/PipelineContext';
15
+ import type { GreenNode } from '../../../Syntax/GreenNode';
16
+ export declare class WaveCollapseTransform implements TransformPass {
17
+ readonly id = "wave-collapse";
18
+ run(tree: GreenNode, plan: TransformationPlan, _context: PipelineContext): GreenNode;
19
+ private transformNode;
20
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Quasar Analysis Framework — Character Count Analyzer (Proof of Concept)
3
+ *
4
+ * The simplest possible AnalyzerPass: it walks the Green Tree and counts
5
+ * text characters. This validates that the full pipeline works:
6
+ *
7
+ * Green Tree → Analyzer → Contribution → Aggregated Report
8
+ *
9
+ * No algorithms, no colours, no decisions — just validating the pipe.
10
+ */
11
+ import type { AnalyzerPass } from '../../Contracts/Pass';
12
+ import type { PipelineContext } from '../../Contracts/PipelineContext';
13
+ import type { Contribution } from '../../Contracts/Contribution';
14
+ import type { GreenNode } from '../../../Syntax/GreenNode';
15
+ export declare class CharacterCountAnalyzer implements AnalyzerPass {
16
+ readonly id = "character-count";
17
+ run(tree: GreenNode, _context: PipelineContext): Contribution[];
18
+ private countChars;
19
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Quasar Analysis Framework — Pipeline
3
+ *
4
+ * The Pipeline is itself a Pass — it can be composed inside larger
5
+ * pipelines. Execution is strictly ordered:
6
+ *
7
+ * 1. All analysis passes run, collecting contributions.
8
+ * 2. The aggregated AnalysisReport is fed to each decision pass.
9
+ * 3. Each transform pass receives the current tree + plan and
10
+ * returns a new tree (never mutating the original).
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const pipeline = new Pipeline([
15
+ * { stage: 'analysis', pass: new CharacterCountAnalyzer() },
16
+ * ])
17
+ * const report = pipeline.run(tree, context)
18
+ * ```
19
+ */
20
+ import type { AnalyzerPass, DecisionPass, TransformPass, TransformationPlan } from '../Contracts/Pass';
21
+ import type { AnalysisReport } from '../Contracts/AnalysisReport';
22
+ import type { PipelineContext } from '../Contracts/PipelineContext';
23
+ import type { PipelineStage } from './PipelineStage';
24
+ import type { GreenNode } from '../../Syntax/GreenNode';
25
+ interface StageEntry {
26
+ readonly stage: PipelineStage;
27
+ readonly pass: AnalyzerPass | DecisionPass | TransformPass;
28
+ }
29
+ export interface PipelineResult {
30
+ /** The final (possibly transformed) Green Tree. */
31
+ readonly tree: GreenNode;
32
+ /** The aggregated analysis report. */
33
+ readonly report: AnalysisReport;
34
+ /**
35
+ * The plan the last DecisionPass produced, empty when none ran.
36
+ *
37
+ * Usually this is an intermediate the transform stage consumes and the
38
+ * caller never needs. It is surfaced because a plan is not always something
39
+ * to execute against the tree: a pass may describe edits meant to be applied
40
+ * to the source text by range, in which case the plan *is* the output and
41
+ * there is no transform stage to hand it to.
42
+ */
43
+ readonly plan: TransformationPlan;
44
+ }
45
+ export declare class Pipeline {
46
+ private readonly stages;
47
+ constructor(stages: readonly StageEntry[]);
48
+ /**
49
+ * Execute the full pipeline against `tree` with the given `context`.
50
+ *
51
+ * @returns The final tree and analysis report.
52
+ */
53
+ run(tree: GreenNode, context: PipelineContext): PipelineResult;
54
+ /**
55
+ * Use PipelineBuilder to construct a Pipeline:
56
+ *
57
+ * ```ts
58
+ * import { PipelineBuilder } from './PipelineBuilder'
59
+ * const pipeline = new PipelineBuilder()
60
+ * .analysis(new CharacterCountAnalyzer())
61
+ * .build()
62
+ * ```
63
+ */
64
+ private runAnalysis;
65
+ private runDecision;
66
+ private runTransform;
67
+ private buildReport;
68
+ }
69
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Quasar Analysis Framework — Pipeline Builder
3
+ *
4
+ * Provides a fluent API for assembling a Pipeline from individually
5
+ * registered passes. Each stage (analysis / decision / transform)
6
+ * has its own registration method so TypeScript catches misuse at
7
+ * compile time.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const pipeline = Pipeline
12
+ * .builder()
13
+ * .analysis(new CharacterCountAnalyzer())
14
+ * .decision(new DefaultDecision())
15
+ * .transform(new CollapseGradientTransform())
16
+ * .build()
17
+ * ```
18
+ */
19
+ import type { AnalyzerPass, DecisionPass, TransformPass } from '../Contracts/Pass';
20
+ import { Pipeline } from './Pipeline';
21
+ export declare class PipelineBuilder {
22
+ private readonly passes;
23
+ /** Register one or more AnalyzerPasses (observation stage). */
24
+ analysis(...passes: AnalyzerPass[]): this;
25
+ /** Register one or more DecisionPasses (planning stage). */
26
+ decision(...passes: DecisionPass[]): this;
27
+ /** Register one or more TransformPasses (mutation stage). */
28
+ transform(...passes: TransformPass[]): this;
29
+ /** Build the Pipeline from the registered passes. */
30
+ build(): Pipeline;
31
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Quasar Analysis Framework — Pipeline Stage
3
+ *
4
+ * Passes are grouped into stages that execute in order:
5
+ *
6
+ * 1. Analysis — observe the tree, produce Contributions
7
+ * 2. Decision — consume the AnalysisReport, produce a TransformationPlan
8
+ * 3. Transform — apply the plan to produce a new Green Tree
9
+ *
10
+ * @see Pass
11
+ */
12
+ export declare const PipelineStage: {
13
+ readonly Analysis: 'analysis';
14
+ readonly Decision: 'decision';
15
+ readonly Transform: 'transform';
16
+ };
17
+ export type PipelineStage = (typeof PipelineStage)[keyof typeof PipelineStage];
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Quasar Analysis Framework — Color Utilities
3
+ *
4
+ * Shared utility functions for color node analysis across all passes.
5
+ * Extracted here to avoid duplication across GradientAnalyzer,
6
+ * RainbowAnalyzer, MergeableColorAnalyzer, etc.
7
+ *
8
+ * @module
9
+ */
10
+ import type { GreenNode } from '../../Syntax/GreenNode';
11
+ /**
12
+ * Extract the hex colour from a [color] GreenNode.
13
+ * Supports both "=#FF0000" and "#FF0000" formats.
14
+ * Returns null if the node is not a color node or has invalid hex.
15
+ */
16
+ export declare function extractHex(node: GreenNode): string | null;
17
+ /**
18
+ * Extract the size value from a [size] / [font_size] GreenNode.
19
+ * Supports "=150", "=90" formats.
20
+ * Returns null if the node is not a size node.
21
+ */
22
+ export declare function extractSize(node: GreenNode): number | null;
23
+ /**
24
+ * Sigmoid function to map a raw score to [0, 1] confidence.
25
+ * Centered at 0: sigmoid(0) = 0.5
26
+ * steepness controls the sharpness of the transition.
27
+ */
28
+ export declare function sigmoid(x: number, steepness?: number): number;
29
+ /**
30
+ * A detected sequence of adjacent similar nodes in the Green Tree.
31
+ */
32
+ export interface NodeSequence {
33
+ /** Extracted values (hex colours, sizes, etc.) in order */
34
+ readonly values: (string | number)[];
35
+ /** Start index in the parent's children array */
36
+ readonly startIdx: number;
37
+ /** End index (exclusive) in the parent's children array */
38
+ readonly endIdx: number;
39
+ }
40
+ /**
41
+ * Extract consecutive sequences of [color] or [font_size] nodes
42
+ * from a parent's children array.
43
+ *
44
+ * @param children - Direct children of a container node
45
+ * @param kind - The node kind to extract ('color' or 'font_size')
46
+ * @param extract - Function to extract values from matching nodes
47
+ * @returns Array of sequences found
48
+ */
49
+ export declare function extractSequences<T extends string | number>(children: GreenNode[], kind: string, extract: (node: GreenNode) => T | null): Array<{
50
+ values: T[];
51
+ startIdx: number;
52
+ endIdx: number;
53
+ }>;
54
+ /**
55
+ * Check if there are formatting tags between nodes in a sequence.
56
+ */
57
+ export declare function checkFormattingBreaks(children: GreenNode[], seq: {
58
+ startIdx: number;
59
+ endIdx: number;
60
+ }, targetKind: string): boolean;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Quasar Analysis Framework — Integration Tests
3
+ *
4
+ * End-to-end tests that exercise the full pipeline with real passes:
5
+ * GradientAnalyzer → DefaultDecision → CollapseGradientTransform
6
+ * MergeableColorAnalyzer → DefaultDecision → MergeColorsTransform
7
+ */
8
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Quasar Analysis Framework — Palette Remap
3
+ *
4
+ * Covers `ColorUsageAnalyzer` and `PaletteRemapDecision` together, because
5
+ * neither is useful alone: the analyzer supplies per-tag offsets, the gradient
6
+ * analyzer supplies the ramp those tags belong to, and the decision joins them.
7
+ *
8
+ * Most assertions run the plan through `applyPlan` and check the resulting
9
+ * *document*. Asserting on action payloads alone would let an off-by-one in a
10
+ * range pass unnoticed; rewriting the source with them cannot.
11
+ *
12
+ * @see RoundTrip.test.ts — establishes that editing by range is the safe move
13
+ */
14
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Quasar Analysis Framework — Pipeline Tests
3
+ *
4
+ * Validates that the core pipeline infrastructure works:
5
+ * - Pass interfaces are correctly typed
6
+ * - PipelineBuilder assembles passes
7
+ * - Pipeline executes them in order
8
+ * - CharacterCountAnalyzer (PoC) produces expected metrics
9
+ */
10
+ export {};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Quasar Analysis Framework — Source Round-Trip Fidelity
3
+ *
4
+ * Every other test in this folder builds Green Trees by hand with
5
+ * `greenNode()` / `greenLeaf()`. That proves the passes work, but it never
6
+ * proves the framework survives contact with a *parsed* document — and any
7
+ * feature that re-themes an existing user document depends on exactly that.
8
+ *
9
+ * This suite closes the gap by exercising the full chain end to end:
10
+ *
11
+ * source → BBCodeDocumentModel.rebuild → greenRoot
12
+ * → Pipeline.run → greenToRedNode → BBCodeExporter.export → source'
13
+ *
14
+ * It answers two questions a document-rewriting feature has to answer before
15
+ * it writes a single byte:
16
+ *
17
+ * 1. Is `source' === source` when nothing was transformed?
18
+ * (If not, re-exporting a whole document silently rewrites regions the
19
+ * user never asked to touch.)
20
+ *
21
+ * 2. Do the `range` offsets on Contributions land on the original source
22
+ * with character precision?
23
+ * (If they do, edits can be applied surgically to those spans and the
24
+ * untouched remainder of the document is never re-serialized.)
25
+ *
26
+ * The answers are: yes for canonical BBCode, and yes for offsets — but the
27
+ * exporter normalizes several non-canonical spellings, and corrupts three
28
+ * bare tags outright. Those are pinned below.
29
+ */
30
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Quasar Analysis Framework — Symbol Analyzer
3
+ *
4
+ * Exercised against *parsed* documents rather than hand-built Green Trees,
5
+ * because the analyzer's whole contract is that its offsets address real
6
+ * source. Every assertion that involves a range slices it back out of the
7
+ * input, so a drifting offset fails the test rather than passing silently.
8
+ *
9
+ * @see RoundTrip.test.ts — the same discipline applied to the export boundary
10
+ */
11
+ export {};
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Quasar Analysis Framework — Public API
3
+ *
4
+ * A pipeline-based analysis and transformation engine for Green Trees.
5
+ *
6
+ * @module
7
+ * @see Analysis/ARCHITECTURE.md (planned)
8
+ */
9
+ export type { Pass } from './Contracts/Pass';
10
+ export type { AnalyzerPass, DecisionPass, TransformPass } from './Contracts/Pass';
11
+ export type { TransformationPlan, TransformAction } from './Contracts/Pass';
12
+ export type { Contribution } from './Contracts/Contribution';
13
+ export type { SemanticContribution, DiagnosticContribution, OptimizationContribution, MetricsContribution, } from './Contracts/Contribution';
14
+ export { ContributionKind } from './Contracts/Contribution';
15
+ export type { AnalysisReport } from './Contracts/AnalysisReport';
16
+ export type { PipelineContext } from './Contracts/PipelineContext';
17
+ export { PipelineMode, ExportTarget } from './Contracts/PipelineContext';
18
+ export { Pipeline } from './Pipeline/Pipeline';
19
+ export type { PipelineResult } from './Pipeline/Pipeline';
20
+ export { PipelineBuilder } from './Pipeline/PipelineBuilder';
21
+ export { PipelineStage } from './Pipeline/PipelineStage';
22
+ export { CharacterCountAnalyzer } from './Passes/Utility/CharacterCountAnalyzer';
23
+ export { MergeableColorAnalyzer } from './Passes/Analysis/MergeableColorAnalyzer';
24
+ export { GradientAnalyzer, findCollapsibleGradients, formatGradientTag } from './Passes/Analysis/GradientAnalyzer';
25
+ export type { GradientModel, GradientDiagnostics, GradientStop, CollapsibleGradient } from './Passes/Analysis/GradientAnalyzer';
26
+ export { RainbowAnalyzer } from './Passes/Analysis/RainbowAnalyzer';
27
+ export type { RainbowModel, RainbowDiagnostics } from './Passes/Analysis/RainbowAnalyzer';
28
+ export { WaveAnalyzer } from './Passes/Analysis/WaveAnalyzer';
29
+ export type { WaveModel, WaveDiagnostics } from './Passes/Analysis/WaveAnalyzer';
30
+ export { SymbolAnalyzer } from './Passes/Analysis/SymbolAnalyzer';
31
+ export type { SymbolGlyph, SymbolRunModel } from './Passes/Analysis/SymbolAnalyzer';
32
+ export { ColorUsageAnalyzer } from './Passes/Analysis/ColorUsageAnalyzer';
33
+ export type { ColorUsageModel } from './Passes/Analysis/ColorUsageAnalyzer';
34
+ export { DefaultDecision } from './Passes/Decision/DefaultDecision';
35
+ export { PaletteRemapDecision } from './Passes/Decision/PaletteRemapDecision';
36
+ export type { Palette, PaletteRemapOptions, RemapAction } from './Passes/Decision/PaletteRemapDecision';
37
+ export { CollapseGradientTransform } from './Passes/Transform/CollapseGradientTransform';
38
+ export { RainbowCollapseTransform } from './Passes/Transform/RainbowCollapseTransform';
39
+ export { WaveCollapseTransform } from './Passes/Transform/WaveCollapseTransform';
40
+ export { MergeColorsTransform } from './Passes/Transform/MergeColorsTransform';