@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.
- package/dist/Visuals/lyne.css +117 -6
- package/dist/Visuals/osu.css +36 -5
- package/dist/index.js +9664 -3282
- package/dist/index.mjs +9535 -3283
- package/dist/types/Analysis/Contracts/AnalysisReport.d.ts +22 -0
- package/dist/types/Analysis/Contracts/Contribution.d.ts +68 -0
- package/dist/types/Analysis/Contracts/Pass.d.ts +59 -0
- package/dist/types/Analysis/Contracts/PipelineContext.d.ts +34 -0
- package/dist/types/Analysis/Passes/Analysis/ColorUsageAnalyzer.d.ts +56 -0
- package/dist/types/Analysis/Passes/Analysis/GradientAnalyzer.d.ts +111 -0
- package/dist/types/Analysis/Passes/Analysis/MergeableColorAnalyzer.d.ts +26 -0
- package/dist/types/Analysis/Passes/Analysis/RainbowAnalyzer.d.ts +47 -0
- package/dist/types/Analysis/Passes/Analysis/SymbolAnalyzer.d.ts +89 -0
- package/dist/types/Analysis/Passes/Analysis/WaveAnalyzer.d.ts +44 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Decision/DefaultDecision.d.ts +30 -0
- package/dist/types/Analysis/Passes/Decision/PaletteRemapDecision.d.ts +169 -0
- package/dist/types/Analysis/Passes/Decision/__tests__/DefaultDecision.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Transform/CollapseGradientTransform.d.ts +37 -0
- package/dist/types/Analysis/Passes/Transform/MergeColorsTransform.d.ts +28 -0
- package/dist/types/Analysis/Passes/Transform/RainbowCollapseTransform.d.ts +19 -0
- package/dist/types/Analysis/Passes/Transform/WaveCollapseTransform.d.ts +20 -0
- package/dist/types/Analysis/Passes/Utility/CharacterCountAnalyzer.d.ts +19 -0
- package/dist/types/Analysis/Pipeline/Pipeline.d.ts +69 -0
- package/dist/types/Analysis/Pipeline/PipelineBuilder.d.ts +31 -0
- package/dist/types/Analysis/Pipeline/PipelineStage.d.ts +17 -0
- package/dist/types/Analysis/Utils/color-utils.d.ts +60 -0
- package/dist/types/Analysis/__tests__/Integration.test.d.ts +8 -0
- package/dist/types/Analysis/__tests__/PaletteRemap.test.d.ts +14 -0
- package/dist/types/Analysis/__tests__/Pipeline.test.d.ts +10 -0
- package/dist/types/Analysis/__tests__/RoundTrip.test.d.ts +30 -0
- package/dist/types/Analysis/__tests__/SymbolAnalyzer.test.d.ts +11 -0
- package/dist/types/Analysis/index.d.ts +40 -0
- package/dist/types/BBCode/BBCodeDocumentModel.d.ts +92 -0
- package/dist/types/BBCode/BBCodeToGreenNode.d.ts +111 -0
- package/dist/types/BBCode/Parser.d.ts +78 -0
- package/dist/types/BBCode/index.d.ts +4 -0
- package/dist/types/Collab/positions.d.ts +55 -0
- package/dist/types/Commands/Command.d.ts +37 -0
- package/dist/types/Commands/CommandRegistry.d.ts +48 -0
- package/dist/types/Commands/DeleteNode.d.ts +7 -0
- package/dist/types/Commands/InsertText.d.ts +8 -0
- package/dist/types/Commands/SplitMerge.d.ts +9 -0
- package/dist/types/Commands/WrapInTag.d.ts +8 -0
- package/dist/types/Commands/index.d.ts +6 -0
- package/dist/types/Diff/TreeDiffer.d.ts +52 -0
- package/dist/types/Diff/__tests__/TreeDiffer.test.d.ts +1 -0
- package/dist/types/Diff/index.d.ts +2 -0
- package/dist/types/Edits/EditPlan.d.ts +144 -0
- package/dist/types/Edits/Optimizer.d.ts +78 -0
- package/dist/types/Edits/Rules/Rule.d.ts +91 -0
- package/dist/types/Edits/Rules/dropEmptyTags.d.ts +40 -0
- package/dist/types/Edits/Rules/dropRedundantNesting.d.ts +59 -0
- package/dist/types/Edits/Rules/index.d.ts +9 -0
- package/dist/types/Edits/Rules/mergeAdjacent.d.ts +93 -0
- package/dist/types/Edits/Rules/reorderWrappers.d.ts +42 -0
- package/dist/types/Edits/Rules/shortenHex.d.ts +30 -0
- package/dist/types/Edits/Rules/tagValue.d.ts +56 -0
- package/dist/types/Edits/Rules/unwrapInvisibleColor.d.ts +47 -0
- package/dist/types/Edits/applyEdits.d.ts +36 -0
- package/dist/types/Edits/index.d.ts +6 -0
- package/dist/types/Events/EventBus.d.ts +103 -0
- package/dist/types/Events/index.d.ts +2 -0
- package/dist/types/Formatter/Formatter.d.ts +32 -0
- package/dist/types/Formatter/index.d.ts +2 -0
- package/dist/types/HTML/HTMLDocumentModel.d.ts +13 -0
- package/dist/types/HTML/HTMLToGreenNode.d.ts +4 -0
- package/dist/types/Incremental/BracketIndex.d.ts +101 -0
- package/dist/types/Incremental/ChangeTracker.d.ts +69 -0
- package/dist/types/Incremental/IncrementalParser.d.ts +246 -0
- package/dist/types/Incremental/__tests__/BracketIndex.test.d.ts +1 -0
- package/dist/types/Incremental/__tests__/IncrementalParser.test.d.ts +1 -0
- package/dist/types/Incremental/index.d.ts +4 -0
- package/dist/types/Lexer/BBCodeLexer.d.ts +74 -0
- package/dist/types/Lexer/Lexer.d.ts +54 -0
- package/dist/types/Lexer/index.d.ts +4 -0
- package/dist/types/Linter/Linter.d.ts +58 -0
- package/dist/types/Linter/index.d.ts +2 -0
- package/dist/types/Markdown/MarkdownAST.d.ts +122 -0
- package/dist/types/Markdown/MarkdownDocumentModel.d.ts +15 -0
- package/dist/types/Markdown/MarkdownLexer.d.ts +155 -0
- package/dist/types/Markdown/MarkdownParser.d.ts +42 -0
- package/dist/types/Markdown/MarkdownToGreenNode.d.ts +6 -0
- package/dist/types/MilHibri/MilHibriDocumentModel.d.ts +21 -0
- package/dist/types/Model/DocumentModel.d.ts +318 -0
- package/dist/types/Model/NodeFactory.d.ts +29 -0
- package/dist/types/Model/TagRegistry.d.ts +165 -0
- package/dist/types/Model/index.d.ts +5 -0
- package/dist/types/Plugins/PluginAPI.d.ts +44 -0
- package/dist/types/Plugins/PluginRegistry.d.ts +81 -0
- package/dist/types/Plugins/index.d.ts +3 -0
- package/dist/types/Queries/QueryEngine.d.ts +32 -0
- package/dist/types/Queries/index.d.ts +1 -0
- package/dist/types/Reconciler/SurgicalReconciler.d.ts +23 -0
- package/dist/types/RenderPipeline/RenderPipeline.d.ts +46 -0
- package/dist/types/RenderPipeline/RenderTree.d.ts +55 -0
- package/dist/types/RenderPipeline/index.d.ts +4 -0
- package/dist/types/Repair/NestingRepair.d.ts +48 -0
- package/dist/types/Repair/index.d.ts +1 -0
- package/dist/types/Semantic/SemanticAnalyzer.d.ts +321 -0
- package/dist/types/Semantic/index.d.ts +2 -0
- package/dist/types/Symbols/SymbolTable.d.ts +47 -0
- package/dist/types/Symbols/index.d.ts +1 -0
- package/dist/types/Syntax/GreenNode.d.ts +154 -0
- package/dist/types/Syntax/GreenNodePool.d.ts +134 -0
- package/dist/types/Syntax/NodeMatcher.d.ts +75 -0
- package/dist/types/Syntax/RedNode.d.ts +280 -0
- package/dist/types/Syntax/RedNodeStore.d.ts +116 -0
- package/dist/types/Syntax/TreeBuilder.d.ts +54 -0
- package/dist/types/Syntax/__tests__/GreenNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNodeStore.test.d.ts +1 -0
- package/dist/types/Syntax/greenEdit.d.ts +64 -0
- package/dist/types/Syntax/hash.d.ts +17 -0
- package/dist/types/Syntax/index.d.ts +8 -0
- package/dist/types/Syntax/nodeAttr.d.ts +63 -0
- package/dist/types/Syntax/partition.d.ts +67 -0
- package/dist/types/Syntax/preserveNodeIds.d.ts +47 -0
- package/dist/types/Tokens/TokenResolver.d.ts +25 -0
- package/dist/types/Tokens/index.d.ts +1 -0
- package/dist/types/Transactions/Transaction.d.ts +36 -0
- package/dist/types/Transactions/UndoManager.d.ts +63 -0
- package/dist/types/Transactions/index.d.ts +3 -0
- package/dist/types/Transformers/ASTOptimizer.d.ts +34 -0
- package/dist/types/Transformers/GradientTransformer.d.ts +18 -0
- package/dist/types/Transformers/GrowTransformer.d.ts +16 -0
- package/dist/types/Transformers/RainbowTransformer.d.ts +17 -0
- package/dist/types/Transformers/SineWaveTransformer.d.ts +17 -0
- package/dist/types/Transformers/Transformer.d.ts +17 -0
- package/dist/types/Types/core.d.ts +104 -0
- package/dist/types/Types/diagnostics.d.ts +85 -0
- package/dist/types/Types/index.d.ts +11 -0
- package/dist/types/Types/operations.d.ts +109 -0
- package/dist/types/Types/queries.d.ts +67 -0
- package/dist/types/Types/symbols.d.ts +42 -0
- package/dist/types/Types/tokens.d.ts +75 -0
- package/dist/types/Utils/BBCodeGenerator.d.ts +21 -0
- package/dist/types/Utils/ColorMath.d.ts +92 -0
- package/dist/types/Utils/EffectMath.d.ts +643 -0
- package/dist/types/Utils/TagVocabulary.d.ts +104 -0
- package/dist/types/Utils/TagVocabulary.test.d.ts +1 -0
- package/dist/types/Utils/color.d.ts +29 -0
- package/dist/types/Utils/dom-to-svg.d.ts +28 -0
- package/dist/types/Utils/dom-to-svg.test.d.ts +1 -0
- package/dist/types/Utils/treeTransformers.d.ts +160 -0
- package/dist/types/Visitors/BBBlocksExporter.d.ts +27 -0
- package/dist/types/Visitors/BBCodeExporter.d.ts +90 -0
- package/dist/types/Visitors/BlockPatcher.d.ts +91 -0
- package/dist/types/Visitors/DOMMorpher.d.ts +13 -0
- package/dist/types/Visitors/HTMLRenderer.d.ts +380 -0
- package/dist/types/Visitors/JSONExporter.d.ts +42 -0
- package/dist/types/Visitors/MarkdownExporter.d.ts +28 -0
- package/dist/types/Visitors/SVGRenderer.d.ts +16 -0
- package/dist/types/Visitors/TiptapExporter.d.ts +40 -0
- package/dist/types/Visitors/Visitor.d.ts +35 -0
- package/dist/types/Visitors/index.d.ts +9 -0
- package/dist/types/Visuals/BoxDrawer.d.ts +49 -0
- package/dist/types/Visuals/index.d.ts +38 -0
- package/dist/types/index.d.ts +154 -0
- package/package.json +14 -10
- package/src/Analysis/Passes/Analysis/ColorUsageAnalyzer.ts +103 -0
- package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +294 -20
- package/src/Analysis/Passes/Analysis/SymbolAnalyzer.ts +257 -0
- package/src/Analysis/Passes/Decision/PaletteRemapDecision.ts +425 -0
- package/src/Analysis/Pipeline/Pipeline.ts +15 -2
- package/src/Analysis/index.ts +8 -2
- package/src/BBCode/BBCodeDocumentModel.ts +3 -0
- package/src/BBCode/BBCodeToGreenNode.ts +18 -12
- package/src/BBCode/Parser.ts +38 -1
- package/src/Edits/EditPlan.ts +290 -0
- package/src/Edits/Optimizer.ts +185 -0
- package/src/Edits/Rules/Rule.ts +145 -0
- package/src/Edits/Rules/dropEmptyTags.ts +110 -0
- package/src/Edits/Rules/dropRedundantNesting.ts +120 -0
- package/src/Edits/Rules/index.ts +28 -0
- package/src/Edits/Rules/mergeAdjacent.ts +224 -0
- package/src/Edits/Rules/reorderWrappers.ts +154 -0
- package/src/Edits/Rules/shortenHex.ts +79 -0
- package/src/Edits/Rules/tagValue.ts +105 -0
- package/src/Edits/Rules/unwrapInvisibleColor.ts +93 -0
- package/src/Edits/applyEdits.ts +54 -0
- package/src/Edits/index.ts +22 -0
- package/src/Events/EventBus.ts +18 -0
- package/src/HTML/HTMLToGreenNode.ts +185 -37
- package/src/Incremental/BracketIndex.ts +249 -0
- package/src/Incremental/IncrementalParser.ts +464 -41
- package/src/Lexer/BBCodeLexer.ts +25 -3
- package/src/Lexer/index.ts +1 -1
- package/src/Markdown/MarkdownAST.ts +65 -2
- package/src/Markdown/MarkdownLexer.ts +69 -14
- package/src/Markdown/MarkdownParser.ts +749 -62
- package/src/Markdown/MarkdownToGreenNode.ts +148 -27
- package/src/MilHibri/MilHibriDocumentModel.ts +56 -0
- package/src/Model/DocumentModel.ts +138 -5
- package/src/Model/TagRegistry.ts +129 -134
- package/src/Reconciler/SurgicalReconciler.ts +460 -0
- package/src/Repair/NestingRepair.ts +116 -0
- package/src/Repair/index.ts +1 -0
- package/src/Semantic/SemanticAnalyzer.ts +1802 -65
- package/src/Syntax/GreenNodePool.ts +12 -12
- package/src/Syntax/RedNode.ts +17 -3
- package/src/Syntax/RedNodeStore.ts +9 -1
- package/src/Syntax/nodeAttr.ts +172 -0
- package/src/Tokens/TokenResolver.ts +55 -0
- package/src/Tokens/index.ts +1 -0
- package/src/Types/core.ts +15 -0
- package/src/Utils/ColorMath.ts +276 -55
- package/src/Utils/EffectMath.ts +2462 -0
- package/src/Utils/TagVocabulary.ts +141 -0
- package/src/Utils/dom-to-svg.ts +28 -12
- package/src/Visitors/BBBlocksExporter.ts +15 -1
- package/src/Visitors/BBCodeExporter.ts +319 -32
- package/src/Visitors/BlockPatcher.ts +87 -11
- package/src/Visitors/DOMMorpher.ts +15 -5
- package/src/Visitors/HTMLRenderer.ts +374 -151
- package/src/Visitors/MarkdownExporter.ts +98 -41
- package/src/Visitors/TiptapExporter.ts +1 -0
- package/src/Visuals/index.ts +7 -4
- package/src/Visuals/lyne.css +117 -6
- package/src/Visuals/osu.css +36 -5
- package/src/index.ts +172 -5
- package/dist/index.d.mts +0 -4612
- package/dist/index.d.ts +0 -4612
- package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +0 -135
- package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +0 -84
- package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +0 -99
- package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +0 -119
- package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +0 -179
- package/src/Analysis/__tests__/Integration.test.ts +0 -162
- package/src/Analysis/__tests__/Pipeline.test.ts +0 -133
- package/src/Diff/__tests__/TreeDiffer.test.ts +0 -65
- package/src/Incremental/__tests__/IncrementalParser.test.ts +0 -164
- package/src/Syntax/__tests__/GreenNode.test.ts +0 -33
- package/src/Syntax/__tests__/RedNode.test.ts +0 -81
- package/src/Syntax/__tests__/RedNodeStore.test.ts +0 -104
- package/src/Tests/ASTOptimizerIdempotence.test.ts +0 -77
- package/src/Tests/BlockPatcher.test.ts +0 -437
- package/src/Tests/BlockPatcherWindowed.test.ts +0 -364
- package/src/Tests/BoxDrawer.test.ts +0 -217
- package/src/Tests/BoxRichTitle.test.ts +0 -105
- package/src/Tests/Chars500kBenchmark.test.ts +0 -151
- package/src/Tests/Chars500kEdits.test.ts +0 -321
- package/src/Tests/CollabPositions.test.ts +0 -146
- package/src/Tests/CompilerPathProfiling.test.ts +0 -186
- package/src/Tests/DOMMorpher.test.ts +0 -142
- package/src/Tests/DomPatchPerf.test.ts +0 -60
- package/src/Tests/EffectSegments.snapshot.json +0 -616
- package/src/Tests/EffectSegments.test.ts +0 -68
- package/src/Tests/FindNodeAtOffset.test.ts +0 -65
- package/src/Tests/Fuzzer.test.ts +0 -166
- package/src/Tests/GreenNodePool.test.ts +0 -153
- package/src/Tests/Lexer.test.ts +0 -238
- package/src/Tests/LyneMode.test.ts +0 -291
- package/src/Tests/ModelCoherence.test.ts +0 -180
- package/src/Tests/Partition.test.ts +0 -238
- package/src/Tests/PluginTags.test.ts +0 -150
- package/src/Tests/ProblematicSection.test.ts +0 -46
- package/src/Tests/ProblematicSectionHTML.test.ts +0 -58
- package/src/Tests/RedReuse.test.ts +0 -134
- package/src/Tests/ReproDelete20k.test.ts +0 -62
- package/src/Tests/SemanticValidators.test.ts +0 -136
- package/src/Tests/StableNodeIds.test.ts +0 -210
- package/src/Tests/StudioColorBloat.test.ts +0 -25
- package/src/Tests/StudioDebugText.test.ts +0 -27
- package/src/Tests/StudioTrailingChar.test.ts +0 -25
- package/src/Tests/StudioValidText.test.ts +0 -25
- package/src/Tests/UrlImgBug.test.ts +0 -23
- package/src/Tests/VisualBuilderFidelity.test.ts +0 -105
- package/src/Tests/referenceDocument.ts +0 -119
- package/src/Utils/dom-to-svg.test.ts +0 -86
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Analysis Report
|
|
3
|
+
*
|
|
4
|
+
* Once all AnalyzerPasses have run, their Contributions are collected
|
|
5
|
+
* into an immutable AnalysisReport. This report is the sole input to
|
|
6
|
+
* the DecisionPass(es).
|
|
7
|
+
*
|
|
8
|
+
* We deliberately keep the aggregator simple for now — just an array
|
|
9
|
+
* of contributions. As more pass types emerge we may introduce a
|
|
10
|
+
* structured Aggregator that indexes/categorises contributions.
|
|
11
|
+
*
|
|
12
|
+
* @see DecisionPass
|
|
13
|
+
*/
|
|
14
|
+
import type { Contribution } from './Contribution';
|
|
15
|
+
export interface AnalysisReport {
|
|
16
|
+
/** All contributions gathered from every AnalyzerPass. */
|
|
17
|
+
readonly contributions: readonly Contribution[];
|
|
18
|
+
/** Total number of analysis passes that ran. */
|
|
19
|
+
readonly passCount: number;
|
|
20
|
+
/** Wall-clock time spent in analysis (ms). */
|
|
21
|
+
readonly elapsedMs: number;
|
|
22
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Contribution Types
|
|
3
|
+
*
|
|
4
|
+
* Every AnalyzerPass produces an array of Contributions. A Contribution
|
|
5
|
+
* is a discriminated union so that downstream consumers (DecisionPass,
|
|
6
|
+
* AnalysisReport consumers, debug UI) can switch on `kind` and get
|
|
7
|
+
* perfect TypeScript narrowing.
|
|
8
|
+
*
|
|
9
|
+
* @see AnalysisReport
|
|
10
|
+
*/
|
|
11
|
+
export declare const ContributionKind: {
|
|
12
|
+
readonly Semantic: 'semantic';
|
|
13
|
+
readonly Diagnostic: 'diagnostic';
|
|
14
|
+
readonly Optimization: 'optimization';
|
|
15
|
+
readonly Metrics: 'metrics';
|
|
16
|
+
};
|
|
17
|
+
export type ContributionKind = (typeof ContributionKind)[keyof typeof ContributionKind];
|
|
18
|
+
/**
|
|
19
|
+
* A semantic pattern recognised in the tree (gradient, wave, rainbow,…).
|
|
20
|
+
* These describe *meaning* of the document, not just surface syntax.
|
|
21
|
+
*/
|
|
22
|
+
export interface SemanticContribution {
|
|
23
|
+
readonly kind: typeof ContributionKind.Semantic;
|
|
24
|
+
readonly label: string;
|
|
25
|
+
readonly confidence: number;
|
|
26
|
+
readonly range: {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
};
|
|
30
|
+
readonly metadata: Record<string, unknown>;
|
|
31
|
+
/** Human-readable description (optional). */
|
|
32
|
+
readonly description?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A diagnostic (warning, error, info) attached to a range in the tree.
|
|
36
|
+
*/
|
|
37
|
+
export interface DiagnosticContribution {
|
|
38
|
+
readonly kind: typeof ContributionKind.Diagnostic;
|
|
39
|
+
readonly severity: 'error' | 'warning' | 'info' | 'hint';
|
|
40
|
+
readonly message: string;
|
|
41
|
+
readonly range?: {
|
|
42
|
+
start: number;
|
|
43
|
+
end: number;
|
|
44
|
+
};
|
|
45
|
+
readonly code?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* An optimisation opportunity detected in the tree (mergeable colours,
|
|
49
|
+
* redundant wrapping, empty tags, …).
|
|
50
|
+
*/
|
|
51
|
+
export interface OptimizationContribution {
|
|
52
|
+
readonly kind: typeof ContributionKind.Optimization;
|
|
53
|
+
readonly label: string;
|
|
54
|
+
readonly description: string;
|
|
55
|
+
readonly estimatedImprovement?: string;
|
|
56
|
+
readonly range: {
|
|
57
|
+
start: number;
|
|
58
|
+
end: number;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Aggregate metrics about the tree (character count, node depth, …).
|
|
63
|
+
*/
|
|
64
|
+
export interface MetricsContribution {
|
|
65
|
+
readonly kind: typeof ContributionKind.Metrics;
|
|
66
|
+
readonly metrics: Record<string, number | string>;
|
|
67
|
+
}
|
|
68
|
+
export type Contribution = SemanticContribution | DiagnosticContribution | OptimizationContribution | MetricsContribution;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Pass Contracts
|
|
3
|
+
*
|
|
4
|
+
* Each pass in the analysis/transform pipeline implements one of these
|
|
5
|
+
* specialized interfaces. The three kinds mirror LLVM's pass structure:
|
|
6
|
+
*
|
|
7
|
+
* Analysis — observe the tree, produce Contributions (never mutate)
|
|
8
|
+
* Decision — consume an AnalysisReport, produce a TransformationPlan
|
|
9
|
+
* Transform — mutate the tree according to a plan
|
|
10
|
+
*
|
|
11
|
+
* @see ARCHITECTURE.md (Analysis Framework)
|
|
12
|
+
*/
|
|
13
|
+
import type { PipelineContext } from './PipelineContext';
|
|
14
|
+
import type { Contribution } from './Contribution';
|
|
15
|
+
import type { GreenNode } from '../../Syntax/GreenNode';
|
|
16
|
+
import type { AnalysisReport } from './AnalysisReport';
|
|
17
|
+
/** Every pass has an identity string and belongs to a stage. */
|
|
18
|
+
export interface Pass {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* An AnalyzerPass observes the Green Tree and produces one or more
|
|
23
|
+
* Contributions. It MUST NOT mutate the tree or the context.
|
|
24
|
+
*/
|
|
25
|
+
export interface AnalyzerPass extends Pass {
|
|
26
|
+
run(tree: GreenNode, context: PipelineContext): Contribution[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A DecisionPass consumes an AnalysisReport (which itself is the
|
|
30
|
+
* aggregated output of all AnalyzerPasses) and produces a
|
|
31
|
+
* TransformationPlan that describes *intended* tree mutations.
|
|
32
|
+
*/
|
|
33
|
+
export interface DecisionPass extends Pass {
|
|
34
|
+
run(report: AnalysisReport, context: PipelineContext): TransformationPlan;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A TransformPass receives the current Green Tree together with a
|
|
38
|
+
* TransformationPlan and returns a **new** Green Tree. It MUST NOT
|
|
39
|
+
* mutate the original tree — immutability guarantees deterministic
|
|
40
|
+
* replay and debugging.
|
|
41
|
+
*/
|
|
42
|
+
export interface TransformPass extends Pass {
|
|
43
|
+
run(tree: GreenNode, plan: TransformationPlan, context: PipelineContext): GreenNode;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A single action described by a TransformationPlan.
|
|
47
|
+
* `kind` tells the TransformPass what to do; `payload` carries
|
|
48
|
+
* per-kind parameters.
|
|
49
|
+
*/
|
|
50
|
+
export interface TransformAction {
|
|
51
|
+
readonly kind: string;
|
|
52
|
+
readonly payload: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Ordered set of actions that a DecisionPass produces.
|
|
56
|
+
*/
|
|
57
|
+
export interface TransformationPlan {
|
|
58
|
+
readonly actions: readonly TransformAction[];
|
|
59
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Pipeline Context
|
|
3
|
+
*
|
|
4
|
+
* PipelineContext is **read-only by contract**. It is built *before*
|
|
5
|
+
* the pipeline starts and MUST NOT be modified by any pass.
|
|
6
|
+
*
|
|
7
|
+
* If a pass needs to make information available to downstream passes it
|
|
8
|
+
* should emit a Contribution rather than mutating the context.
|
|
9
|
+
*
|
|
10
|
+
* @immutable
|
|
11
|
+
*/
|
|
12
|
+
export declare const PipelineMode: {
|
|
13
|
+
readonly Interactive: 'interactive';
|
|
14
|
+
readonly Batch: 'batch';
|
|
15
|
+
readonly Import: 'import';
|
|
16
|
+
};
|
|
17
|
+
export type PipelineMode = (typeof PipelineMode)[keyof typeof PipelineMode];
|
|
18
|
+
export declare const ExportTarget: {
|
|
19
|
+
readonly Osu: 'osu';
|
|
20
|
+
readonly Miliastry: 'miliastry';
|
|
21
|
+
readonly HTML: 'html';
|
|
22
|
+
readonly Markdown: 'markdown';
|
|
23
|
+
};
|
|
24
|
+
export type ExportTarget = (typeof ExportTarget)[keyof typeof ExportTarget];
|
|
25
|
+
export interface PipelineContext {
|
|
26
|
+
/** Where this pipeline run originates from. */
|
|
27
|
+
readonly mode: PipelineMode;
|
|
28
|
+
/** The format we intend to export to (influences decisions). */
|
|
29
|
+
readonly target: ExportTarget;
|
|
30
|
+
/** Feature flags that may enable/disable certain behaviours. */
|
|
31
|
+
readonly featureFlags: Readonly<Record<string, boolean>>;
|
|
32
|
+
/** Free-form metadata provided by the caller (e.g. selection range). */
|
|
33
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Color Usage Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Reports every `[color=#RRGGBB]` in the document, one contribution per tag.
|
|
5
|
+
*
|
|
6
|
+
* ## Why this exists alongside GradientAnalyzer
|
|
7
|
+
*
|
|
8
|
+
* `GradientAnalyzer` recognises that a run of colour tags forms a gradient and
|
|
9
|
+
* describes its *shape* — the stops, the easing, the span. What it does not
|
|
10
|
+
* describe is where each individual tag sits, because a gradient is modelled
|
|
11
|
+
* as one continuous ramp rather than as the tags that spell it out.
|
|
12
|
+
*
|
|
13
|
+
* A consumer that wants to recolour a document needs both: the shape, to know
|
|
14
|
+
* what the gradient is doing, and the tag positions, to know what to edit.
|
|
15
|
+
* This pass supplies the second half. A DecisionPass sees both contributions
|
|
16
|
+
* in the same report and can join them — which is exactly how the framework is
|
|
17
|
+
* meant to compose, since analyzer passes cannot observe each other.
|
|
18
|
+
*
|
|
19
|
+
* ## What gets reported
|
|
20
|
+
*
|
|
21
|
+
* Every colour tag, gradient member or not. Deciding which ones are
|
|
22
|
+
* interesting is a decision, and decisions belong in the decision stage.
|
|
23
|
+
*
|
|
24
|
+
* Only full six-digit hex is recognised, because that is what `extractHex`
|
|
25
|
+
* accepts. `[color=red]` and `[color=#F00]` are parsed as colours by the
|
|
26
|
+
* engine but are invisible here — a deliberate limit, since rewriting them
|
|
27
|
+
* would mean choosing a canonical spelling the author did not use.
|
|
28
|
+
*
|
|
29
|
+
* @see SemanticContribution
|
|
30
|
+
* @see GradientAnalyzer
|
|
31
|
+
*/
|
|
32
|
+
import type { AnalyzerPass } from '../../Contracts/Pass';
|
|
33
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
34
|
+
import type { Contribution } from '../../Contracts/Contribution';
|
|
35
|
+
import type { GreenNode } from '../../../Syntax/GreenNode';
|
|
36
|
+
export interface ColorUsageModel {
|
|
37
|
+
/** Normalised to uppercase `#RRGGBB` by `extractHex`. */
|
|
38
|
+
readonly hex: string;
|
|
39
|
+
/**
|
|
40
|
+
* Source offsets of the opening delimiter alone — `[color=#D194B3]`.
|
|
41
|
+
*
|
|
42
|
+
* Recolouring replaces this span rather than the attribute inside it. The
|
|
43
|
+
* attribute's own position would have to be derived from the delimiter's
|
|
44
|
+
* width and the hex's length, which breaks the moment the author writes
|
|
45
|
+
* `[color = #D194B3]`; the delimiter's bounds are read straight off the
|
|
46
|
+
* node. The cost is that a rewritten tag comes back in canonical spelling,
|
|
47
|
+
* which is acceptable for a tag being edited anyway.
|
|
48
|
+
*/
|
|
49
|
+
readonly openStart: number;
|
|
50
|
+
readonly openEnd: number;
|
|
51
|
+
}
|
|
52
|
+
export declare class ColorUsageAnalyzer implements AnalyzerPass {
|
|
53
|
+
readonly id = "color-usage";
|
|
54
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[];
|
|
55
|
+
private walk;
|
|
56
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Gradient Analyzer (v2)
|
|
3
|
+
*
|
|
4
|
+
* Detects sequences of [color=#HEX] tags that form a gradient pattern
|
|
5
|
+
* and reports them as SemanticContributions with a confidence score.
|
|
6
|
+
*
|
|
7
|
+
* ## Refinements over v1
|
|
8
|
+
*
|
|
9
|
+
* 1. **OKLab color space** — Uses OKLab (Bottosson 2020) for perceptual
|
|
10
|
+
* colour distance instead of RGB. Two colours with small OKLab distance
|
|
11
|
+
* look nearly identical to the human eye, making gradient detection
|
|
12
|
+
* much more accurate.
|
|
13
|
+
*
|
|
14
|
+
* 2. **Change-point detection** — Identifies gradient *stops* even when
|
|
15
|
+
* plateaus (runs of identical colour) exist, so a sequence like
|
|
16
|
+
* RRRR→G→BBBB is correctly parsed as a 3-stop gradient rather than
|
|
17
|
+
* a failed linear interpolation.
|
|
18
|
+
*
|
|
19
|
+
* 3. **Sharper sigmoid (k=6)** — Better separation between "likely
|
|
20
|
+
* gradient" and "maybe gradient" at the decision thresholds.
|
|
21
|
+
*
|
|
22
|
+
* ## Confidence features (weights sum to 1.0)
|
|
23
|
+
*
|
|
24
|
+
* - uniformPerceptualSpacing (+0.30)
|
|
25
|
+
* - contiguousWrappers (+0.25)
|
|
26
|
+
* - noFormattingBreaks (+0.15)
|
|
27
|
+
* - monotonicProgression (+0.20)
|
|
28
|
+
* - lowPerceptualError (+0.10)
|
|
29
|
+
*
|
|
30
|
+
* @see SemanticContribution
|
|
31
|
+
*/
|
|
32
|
+
import type { AnalyzerPass } from '../../Contracts/Pass';
|
|
33
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
34
|
+
import type { Contribution } from '../../Contracts/Contribution';
|
|
35
|
+
import type { GreenNode } from '../../../Syntax/GreenNode';
|
|
36
|
+
export interface GradientModel {
|
|
37
|
+
readonly colors: string[];
|
|
38
|
+
readonly easing: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
|
|
39
|
+
readonly stops: GradientStop[];
|
|
40
|
+
readonly rangeStart: number;
|
|
41
|
+
readonly rangeEnd: number;
|
|
42
|
+
readonly charCount: number;
|
|
43
|
+
readonly diagnostics: GradientDiagnostics;
|
|
44
|
+
}
|
|
45
|
+
export interface GradientStop {
|
|
46
|
+
/** Hex colour at this stop */
|
|
47
|
+
readonly color: string;
|
|
48
|
+
/** Normalised position 0-1 */
|
|
49
|
+
readonly position: number;
|
|
50
|
+
}
|
|
51
|
+
export interface GradientDiagnostics {
|
|
52
|
+
readonly uniformSpacing: boolean;
|
|
53
|
+
readonly monotonic: boolean;
|
|
54
|
+
readonly plateauCount: number;
|
|
55
|
+
readonly maxPerceptualError: number;
|
|
56
|
+
readonly stopCount: number;
|
|
57
|
+
readonly featureScores: Readonly<Record<string, number>>;
|
|
58
|
+
}
|
|
59
|
+
export interface CollapsibleGradient {
|
|
60
|
+
readonly range: {
|
|
61
|
+
start: number;
|
|
62
|
+
end: number;
|
|
63
|
+
};
|
|
64
|
+
readonly colors: string[];
|
|
65
|
+
readonly stops: GradientStop[];
|
|
66
|
+
readonly easing: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
|
|
67
|
+
readonly combinedText: string;
|
|
68
|
+
readonly replacementText: string;
|
|
69
|
+
readonly confidence: number;
|
|
70
|
+
readonly colorCount: number;
|
|
71
|
+
}
|
|
72
|
+
export declare function formatGradientTag(stops: GradientStop[], colors: string[], easing: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut', text: string): string;
|
|
73
|
+
export declare class GradientAnalyzer implements AnalyzerPass {
|
|
74
|
+
readonly id = "gradient-analyzer";
|
|
75
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[];
|
|
76
|
+
findCollapsibleGradients(tree: GreenNode, minConfidence?: number): CollapsibleGradient[];
|
|
77
|
+
private collectCollapsibleGradients;
|
|
78
|
+
/**
|
|
79
|
+
* The collapsible runs among the DIRECT children of `node`, and nothing
|
|
80
|
+
* below them.
|
|
81
|
+
*
|
|
82
|
+
* A run is a property of one children list: which siblings are `color`,
|
|
83
|
+
* what sits between them, what each one wraps. That is what makes it the
|
|
84
|
+
* unit the incremental analysis can work with — an edit rebuilds the child
|
|
85
|
+
* lists on the path down to it and nothing else, so only those lists can
|
|
86
|
+
* have gained or lost a run (see `SemanticAnalyzer.analyzeWindow`). The
|
|
87
|
+
* full scan above is this, applied to every node in pre-order; running it
|
|
88
|
+
* per list keeps the two paths producing the same items in the same order.
|
|
89
|
+
*
|
|
90
|
+
* Returns the number of runs appended to `sink`. `nodeStart` is the absolute
|
|
91
|
+
* offset of `node`, so the ranges come out in document coordinates.
|
|
92
|
+
*/
|
|
93
|
+
collapsibleGradientsAt(node: GreenNode, nodeStart: number, sink: CollapsibleGradient[], minConfidence?: number): number;
|
|
94
|
+
private findGradients;
|
|
95
|
+
/**
|
|
96
|
+
* Detect gradient stops from a sequence of hex colours, handling plateaus.
|
|
97
|
+
*
|
|
98
|
+
* Algorithm: Scan for "significant changes" in perceptual distance.
|
|
99
|
+
* Wherever the cumulative perceptual distance from the last stop exceeds a
|
|
100
|
+
* threshold, a new stop is recorded. This naturally skips over plateaus.
|
|
101
|
+
*/
|
|
102
|
+
private detectStops;
|
|
103
|
+
private buildDiagnostics;
|
|
104
|
+
private calculateRawScore;
|
|
105
|
+
}
|
|
106
|
+
export declare function findCollapsibleGradients(tree: GreenNode, minConfidence?: number): CollapsibleGradient[];
|
|
107
|
+
/**
|
|
108
|
+
* The collapsible runs among the direct children of `node`, whose absolute
|
|
109
|
+
* start is `nodeStart`. See {@link GradientAnalyzer.collapsibleGradientsAt}.
|
|
110
|
+
*/
|
|
111
|
+
export declare function collapsibleGradientsAt(node: GreenNode, nodeStart: number, sink: CollapsibleGradient[], minConfidence?: number): number;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Mergeable Color Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Detects sequences of consecutive [color=#HEX] wrappers where ALL
|
|
5
|
+
* adjacent colours are identical. These are optimisation opportunities:
|
|
6
|
+
* the user could merge them into a single `[color]` tag.
|
|
7
|
+
*
|
|
8
|
+
* Example:
|
|
9
|
+
* [color=#FF0000]H[/color][color=#FF0000]e[/color] → mergeable
|
|
10
|
+
* [color=#FF0000]H[/color][color=#EE1100]e[/color] → NOT mergeable
|
|
11
|
+
*
|
|
12
|
+
* @see OptimizationContribution
|
|
13
|
+
*/
|
|
14
|
+
import type { AnalyzerPass } from '../../Contracts/Pass';
|
|
15
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
16
|
+
import type { Contribution } from '../../Contracts/Contribution';
|
|
17
|
+
import type { GreenNode } from '../../../Syntax/GreenNode';
|
|
18
|
+
export declare class MergeableColorAnalyzer implements AnalyzerPass {
|
|
19
|
+
readonly id = "mergeable-color";
|
|
20
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[];
|
|
21
|
+
/**
|
|
22
|
+
* Walk the tree and find consecutive color nodes with identical colours.
|
|
23
|
+
*/
|
|
24
|
+
private findMergeableColorSequences;
|
|
25
|
+
private emitMergeable;
|
|
26
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Rainbow Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Detects sequences of [color=#HEX] tags where the HSL hue rotates
|
|
5
|
+
* continuously while saturation and lightness remain approximately
|
|
6
|
+
* constant — the classic "rainbow" pattern.
|
|
7
|
+
*
|
|
8
|
+
* ## Confidence features
|
|
9
|
+
*
|
|
10
|
+
* - hueRotation (+0.35) — hue changes monotonically (increasing or decreasing)
|
|
11
|
+
* - stableSaturation (+0.20) — saturation stays within a narrow band
|
|
12
|
+
* - stableLightness (+0.20) — lightness stays within a narrow band
|
|
13
|
+
* - contiguousWrappers (+0.15) — no gaps in the colour sequence
|
|
14
|
+
* - noFormattingBreaks (+0.10) — no formatting tags between colours
|
|
15
|
+
*
|
|
16
|
+
* @see SemanticContribution
|
|
17
|
+
*/
|
|
18
|
+
import type { AnalyzerPass } from '../../Contracts/Pass';
|
|
19
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
20
|
+
import type { Contribution } from '../../Contracts/Contribution';
|
|
21
|
+
import type { GreenNode } from '../../../Syntax/GreenNode';
|
|
22
|
+
export interface RainbowModel {
|
|
23
|
+
readonly colors: string[];
|
|
24
|
+
readonly hueStart: number;
|
|
25
|
+
readonly hueEnd: number;
|
|
26
|
+
readonly avgSaturation: number;
|
|
27
|
+
readonly avgLightness: number;
|
|
28
|
+
readonly rangeStart: number;
|
|
29
|
+
readonly rangeEnd: number;
|
|
30
|
+
readonly charCount: number;
|
|
31
|
+
readonly diagnostics: RainbowDiagnostics;
|
|
32
|
+
}
|
|
33
|
+
export interface RainbowDiagnostics {
|
|
34
|
+
readonly hueDelta: number;
|
|
35
|
+
readonly saturationDeviation: number;
|
|
36
|
+
readonly lightnessDeviation: number;
|
|
37
|
+
readonly isContinuous: boolean;
|
|
38
|
+
readonly featureScores: Readonly<Record<string, number>>;
|
|
39
|
+
}
|
|
40
|
+
export declare class RainbowAnalyzer implements AnalyzerPass {
|
|
41
|
+
readonly id = "rainbow-analyzer";
|
|
42
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[];
|
|
43
|
+
private findRainbows;
|
|
44
|
+
private extractHSL;
|
|
45
|
+
private analyzeRainbow;
|
|
46
|
+
private calculateRawScore;
|
|
47
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Symbol Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Detects decorative Unicode glyphs — `✧ ⚔ ☽ ━ ◈` — in document text and
|
|
5
|
+
* reports them as SemanticContributions.
|
|
6
|
+
*
|
|
7
|
+
* The colour analyzers recognise structure that BBCode itself encodes: a
|
|
8
|
+
* gradient is a *sequence of tags*, so the tree already separates it from the
|
|
9
|
+
* prose around it. Symbols have no such marker. They are ordinary characters
|
|
10
|
+
* inside ordinary text nodes, indistinguishable at the syntax level from the
|
|
11
|
+
* words beside them. Recognising them therefore has to happen at the character
|
|
12
|
+
* level, against the Unicode blocks they come from.
|
|
13
|
+
*
|
|
14
|
+
* ## Runs, not characters
|
|
15
|
+
*
|
|
16
|
+
* Symbols are reported as contiguous *runs*, because the two ways a document
|
|
17
|
+
* uses them need different treatment:
|
|
18
|
+
*
|
|
19
|
+
* `✧ airi ✧` two one-glyph runs — ornaments framing a word
|
|
20
|
+
* `✧⋆⋅⋆⋅⋆✧` one seven-glyph run — a divider line
|
|
21
|
+
*
|
|
22
|
+
* Swapping the first means substituting glyph for glyph. Swapping the second
|
|
23
|
+
* means replacing the whole line with a different divider. A run of
|
|
24
|
+
* `MIN_SEPARATOR_LENGTH` or more is labelled `Separator`; anything shorter is
|
|
25
|
+
* labelled `Symbol`. Both carry per-glyph offsets in their metadata, so a
|
|
26
|
+
* consumer can address either the run or its individual characters.
|
|
27
|
+
*
|
|
28
|
+
* ## Confidence
|
|
29
|
+
*
|
|
30
|
+
* Detection is exact — a code point is either in a decorative block or it is
|
|
31
|
+
* not. Confidence answers the question that actually matters: is this glyph
|
|
32
|
+
* *ornamental*, or does it carry meaning? A dingbat is almost always
|
|
33
|
+
* decoration; `≈` in a sentence is probably arithmetic, and re-theming it
|
|
34
|
+
* would corrupt the text.
|
|
35
|
+
*
|
|
36
|
+
* Each block carries a base confidence, a run takes the *lowest* of its
|
|
37
|
+
* members — a run is only as safely ornamental as its least ornamental glyph —
|
|
38
|
+
* and separator-length runs receive a bonus, because a seven-character line of
|
|
39
|
+
* symbols is decoration regardless of which blocks it draws from.
|
|
40
|
+
*
|
|
41
|
+
* @see SemanticContribution
|
|
42
|
+
*/
|
|
43
|
+
import type { AnalyzerPass } from '../../Contracts/Pass';
|
|
44
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
45
|
+
import type { Contribution } from '../../Contracts/Contribution';
|
|
46
|
+
import type { GreenNode } from '../../../Syntax/GreenNode';
|
|
47
|
+
export interface SymbolGlyph {
|
|
48
|
+
readonly char: string;
|
|
49
|
+
readonly codePoint: number;
|
|
50
|
+
/** Unicode block name this glyph was matched in. */
|
|
51
|
+
readonly block: string;
|
|
52
|
+
/** Absolute source offsets, UTF-16 code units — `source.slice(start, end)`. */
|
|
53
|
+
readonly start: number;
|
|
54
|
+
readonly end: number;
|
|
55
|
+
}
|
|
56
|
+
export interface SymbolRunModel {
|
|
57
|
+
/** The run exactly as it appears in the source. */
|
|
58
|
+
readonly text: string;
|
|
59
|
+
readonly glyphs: readonly SymbolGlyph[];
|
|
60
|
+
/** Distinct block names present, in first-seen order. */
|
|
61
|
+
readonly blocks: readonly string[];
|
|
62
|
+
/** Length in glyphs — not in UTF-16 units, which astral symbols inflate. */
|
|
63
|
+
readonly length: number;
|
|
64
|
+
/** Whether the run was long enough to read as a divider. */
|
|
65
|
+
readonly isSeparator: boolean;
|
|
66
|
+
}
|
|
67
|
+
export declare class SymbolAnalyzer implements AnalyzerPass {
|
|
68
|
+
readonly id = "symbol";
|
|
69
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[];
|
|
70
|
+
/**
|
|
71
|
+
* Descend the tree, accumulating absolute offsets.
|
|
72
|
+
*
|
|
73
|
+
* Green nodes carry widths rather than positions (see `GreenNode.ts`), so
|
|
74
|
+
* the offsets a Contribution reports are built on the way down. Only `text`
|
|
75
|
+
* leaves are scanned: an element node's own `text` holds its attributes
|
|
76
|
+
* (`=#D194B3`), which are syntax, not content.
|
|
77
|
+
*/
|
|
78
|
+
private walk;
|
|
79
|
+
/**
|
|
80
|
+
* Find runs of decorative glyphs in one text leaf.
|
|
81
|
+
*
|
|
82
|
+
* Iterates by code point, not by index: an astral symbol such as `🌸`
|
|
83
|
+
* occupies two UTF-16 units, and stepping one unit at a time would split it
|
|
84
|
+
* into unpaired surrogates that match no block. The offsets recorded stay in
|
|
85
|
+
* UTF-16 units so they address the source directly.
|
|
86
|
+
*/
|
|
87
|
+
private scanText;
|
|
88
|
+
private toContribution;
|
|
89
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Wave (Size Oscillation) Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Detects sequences of [size=N] tags where the sizes follow a sinusoidal
|
|
5
|
+
* (or other periodic) oscillation pattern — the classic "wave/grow" effect.
|
|
6
|
+
*
|
|
7
|
+
* ## Confidence features
|
|
8
|
+
*
|
|
9
|
+
* - periodicPattern (+0.35) — sizes follow a clear periodic pattern
|
|
10
|
+
* - boundedRange (+0.20) — sizes stay within a plausible min-max range
|
|
11
|
+
* - smoothTransitions (+0.20) — adjacent size differences are small
|
|
12
|
+
* - contiguousWrappers (+0.15) — no gaps in the size sequence
|
|
13
|
+
* - noFormattingBreaks (+0.10) — no formatting tags between size nodes
|
|
14
|
+
*
|
|
15
|
+
* @see SemanticContribution
|
|
16
|
+
*/
|
|
17
|
+
import type { AnalyzerPass } from '../../Contracts/Pass';
|
|
18
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
19
|
+
import type { Contribution } from '../../Contracts/Contribution';
|
|
20
|
+
import type { GreenNode } from '../../../Syntax/GreenNode';
|
|
21
|
+
export interface WaveModel {
|
|
22
|
+
readonly sizes: number[];
|
|
23
|
+
readonly minSize: number;
|
|
24
|
+
readonly maxSize: number;
|
|
25
|
+
readonly estimatedFrequency: number;
|
|
26
|
+
readonly rangeStart: number;
|
|
27
|
+
readonly rangeEnd: number;
|
|
28
|
+
readonly charCount: number;
|
|
29
|
+
readonly diagnostics: WaveDiagnostics;
|
|
30
|
+
}
|
|
31
|
+
export interface WaveDiagnostics {
|
|
32
|
+
readonly periodicityScore: number;
|
|
33
|
+
readonly hasSymmetry: boolean;
|
|
34
|
+
readonly isBounded: boolean;
|
|
35
|
+
readonly transitionSmoothness: number;
|
|
36
|
+
readonly featureScores: Readonly<Record<string, number>>;
|
|
37
|
+
}
|
|
38
|
+
export declare class WaveAnalyzer implements AnalyzerPass {
|
|
39
|
+
readonly id = "wave-analyzer";
|
|
40
|
+
run(tree: GreenNode, _context: PipelineContext): Contribution[];
|
|
41
|
+
private findWaves;
|
|
42
|
+
private analyzeWave;
|
|
43
|
+
private calculateRawScore;
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quasar Analysis Framework — Default Decision
|
|
3
|
+
*
|
|
4
|
+
* Consumes an AnalysisReport and produces a TransformationPlan.
|
|
5
|
+
* The decision logic depends on the PipelineContext:
|
|
6
|
+
*
|
|
7
|
+
* - target === 'miliastry':
|
|
8
|
+
* Aggressively collapses detected gradients (confidence ≥ 0.6).
|
|
9
|
+
* - target === 'osu':
|
|
10
|
+
* Only collapses very high-confidence gradients (confidence ≥ 0.95).
|
|
11
|
+
* - mode === 'batch' || mode === 'import':
|
|
12
|
+
* Uses the OSU threshold by default.
|
|
13
|
+
*
|
|
14
|
+
* Optimisation opportunities (mergeable colours) are always included
|
|
15
|
+
* regardless of target, but only when the count exceeds 1.
|
|
16
|
+
*
|
|
17
|
+
* @see DecisionPass
|
|
18
|
+
* @see TransformationPlan
|
|
19
|
+
*/
|
|
20
|
+
import type { DecisionPass, TransformationPlan } from '../../Contracts/Pass';
|
|
21
|
+
import type { AnalysisReport } from '../../Contracts/AnalysisReport';
|
|
22
|
+
import type { PipelineContext } from '../../Contracts/PipelineContext';
|
|
23
|
+
export declare class DefaultDecision implements DecisionPass {
|
|
24
|
+
readonly id = "default-decision";
|
|
25
|
+
run(report: AnalysisReport, context: PipelineContext): TransformationPlan;
|
|
26
|
+
/** Map contribution label → transform action kind */
|
|
27
|
+
private labelToActionKind;
|
|
28
|
+
private handleSemantic;
|
|
29
|
+
private handleOptimization;
|
|
30
|
+
}
|