@crazyhappyone/auto-graph 0.2.2 → 0.2.3
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/cli/index.cjs.map +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +281 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -1
- package/dist/index.d.ts +85 -1
- package/dist/index.js +280 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -448,6 +448,19 @@ interface ConstraintSolverResult {
|
|
|
448
448
|
|
|
449
449
|
declare function applyLayoutConstraints(input: ConstraintSolverInput): ConstraintSolverResult;
|
|
450
450
|
|
|
451
|
+
interface QualityMetric {
|
|
452
|
+
readonly kind: QualityMetricKind;
|
|
453
|
+
readonly value: number;
|
|
454
|
+
readonly label: string;
|
|
455
|
+
}
|
|
456
|
+
type QualityMetricKind = "node-overlap" | "edge-crossing" | "bend-count" | "route-backtrack" | "label-collision";
|
|
457
|
+
interface QualityReport {
|
|
458
|
+
readonly metrics: QualityMetric[];
|
|
459
|
+
/** Aggregate score 0–100 (higher = better). */
|
|
460
|
+
readonly score: number;
|
|
461
|
+
readonly diagnostics: Diagnostic[];
|
|
462
|
+
}
|
|
463
|
+
|
|
451
464
|
type DiagramStage = "intent" | "normalized" | "coordinated";
|
|
452
465
|
type DiagramMetadata = JsonObject;
|
|
453
466
|
interface IntentDiagram {
|
|
@@ -499,6 +512,7 @@ interface CoordinatedDiagram {
|
|
|
499
512
|
bounds: Box;
|
|
500
513
|
frame?: CoordinatedFrame;
|
|
501
514
|
metadata?: DiagramMetadata;
|
|
515
|
+
qualityReport?: QualityReport;
|
|
502
516
|
}
|
|
503
517
|
|
|
504
518
|
type DslDiagnosticLayer = "parse" | "validate" | "solve" | "export" | "io";
|
|
@@ -740,6 +754,8 @@ interface SolveDiagramOptions {
|
|
|
740
754
|
initialLayout?: InitialLayoutMode;
|
|
741
755
|
routeKind?: RouteKind;
|
|
742
756
|
obstacleMargin?: number | Insets;
|
|
757
|
+
/** When true, compute quality score after solving (Issue #54, 方案 E). */
|
|
758
|
+
qualityScore?: boolean;
|
|
743
759
|
/** Extra horizontal/vertical clearance reserved around nodes for edge corridors. */
|
|
744
760
|
routingGutter?: number;
|
|
745
761
|
overlapSpacing?: number;
|
|
@@ -781,5 +797,73 @@ declare function solveDiagram(diagram: NormalizedDiagram, options?: SolveDiagram
|
|
|
781
797
|
* @see SolveDiagramOptions.prefitLabelSize
|
|
782
798
|
*/
|
|
783
799
|
declare function solveDiagramSafe(diagram: NormalizedDiagram, options?: SolveDiagramOptions): CoordinatedDiagram;
|
|
800
|
+
/**
|
|
801
|
+
* Build the default layout pipeline. Currently wraps `solveDiagram` in
|
|
802
|
+
* a single mega-phase so custom callers can replace individual phases
|
|
803
|
+
* (e.g. "initial-layout", "route-edges") without touching the rest.
|
|
804
|
+
*
|
|
805
|
+
* Individual phases will be extracted from the mega-phase in follow-up
|
|
806
|
+
* PRs for 方案 A (recursive layout) and 方案 B (corner-graph A*).
|
|
807
|
+
*/
|
|
808
|
+
declare function createDefaultPipeline(): LayoutPipeline;
|
|
809
|
+
|
|
810
|
+
/** Shared mutable state flowing through every pipeline phase. */
|
|
811
|
+
interface LayoutState {
|
|
812
|
+
diagram: NormalizedDiagram;
|
|
813
|
+
options: SolveDiagramOptions;
|
|
814
|
+
nodes: NormalizedNode[];
|
|
815
|
+
edges: NormalizedEdge[];
|
|
816
|
+
groups: NormalizedGroup[];
|
|
817
|
+
swimlanes: Swimlane[];
|
|
818
|
+
constraints: Constraint[];
|
|
819
|
+
boxes: Map<string, Box>;
|
|
820
|
+
locks: Map<string, LayoutLock>;
|
|
821
|
+
nodeGeometry: Map<string, ShapeGeometry>;
|
|
822
|
+
coordinatedNodes: CoordinatedNode[];
|
|
823
|
+
coordinatedEdges: CoordinatedEdge[];
|
|
824
|
+
coordinatedGroups: CoordinatedGroup[];
|
|
825
|
+
coordinatedMatrices: CoordinatedMatrixBlock[];
|
|
826
|
+
coordinatedTables: CoordinatedTableBlock[];
|
|
827
|
+
coordinatedEvidencePanels: CoordinatedEvidencePanel[];
|
|
828
|
+
frame?: CoordinatedFrame;
|
|
829
|
+
baseTextAnnotations: SolvedTextAnnotation[];
|
|
830
|
+
edgeTextAnnotations: SolvedTextAnnotation[];
|
|
831
|
+
contentBounds: Box;
|
|
832
|
+
bounds: Box;
|
|
833
|
+
degraded: boolean;
|
|
834
|
+
diagnostics: Diagnostic[];
|
|
835
|
+
qualityReport?: QualityReport;
|
|
836
|
+
phaseTrace: PhaseTraceEntry[];
|
|
837
|
+
}
|
|
838
|
+
interface PhaseTraceEntry {
|
|
839
|
+
phase: string;
|
|
840
|
+
durationMs: number;
|
|
841
|
+
diagnosticsAdded: number;
|
|
842
|
+
}
|
|
843
|
+
/** A single pipeline phase — mutates `state` in-place. */
|
|
844
|
+
interface LayoutPhase {
|
|
845
|
+
readonly name: string;
|
|
846
|
+
run(state: LayoutState): void;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Pluggable layout pipeline (Issue #54, 方案 D).
|
|
851
|
+
*
|
|
852
|
+
* Phases run sequentially, each mutating the shared LayoutState.
|
|
853
|
+
* Custom pipelines are built with the fluent builder API:
|
|
854
|
+
*
|
|
855
|
+
* new LayoutPipeline()
|
|
856
|
+
* .addPhase(myPhase)
|
|
857
|
+
* .addBefore("apply-constraints", prePhase)
|
|
858
|
+
* .run(diagram, options);
|
|
859
|
+
*/
|
|
860
|
+
declare class LayoutPipeline {
|
|
861
|
+
private phases;
|
|
862
|
+
addPhase(phase: LayoutPhase): this;
|
|
863
|
+
addBefore(refName: string, phase: LayoutPhase): this;
|
|
864
|
+
addAfter(refName: string, phase: LayoutPhase): this;
|
|
865
|
+
replacePhase(name: string, phase: LayoutPhase): this;
|
|
866
|
+
run(state: LayoutState): void;
|
|
867
|
+
}
|
|
784
868
|
|
|
785
|
-
export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type BoxSpatialIndex, type BoxSpatialIndexEntry, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutMode, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
|
|
869
|
+
export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type BoxSpatialIndex, type BoxSpatialIndexEntry, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutMode, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type LayoutPhase, LayoutPipeline, type LayoutState, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type PhaseTraceEntry, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultPipeline, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
|
package/dist/index.d.ts
CHANGED
|
@@ -448,6 +448,19 @@ interface ConstraintSolverResult {
|
|
|
448
448
|
|
|
449
449
|
declare function applyLayoutConstraints(input: ConstraintSolverInput): ConstraintSolverResult;
|
|
450
450
|
|
|
451
|
+
interface QualityMetric {
|
|
452
|
+
readonly kind: QualityMetricKind;
|
|
453
|
+
readonly value: number;
|
|
454
|
+
readonly label: string;
|
|
455
|
+
}
|
|
456
|
+
type QualityMetricKind = "node-overlap" | "edge-crossing" | "bend-count" | "route-backtrack" | "label-collision";
|
|
457
|
+
interface QualityReport {
|
|
458
|
+
readonly metrics: QualityMetric[];
|
|
459
|
+
/** Aggregate score 0–100 (higher = better). */
|
|
460
|
+
readonly score: number;
|
|
461
|
+
readonly diagnostics: Diagnostic[];
|
|
462
|
+
}
|
|
463
|
+
|
|
451
464
|
type DiagramStage = "intent" | "normalized" | "coordinated";
|
|
452
465
|
type DiagramMetadata = JsonObject;
|
|
453
466
|
interface IntentDiagram {
|
|
@@ -499,6 +512,7 @@ interface CoordinatedDiagram {
|
|
|
499
512
|
bounds: Box;
|
|
500
513
|
frame?: CoordinatedFrame;
|
|
501
514
|
metadata?: DiagramMetadata;
|
|
515
|
+
qualityReport?: QualityReport;
|
|
502
516
|
}
|
|
503
517
|
|
|
504
518
|
type DslDiagnosticLayer = "parse" | "validate" | "solve" | "export" | "io";
|
|
@@ -740,6 +754,8 @@ interface SolveDiagramOptions {
|
|
|
740
754
|
initialLayout?: InitialLayoutMode;
|
|
741
755
|
routeKind?: RouteKind;
|
|
742
756
|
obstacleMargin?: number | Insets;
|
|
757
|
+
/** When true, compute quality score after solving (Issue #54, 方案 E). */
|
|
758
|
+
qualityScore?: boolean;
|
|
743
759
|
/** Extra horizontal/vertical clearance reserved around nodes for edge corridors. */
|
|
744
760
|
routingGutter?: number;
|
|
745
761
|
overlapSpacing?: number;
|
|
@@ -781,5 +797,73 @@ declare function solveDiagram(diagram: NormalizedDiagram, options?: SolveDiagram
|
|
|
781
797
|
* @see SolveDiagramOptions.prefitLabelSize
|
|
782
798
|
*/
|
|
783
799
|
declare function solveDiagramSafe(diagram: NormalizedDiagram, options?: SolveDiagramOptions): CoordinatedDiagram;
|
|
800
|
+
/**
|
|
801
|
+
* Build the default layout pipeline. Currently wraps `solveDiagram` in
|
|
802
|
+
* a single mega-phase so custom callers can replace individual phases
|
|
803
|
+
* (e.g. "initial-layout", "route-edges") without touching the rest.
|
|
804
|
+
*
|
|
805
|
+
* Individual phases will be extracted from the mega-phase in follow-up
|
|
806
|
+
* PRs for 方案 A (recursive layout) and 方案 B (corner-graph A*).
|
|
807
|
+
*/
|
|
808
|
+
declare function createDefaultPipeline(): LayoutPipeline;
|
|
809
|
+
|
|
810
|
+
/** Shared mutable state flowing through every pipeline phase. */
|
|
811
|
+
interface LayoutState {
|
|
812
|
+
diagram: NormalizedDiagram;
|
|
813
|
+
options: SolveDiagramOptions;
|
|
814
|
+
nodes: NormalizedNode[];
|
|
815
|
+
edges: NormalizedEdge[];
|
|
816
|
+
groups: NormalizedGroup[];
|
|
817
|
+
swimlanes: Swimlane[];
|
|
818
|
+
constraints: Constraint[];
|
|
819
|
+
boxes: Map<string, Box>;
|
|
820
|
+
locks: Map<string, LayoutLock>;
|
|
821
|
+
nodeGeometry: Map<string, ShapeGeometry>;
|
|
822
|
+
coordinatedNodes: CoordinatedNode[];
|
|
823
|
+
coordinatedEdges: CoordinatedEdge[];
|
|
824
|
+
coordinatedGroups: CoordinatedGroup[];
|
|
825
|
+
coordinatedMatrices: CoordinatedMatrixBlock[];
|
|
826
|
+
coordinatedTables: CoordinatedTableBlock[];
|
|
827
|
+
coordinatedEvidencePanels: CoordinatedEvidencePanel[];
|
|
828
|
+
frame?: CoordinatedFrame;
|
|
829
|
+
baseTextAnnotations: SolvedTextAnnotation[];
|
|
830
|
+
edgeTextAnnotations: SolvedTextAnnotation[];
|
|
831
|
+
contentBounds: Box;
|
|
832
|
+
bounds: Box;
|
|
833
|
+
degraded: boolean;
|
|
834
|
+
diagnostics: Diagnostic[];
|
|
835
|
+
qualityReport?: QualityReport;
|
|
836
|
+
phaseTrace: PhaseTraceEntry[];
|
|
837
|
+
}
|
|
838
|
+
interface PhaseTraceEntry {
|
|
839
|
+
phase: string;
|
|
840
|
+
durationMs: number;
|
|
841
|
+
diagnosticsAdded: number;
|
|
842
|
+
}
|
|
843
|
+
/** A single pipeline phase — mutates `state` in-place. */
|
|
844
|
+
interface LayoutPhase {
|
|
845
|
+
readonly name: string;
|
|
846
|
+
run(state: LayoutState): void;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Pluggable layout pipeline (Issue #54, 方案 D).
|
|
851
|
+
*
|
|
852
|
+
* Phases run sequentially, each mutating the shared LayoutState.
|
|
853
|
+
* Custom pipelines are built with the fluent builder API:
|
|
854
|
+
*
|
|
855
|
+
* new LayoutPipeline()
|
|
856
|
+
* .addPhase(myPhase)
|
|
857
|
+
* .addBefore("apply-constraints", prePhase)
|
|
858
|
+
* .run(diagram, options);
|
|
859
|
+
*/
|
|
860
|
+
declare class LayoutPipeline {
|
|
861
|
+
private phases;
|
|
862
|
+
addPhase(phase: LayoutPhase): this;
|
|
863
|
+
addBefore(refName: string, phase: LayoutPhase): this;
|
|
864
|
+
addAfter(refName: string, phase: LayoutPhase): this;
|
|
865
|
+
replacePhase(name: string, phase: LayoutPhase): this;
|
|
866
|
+
run(state: LayoutState): void;
|
|
867
|
+
}
|
|
784
868
|
|
|
785
|
-
export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type BoxSpatialIndex, type BoxSpatialIndexEntry, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutMode, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
|
|
869
|
+
export { type AlignConstraint, type AlignmentAxis, type AnchorName, type AnchorPoint, type Arrowhead, type Box, type BoxSpatialIndex, type BoxSpatialIndexEntry, type CanonicalJson, type CanonicalizeOptions, type Constraint, type ConstraintBase, type ConstraintSolverInput, type ConstraintSolverResult, type ConstraintTarget, type ConstraintTargetKind, type ContainerGeometry, type ContainerGeometryInput, type ContainmentConstraint, type CoordinatedDiagram, type CoordinatedEdge, type CoordinatedEvidencePanel, type CoordinatedFrame, type CoordinatedGroup, type CoordinatedMatrixBlock, type CoordinatedNode, type CoordinatedPort, type CoordinatedTableBlock, DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, type DagreLayoutEdge, type DagreLayoutInput, type DagreLayoutNode, type DagreLayoutOptions, type DefaultTextMeasurerOptions, DeterministicTextMeasurer, type Diagnostic, type DiagnosticPathSegment, type DiagnosticSeverity, type DiagramDirection, type DiagramFrame, type DiagramMetadata, type DiagramStage, type DistributeConstraint, type DistributionAxis, type DslDiagnostic, type DslDiagnosticLayer, type DslOutputFormat, type EdgeArrowhead, type EdgeEndpoint, type EdgeStrokeStyle, type EvidenceCell, type EvidencePanel, type EvidencePanelItem, type EvidencePanelKind, type EvidenceTextLayout, type ExactPositionConstraint, type ExportFormat, type ExportOptions, type ExportResult, type InitialLayoutMode, type InitialLayoutResult, type Insets, type IntentDiagram, type IntentEdge, type IntentGroup, type IntentNode, type JsonObject, type JsonPrimitive, type JsonValue, type Label, type LabelFitOptions, LabelFitter, type LabelLayout, type LabelLineLayout, type LayoutLock, type LayoutLockSource, type LayoutPhase, LayoutPipeline, type LayoutState, type MatrixBlock, type NodeBase, type NodeCompartments, type NodePort, type NodeShape, type NormalizeDiagramDslOptions, type NormalizeDiagramDslResult, type NormalizedDiagram, type NormalizedEdge, type NormalizedGroup, type NormalizedNode, type ParseDiagramDslOptions, type ParseDiagramDslResult, type ParsedEdgeShorthand, type PhaseTraceEntry, type Point, type PortKind, type PortShiftingOptions, type PortSide, type PreparedText, PretextTextMeasurer, type RelativePositionConstraint, type RelativePositionRelation, type RenderDiagramDslOptions, type RenderDiagramDslResult, type RouteEdgeInput, type RouteEdgeResult, type RouteKind, type ShapeGeometry, type ShapeGeometryInput, type Size, type SolveDiagramOptions, type SolvedTextAnnotation, type Swimlane, type SwimlaneLane, type SwimlaneLayout, type SwimlaneOrientation, type TableBlock, type TableColumn, type TableRow, type TextCursor, type TextLayout, type TextLayoutLine, type TextMeasurementBackend, type TextMeasurer, type TextStyleOptions, type TextSurfaceKind, type VisualStyle, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultPipeline, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
|
package/dist/index.js
CHANGED
|
@@ -4051,6 +4051,45 @@ function indentLines(values) {
|
|
|
4051
4051
|
return values.map(indent);
|
|
4052
4052
|
}
|
|
4053
4053
|
|
|
4054
|
+
// src/solver/pipeline/pipeline.ts
|
|
4055
|
+
var LayoutPipeline = class {
|
|
4056
|
+
phases = [];
|
|
4057
|
+
addPhase(phase) {
|
|
4058
|
+
this.phases.push(phase);
|
|
4059
|
+
return this;
|
|
4060
|
+
}
|
|
4061
|
+
addBefore(refName, phase) {
|
|
4062
|
+
const idx = this.phases.findIndex((p) => p.name === refName);
|
|
4063
|
+
if (idx === -1) throw new Error(`Phase "${refName}" not found`);
|
|
4064
|
+
this.phases.splice(idx, 0, phase);
|
|
4065
|
+
return this;
|
|
4066
|
+
}
|
|
4067
|
+
addAfter(refName, phase) {
|
|
4068
|
+
const idx = this.phases.findIndex((p) => p.name === refName);
|
|
4069
|
+
if (idx === -1) throw new Error(`Phase "${refName}" not found`);
|
|
4070
|
+
this.phases.splice(idx + 1, 0, phase);
|
|
4071
|
+
return this;
|
|
4072
|
+
}
|
|
4073
|
+
replacePhase(name, phase) {
|
|
4074
|
+
const idx = this.phases.findIndex((p) => p.name === name);
|
|
4075
|
+
if (idx === -1) throw new Error(`Phase "${name}" not found`);
|
|
4076
|
+
this.phases[idx] = phase;
|
|
4077
|
+
return this;
|
|
4078
|
+
}
|
|
4079
|
+
run(state) {
|
|
4080
|
+
for (const phase of this.phases) {
|
|
4081
|
+
const before = state.diagnostics.length;
|
|
4082
|
+
const start = performance.now();
|
|
4083
|
+
phase.run(state);
|
|
4084
|
+
state.phaseTrace.push({
|
|
4085
|
+
phase: phase.name,
|
|
4086
|
+
durationMs: performance.now() - start,
|
|
4087
|
+
diagnosticsAdded: state.diagnostics.length - before
|
|
4088
|
+
});
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
};
|
|
4092
|
+
|
|
4054
4093
|
// src/ir/diagnostics.ts
|
|
4055
4094
|
var DELIVERABILITY_DIAGNOSTIC_CODES = /* @__PURE__ */ new Set([
|
|
4056
4095
|
"constraints.locked-target-not-moved",
|
|
@@ -5436,6 +5475,217 @@ function areCollinear2(a, b, c) {
|
|
|
5436
5475
|
return a.x === b.x && b.x === c.x || a.y === b.y && b.y === c.y;
|
|
5437
5476
|
}
|
|
5438
5477
|
|
|
5478
|
+
// src/solver/pipeline/quality.ts
|
|
5479
|
+
function scoreLayoutQuality(nodes, edges) {
|
|
5480
|
+
const diagnostics = [];
|
|
5481
|
+
const metrics = [];
|
|
5482
|
+
const overlapCount = countNodeOverlaps(nodes);
|
|
5483
|
+
const overlapScore = Math.max(0, 20 - overlapCount * 5);
|
|
5484
|
+
metrics.push({
|
|
5485
|
+
kind: "node-overlap",
|
|
5486
|
+
value: overlapCount,
|
|
5487
|
+
label: `${overlapCount} overlaps`
|
|
5488
|
+
});
|
|
5489
|
+
if (overlapCount > 0) {
|
|
5490
|
+
diagnostics.push({
|
|
5491
|
+
severity: "warning",
|
|
5492
|
+
code: "quality.node_overlap",
|
|
5493
|
+
message: `${overlapCount} node pair(s) overlap.`,
|
|
5494
|
+
detail: { overlapCount }
|
|
5495
|
+
});
|
|
5496
|
+
}
|
|
5497
|
+
const crossingCount = countEdgeCrossings(edges);
|
|
5498
|
+
const crossingScore = Math.max(0, 20 - crossingCount * 2);
|
|
5499
|
+
metrics.push({
|
|
5500
|
+
kind: "edge-crossing",
|
|
5501
|
+
value: crossingCount,
|
|
5502
|
+
label: `${crossingCount} crossings`
|
|
5503
|
+
});
|
|
5504
|
+
if (crossingCount > 0) {
|
|
5505
|
+
diagnostics.push({
|
|
5506
|
+
severity: "warning",
|
|
5507
|
+
code: "quality.edge_crossing",
|
|
5508
|
+
message: `${crossingCount} edge segment pair(s) cross.`,
|
|
5509
|
+
detail: { crossingCount }
|
|
5510
|
+
});
|
|
5511
|
+
}
|
|
5512
|
+
const totalBends = countTotalBends(edges);
|
|
5513
|
+
const bendScore = Math.max(0, 20 - totalBends * 0.5);
|
|
5514
|
+
metrics.push({
|
|
5515
|
+
kind: "bend-count",
|
|
5516
|
+
value: totalBends,
|
|
5517
|
+
label: `${totalBends} bends`
|
|
5518
|
+
});
|
|
5519
|
+
const backtrackCount = countBacktrackingEdges(edges);
|
|
5520
|
+
const backtrackScore = Math.max(0, 20 - backtrackCount * 5);
|
|
5521
|
+
metrics.push({
|
|
5522
|
+
kind: "route-backtrack",
|
|
5523
|
+
value: backtrackCount,
|
|
5524
|
+
label: `${backtrackCount} backtracking`
|
|
5525
|
+
});
|
|
5526
|
+
if (backtrackCount > 0) {
|
|
5527
|
+
diagnostics.push({
|
|
5528
|
+
severity: "warning",
|
|
5529
|
+
code: "quality.route_backtrack",
|
|
5530
|
+
message: `${backtrackCount} edge(s) are excessively long (>3\xD7 direct).`,
|
|
5531
|
+
detail: { backtrackCount }
|
|
5532
|
+
});
|
|
5533
|
+
}
|
|
5534
|
+
const labelCollisions = countLabelCollisions(nodes, edges);
|
|
5535
|
+
const labelScore = Math.max(0, 20 - labelCollisions * 3);
|
|
5536
|
+
metrics.push({
|
|
5537
|
+
kind: "label-collision",
|
|
5538
|
+
value: labelCollisions,
|
|
5539
|
+
label: `${labelCollisions} label collisions`
|
|
5540
|
+
});
|
|
5541
|
+
const score = Math.max(
|
|
5542
|
+
0,
|
|
5543
|
+
Math.min(
|
|
5544
|
+
100,
|
|
5545
|
+
overlapScore + crossingScore + bendScore + backtrackScore + labelScore
|
|
5546
|
+
)
|
|
5547
|
+
);
|
|
5548
|
+
return { metrics, score, diagnostics };
|
|
5549
|
+
}
|
|
5550
|
+
function countNodeOverlaps(nodes) {
|
|
5551
|
+
let count = 0;
|
|
5552
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
5553
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
5554
|
+
if (intersectsAabb(nodes[i].box, nodes[j].box)) {
|
|
5555
|
+
count++;
|
|
5556
|
+
}
|
|
5557
|
+
}
|
|
5558
|
+
}
|
|
5559
|
+
return count;
|
|
5560
|
+
}
|
|
5561
|
+
function countEdgeCrossings(edges) {
|
|
5562
|
+
let count = 0;
|
|
5563
|
+
for (let i = 0; i < edges.length; i++) {
|
|
5564
|
+
const aPts = edges[i].points;
|
|
5565
|
+
for (let j = i + 1; j < edges.length; j++) {
|
|
5566
|
+
const bPts = edges[j].points;
|
|
5567
|
+
for (let ai = 0; ai < aPts.length - 1; ai++) {
|
|
5568
|
+
for (let bi = 0; bi < bPts.length - 1; bi++) {
|
|
5569
|
+
if (segmentsIntersect(
|
|
5570
|
+
aPts[ai],
|
|
5571
|
+
aPts[ai + 1],
|
|
5572
|
+
bPts[bi],
|
|
5573
|
+
bPts[bi + 1]
|
|
5574
|
+
)) {
|
|
5575
|
+
count++;
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5580
|
+
}
|
|
5581
|
+
return count;
|
|
5582
|
+
}
|
|
5583
|
+
function segmentsIntersect(a, b, c, d) {
|
|
5584
|
+
const d1 = cross(c, d, a);
|
|
5585
|
+
const d2 = cross(c, d, b);
|
|
5586
|
+
const d3 = cross(a, b, c);
|
|
5587
|
+
const d4 = cross(a, b, d);
|
|
5588
|
+
return (d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) && (d3 > 0 && d4 < 0 || d3 < 0 && d4 > 0);
|
|
5589
|
+
}
|
|
5590
|
+
function cross(o, a, b) {
|
|
5591
|
+
return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
|
5592
|
+
}
|
|
5593
|
+
function countTotalBends(edges) {
|
|
5594
|
+
const sign = (n) => n > 0 ? 1 : n < 0 ? -1 : 0;
|
|
5595
|
+
let bends = 0;
|
|
5596
|
+
for (const e of edges) {
|
|
5597
|
+
if (e.points.length < 3) continue;
|
|
5598
|
+
for (let i = 1; i < e.points.length - 1; i++) {
|
|
5599
|
+
const prev = e.points[i - 1];
|
|
5600
|
+
const curr = e.points[i];
|
|
5601
|
+
const next = e.points[i + 1];
|
|
5602
|
+
const dx1 = curr.x - prev.x;
|
|
5603
|
+
const dy1 = curr.y - prev.y;
|
|
5604
|
+
const dx2 = next.x - curr.x;
|
|
5605
|
+
const dy2 = next.y - curr.y;
|
|
5606
|
+
if (sign(dx1) !== sign(dx2) || sign(dy1) !== sign(dy2)) {
|
|
5607
|
+
bends++;
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
return bends;
|
|
5612
|
+
}
|
|
5613
|
+
function countBacktrackingEdges(edges) {
|
|
5614
|
+
let count = 0;
|
|
5615
|
+
for (const e of edges) {
|
|
5616
|
+
if (e.points.length < 2) continue;
|
|
5617
|
+
const first = e.points[0];
|
|
5618
|
+
const last = e.points[e.points.length - 1];
|
|
5619
|
+
const direct = Math.hypot(last.x - first.x, last.y - first.y);
|
|
5620
|
+
if (direct <= 0) continue;
|
|
5621
|
+
let routeLen = 0;
|
|
5622
|
+
for (let i = 0; i < e.points.length - 1; i++) {
|
|
5623
|
+
routeLen += Math.hypot(
|
|
5624
|
+
e.points[i + 1].x - e.points[i].x,
|
|
5625
|
+
e.points[i + 1].y - e.points[i].y
|
|
5626
|
+
);
|
|
5627
|
+
}
|
|
5628
|
+
if (routeLen > direct * 3) count++;
|
|
5629
|
+
}
|
|
5630
|
+
return count;
|
|
5631
|
+
}
|
|
5632
|
+
function countLabelCollisions(nodes, edges) {
|
|
5633
|
+
let count = 0;
|
|
5634
|
+
const nodeBoxes = /* @__PURE__ */ new Map();
|
|
5635
|
+
for (const n of nodes) {
|
|
5636
|
+
nodeBoxes.set(n.id, n.box);
|
|
5637
|
+
if (n.label?.text !== void 0) {
|
|
5638
|
+
const lw = n.label.text.length * 8;
|
|
5639
|
+
const labelBox = {
|
|
5640
|
+
x: n.box.x + n.box.width / 2 - lw / 2,
|
|
5641
|
+
y: n.box.y - 8,
|
|
5642
|
+
width: lw,
|
|
5643
|
+
height: 14
|
|
5644
|
+
};
|
|
5645
|
+
for (const [id, box] of nodeBoxes) {
|
|
5646
|
+
if (id === n.id) continue;
|
|
5647
|
+
if (intersectsAabb(labelBox, box)) count++;
|
|
5648
|
+
}
|
|
5649
|
+
for (const e of edges) {
|
|
5650
|
+
for (let i = 0; i < e.points.length - 1; i++) {
|
|
5651
|
+
if (segmentIntersectsBox2(e.points[i], e.points[i + 1], labelBox)) {
|
|
5652
|
+
count++;
|
|
5653
|
+
break;
|
|
5654
|
+
}
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
return count;
|
|
5660
|
+
}
|
|
5661
|
+
function segmentIntersectsBox2(start, end, box) {
|
|
5662
|
+
const left = box.x;
|
|
5663
|
+
const right = box.x + box.width;
|
|
5664
|
+
const top = box.y;
|
|
5665
|
+
const bottom = box.y + box.height;
|
|
5666
|
+
if (start.x > left && start.x < right && start.y > top && start.y < bottom || end.x > left && end.x < right && end.y > top && end.y < bottom)
|
|
5667
|
+
return true;
|
|
5668
|
+
if (start.x === end.x) {
|
|
5669
|
+
return start.x > left && start.x < right && rangesOverlap3(start.y, end.y, top, bottom);
|
|
5670
|
+
}
|
|
5671
|
+
if (start.y === end.y) {
|
|
5672
|
+
return start.y > top && start.y < bottom && rangesOverlap3(start.x, end.x, left, right);
|
|
5673
|
+
}
|
|
5674
|
+
return edgeIntersect(start, end, left, top, right, top) || edgeIntersect(start, end, right, top, right, bottom) || edgeIntersect(start, end, right, bottom, left, bottom) || edgeIntersect(start, end, left, bottom, left, top);
|
|
5675
|
+
}
|
|
5676
|
+
function rangesOverlap3(a, b, min, max) {
|
|
5677
|
+
const lo = Math.min(a, b);
|
|
5678
|
+
const hi = Math.max(a, b);
|
|
5679
|
+
return hi > min && lo < max;
|
|
5680
|
+
}
|
|
5681
|
+
function edgeIntersect(start, end, x1, y1, x2, y2) {
|
|
5682
|
+
const denom = (end.x - start.x) * (y2 - y1) - (end.y - start.y) * (x2 - x1);
|
|
5683
|
+
if (denom === 0) return false;
|
|
5684
|
+
const t = ((start.x - x1) * (y2 - y1) - (start.y - y1) * (x2 - x1)) / denom;
|
|
5685
|
+
const u = ((start.x - x1) * (end.y - start.y) - (start.y - y1) * (end.x - start.x)) / denom;
|
|
5686
|
+
return t > 0 && t < 1 && u > 0 && u < 1;
|
|
5687
|
+
}
|
|
5688
|
+
|
|
5439
5689
|
// src/solver/solve.ts
|
|
5440
5690
|
var DEFAULT_MATRIX_CELL_SIZE2 = { width: 120, height: 36 };
|
|
5441
5691
|
var DEFAULT_TABLE_CELL_SIZE2 = { width: 128, height: 34 };
|
|
@@ -8123,13 +8373,13 @@ function routeIntersectsTextBox(points, box) {
|
|
|
8123
8373
|
if (start === void 0 || end === void 0) {
|
|
8124
8374
|
continue;
|
|
8125
8375
|
}
|
|
8126
|
-
if (
|
|
8376
|
+
if (segmentIntersectsBox3(start, end, box)) {
|
|
8127
8377
|
return true;
|
|
8128
8378
|
}
|
|
8129
8379
|
}
|
|
8130
8380
|
return false;
|
|
8131
8381
|
}
|
|
8132
|
-
function
|
|
8382
|
+
function segmentIntersectsBox3(start, end, box) {
|
|
8133
8383
|
const left = box.x;
|
|
8134
8384
|
const right = box.x + box.width;
|
|
8135
8385
|
const top = box.y;
|
|
@@ -8138,17 +8388,17 @@ function segmentIntersectsBox2(start, end, box) {
|
|
|
8138
8388
|
return true;
|
|
8139
8389
|
}
|
|
8140
8390
|
if (start.x === end.x) {
|
|
8141
|
-
return start.x > left && start.x < right &&
|
|
8391
|
+
return start.x > left && start.x < right && rangesOverlap4(start.y, end.y, top, bottom);
|
|
8142
8392
|
}
|
|
8143
8393
|
if (start.y === end.y) {
|
|
8144
|
-
return start.y > top && start.y < bottom &&
|
|
8394
|
+
return start.y > top && start.y < bottom && rangesOverlap4(start.x, end.x, left, right);
|
|
8145
8395
|
}
|
|
8146
8396
|
return segmentIntersectsBoxEdge2(start, end, left, top, right, top) || segmentIntersectsBoxEdge2(start, end, right, top, right, bottom) || segmentIntersectsBoxEdge2(start, end, right, bottom, left, bottom) || segmentIntersectsBoxEdge2(start, end, left, bottom, left, top);
|
|
8147
8397
|
}
|
|
8148
8398
|
function pointInsideBox2(point2, box) {
|
|
8149
8399
|
return point2.x > box.x && point2.x < box.x + box.width && point2.y > box.y && point2.y < box.y + box.height;
|
|
8150
8400
|
}
|
|
8151
|
-
function
|
|
8401
|
+
function rangesOverlap4(a, b, min, max) {
|
|
8152
8402
|
const low = Math.min(a, b);
|
|
8153
8403
|
const high = Math.max(a, b);
|
|
8154
8404
|
return high > min && low < max;
|
|
@@ -8511,6 +8761,30 @@ function groupReferenceMissing(groupId, referenceKind, id) {
|
|
|
8511
8761
|
detail: id === void 0 ? { groupId } : { groupId, id }
|
|
8512
8762
|
};
|
|
8513
8763
|
}
|
|
8764
|
+
function createDefaultPipeline() {
|
|
8765
|
+
return new LayoutPipeline().addPhase({
|
|
8766
|
+
name: "solve-diagram",
|
|
8767
|
+
run(state) {
|
|
8768
|
+
const result = solveDiagram(state.diagram, state.options);
|
|
8769
|
+
state.diagnostics.push(...result.diagnostics);
|
|
8770
|
+
state.bounds = result.bounds;
|
|
8771
|
+
state.degraded = result.degraded ?? false;
|
|
8772
|
+
state.coordinatedNodes = result.nodes;
|
|
8773
|
+
state.coordinatedEdges = result.edges;
|
|
8774
|
+
}
|
|
8775
|
+
}).addPhase({
|
|
8776
|
+
name: "quality-score",
|
|
8777
|
+
run(state) {
|
|
8778
|
+
if (!state.options.qualityScore) return;
|
|
8779
|
+
const report = scoreLayoutQuality(
|
|
8780
|
+
state.coordinatedNodes,
|
|
8781
|
+
state.coordinatedEdges
|
|
8782
|
+
);
|
|
8783
|
+
state.qualityReport = report;
|
|
8784
|
+
state.diagnostics.push(...report.diagnostics);
|
|
8785
|
+
}
|
|
8786
|
+
});
|
|
8787
|
+
}
|
|
8514
8788
|
|
|
8515
8789
|
// src/dsl/render.ts
|
|
8516
8790
|
function resolveOutputFormat(cliFormat, dslFormat) {
|
|
@@ -8748,6 +9022,6 @@ function isPointLikeRecord(value) {
|
|
|
8748
9022
|
return isPlainObject(value) && typeof value.x === "number" && typeof value.y === "number";
|
|
8749
9023
|
}
|
|
8750
9024
|
|
|
8751
|
-
export { DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, DeterministicTextMeasurer, LabelFitter, PretextTextMeasurer, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute2 as simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
|
|
9025
|
+
export { DEFAULT_CANONICAL_PRECISION, DEFAULT_DSL_MAX_BYTES, DELIVERABILITY_DIAGNOSTIC_CODES, DeterministicTextMeasurer, LabelFitter, LayoutPipeline, PretextTextMeasurer, applyLayoutConstraints, assertFiniteNonNegative, assertFinitePositive, boxCenter, canonicalize, computeArrowhead, computeContainerGeometry, computeShapeGeometry, createBoxSpatialIndex, createDefaultPipeline, createDefaultTextMeasurer, expandBox, expandBoxForQuery, exportExcalidraw, exportSvg, fitLabel, getEdgePort, installNodeCanvasRuntime, intersectsAabb, isPretextRuntimeAvailable, normalizeDiagramDsl, normalizeInsets, overlapArea, parseDiagramDsl, parseEdgeShorthand, queryBoxSpatialIndex, querySegmentSpatialIndex, renderDiagramDsl, resolveLineHeight, resolveOutputFormat, routeEdge, runComponentAwareDagreInitialLayout, runDagreInitialLayout, simplifyRoute2 as simplifyRoute, solveDiagram, solveDiagramSafe, sortDslDiagnostics, stringifyCanonical, toCanvasFont, unionBoxes, validateBox, validateTextStyle };
|
|
8752
9026
|
//# sourceMappingURL=index.js.map
|
|
8753
9027
|
//# sourceMappingURL=index.js.map
|