diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go
index a3e0bf760..36d206e41 100644
--- a/d2graph/d2graph.go
+++ b/d2graph/d2graph.go
@@ -1925,7 +1925,7 @@ func (g *Graph) PrintString() string {
buf := &bytes.Buffer{}
fmt.Fprint(buf, "Objects: [")
for _, obj := range g.Objects {
- fmt.Fprintf(buf, "%#v @(%v)", obj.AbsID(), obj.TopLeft.ToString())
+ fmt.Fprintf(buf, "%v, ", obj.AbsID())
}
fmt.Fprint(buf, "]")
return buf.String()
diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go
index 9e9109453..853a691e7 100644
--- a/d2layouts/d2grid/layout.go
+++ b/d2layouts/d2grid/layout.go
@@ -47,6 +47,164 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d
}
}
+func Layout2(ctx context.Context, g *d2graph.Graph) error {
+
+ obj := g.Root
+
+ gd, err := layoutGrid(g, obj)
+ if err != nil {
+ return err
+ }
+ // obj.Children = make(map[string]*d2graph.Object)
+ // obj.ChildrenArray = nil
+
+ if obj.Box != nil {
+ // CONTAINER_PADDING is default, but use gap value if set
+ horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING
+ if obj.GridGap != nil || obj.HorizontalGap != nil {
+ horizontalPadding = gd.horizontalGap
+ }
+ if obj.GridGap != nil || obj.VerticalGap != nil {
+ verticalPadding = gd.verticalGap
+ }
+
+ // size shape according to grid
+ obj.SizeToContent(gd.width, gd.height, float64(2*horizontalPadding), float64(2*verticalPadding))
+
+ // compute where the grid should be placed inside shape
+ s := obj.ToShape()
+ innerBox := s.GetInnerBox()
+ if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 {
+ gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y)
+ }
+
+ // compute how much space the label and icon occupy
+ var occupiedWidth, occupiedHeight float64
+ if obj.Icon != nil {
+ iconSpace := float64(d2target.MAX_ICON_SIZE + 2*label.PADDING)
+ occupiedWidth = iconSpace
+ occupiedHeight = iconSpace
+ }
+
+ var dx, dy float64
+ if obj.LabelDimensions.Height != 0 {
+ occupiedHeight = math.Max(
+ occupiedHeight,
+ float64(obj.LabelDimensions.Height)+2*label.PADDING,
+ )
+ }
+ if obj.LabelDimensions.Width != 0 {
+ // . ├────┤───────├────┤
+ // . icon label icon
+ // with an icon in top left we need 2x the space to fit the label in the center
+ occupiedWidth *= 2
+ occupiedWidth += float64(obj.LabelDimensions.Width) + 2*label.PADDING
+ if occupiedWidth > obj.Width {
+ dx = (occupiedWidth - obj.Width) / 2
+ obj.Width = occupiedWidth
+ }
+ }
+
+ // also check for grid cells with outside top labels or icons
+ // the first grid object is at the top (and always exists)
+ topY := gd.objects[0].TopLeft.Y
+ highestOutside := topY
+ for _, o := range gd.objects {
+ // we only want to compute label positions for objects at the top of the grid
+ if o.TopLeft.Y > topY {
+ if gd.rowDirected {
+ // if the grid is rowDirected (row1, row2, etc) we can stop after finishing the first row
+ break
+ } else {
+ // otherwise we continue until the next column
+ continue
+ }
+ }
+ if o.LabelPosition != nil {
+ labelPosition := label.Position(*o.LabelPosition)
+ if labelPosition.IsOutside() {
+ labelTL := o.GetLabelTopLeft()
+ if labelTL.Y < highestOutside {
+ highestOutside = labelTL.Y
+ }
+ }
+ }
+ if o.IconPosition != nil {
+ switch label.Position(*o.IconPosition) {
+ case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight:
+ iconSpace := float64(d2target.MAX_ICON_SIZE + label.PADDING)
+ if topY-iconSpace < highestOutside {
+ highestOutside = topY - iconSpace
+ }
+ }
+ }
+ }
+ if highestOutside < topY {
+ occupiedHeight += topY - highestOutside + 2*label.PADDING
+ }
+ if occupiedHeight > float64(verticalPadding) {
+ // if the label doesn't fit within the padding, we need to add more
+ dy = occupiedHeight - float64(verticalPadding)
+ obj.Height += dy
+ }
+
+ // we need to center children if we have to expand to fit the container label
+ if dx != 0 || dy != 0 {
+ gd.shift(dx, dy)
+ }
+ }
+
+ if obj.HasLabel() {
+ obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
+ }
+ if obj.Icon != nil {
+ obj.IconPosition = go2.Pointer(string(label.InsideTopLeft))
+ }
+
+ // simple straight line edge routing between grid objects
+ for _, e := range g.Edges {
+ // edgeOrder[e.AbsID()] = i
+ if !e.Src.Parent.IsDescendantOf(obj) && !e.Dst.Parent.IsDescendantOf(obj) {
+ continue
+ }
+ // if edge is within grid, remove it from outer layout
+ gd.edges = append(gd.edges, e)
+ // edgeToRemove[e] = struct{}{}
+
+ if e.Src.Parent != obj || e.Dst.Parent != obj {
+ continue
+ }
+ // if edge is grid child, use simple routing
+ e.Route = []*geo.Point{e.Src.Center(), e.Dst.Center()}
+ e.TraceToShape(e.Route, 0, 1)
+ if e.Label.Value != "" {
+ e.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
+ }
+ }
+
+ if g.Root.IsGridDiagram() && len(g.Root.ChildrenArray) != 0 {
+ g.Root.TopLeft = geo.NewPoint(0, 0)
+ }
+
+ obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
+
+ horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING
+ if obj.GridGap != nil || obj.HorizontalGap != nil {
+ horizontalPadding = gd.horizontalGap
+ }
+ if obj.GridGap != nil || obj.VerticalGap != nil {
+ verticalPadding = gd.verticalGap
+ }
+
+ // shift the grid from (0, 0)
+ gd.shift(
+ obj.TopLeft.X+float64(horizontalPadding),
+ obj.TopLeft.Y+float64(verticalPadding),
+ )
+ gd.cleanup(obj, g)
+ return nil
+}
+
func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder, edgeOrder map[string]int, err error) {
toRemove := make(map[*d2graph.Object]struct{})
edgeToRemove := make(map[*d2graph.Edge]struct{})
diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go
index dfd5703a6..a3001cf4f 100644
--- a/d2layouts/d2layouts.go
+++ b/d2layouts/d2layouts.go
@@ -5,11 +5,13 @@ import (
"math"
"strings"
+ "cdr.dev/slog"
"oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2layouts/d2grid"
"oss.terrastruct.com/d2/d2layouts/d2near"
"oss.terrastruct.com/d2/d2layouts/d2sequence"
"oss.terrastruct.com/d2/lib/geo"
+ "oss.terrastruct.com/d2/lib/log"
)
type DiagramType string
@@ -33,6 +35,7 @@ func (gi GraphInfo) isDefault() bool {
func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing {
+ log.Warn(ctx, "ln info", slog.F("gi", graphInfo))
// Before we can layout these nodes, we need to handle all nested diagrams first.
extracted := make(map[*d2graph.Object]*d2graph.Graph)
extractedInfo := make(map[*d2graph.Object]GraphInfo)
@@ -53,28 +56,39 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
for _, child := range queue {
if gi := NestedGraphInfo(child); !gi.isDefault() {
extractedInfo[child] = gi
+ // log.Warn(ctx, "nested", slog.F("child", child.AbsID()), slog.F("gi", gi))
- var nestedGraph *d2graph.Graph
- if gi.IsConstantNear {
- nestedGraph = ExtractSelf(child)
- } else {
- // There is a nested diagram here, so extract its contents and process in the same way
- nestedGraph = ExtractDescendants(child)
- }
+ // There is a nested diagram here, so extract its contents and process in the same way
+ nestedGraph := ExtractDescendants(child)
// Layout of nestedGraph is completed
+ // log.Error(ctx, "recurse", slog.F("child", child.AbsID()), slog.F("level", child.Level()))
spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout)
- if !gi.IsConstantNear {
- // Fit child to size of nested layout
- FitToGraph(child, nestedGraph, spacing)
+ log.Warn(ctx, "fitting child", slog.F("child", child.AbsID()))
+ // Fit child to size of nested layout
+ FitToGraph(child, nestedGraph, spacing)
+
+ var nearGraph *d2graph.Graph
+ if gi.IsConstantNear {
+ nearGraph = ExtractSelf(child)
+ child.TopLeft = geo.NewPoint(0, 0)
+ child.Width = nestedGraph.Root.Width
+ child.Width = nestedGraph.Root.Height
}
+ // if gi.IsConstantNear {
+ // // FitToGraph(child, nestedGraph, spacing)
+ // if nestedGraph.Root.Box != nil {
+ // child.Width = nestedGraph.Root.Width
+ // child.Height = nestedGraph.Root.Height
+ // }
+ // }
+
// We will restore the contents after running layout with child as the placeholder
if gi.IsConstantNear {
- constantNears = append(constantNears, nestedGraph)
- } else {
- extracted[child] = nestedGraph
+ constantNears = append(constantNears, nearGraph)
}
+ extracted[child] = nestedGraph
} else if len(child.Children) > 0 {
queue = append(queue, child.ChildrenArray...)
}
@@ -89,17 +103,21 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
switch graphInfo.DiagramType {
case GridDiagram:
- layoutWithGrids := d2grid.Layout(ctx, g, coreLayout)
- if err = layoutWithGrids(ctx, g); err != nil {
+ log.Warn(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString()))
+ // layoutWithGrids := d2grid.Layout2(ctx, g, coreLayout)
+ // layoutWithGrids(ctx, g)
+ if err = d2grid.Layout2(ctx, g); err != nil {
panic(err)
}
case SequenceDiagram:
+ log.Warn(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString()))
err = d2sequence.Layout2(ctx, g, coreLayout)
if err != nil {
panic(err)
}
default:
+ log.Warn(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString()))
err := coreLayout(ctx, g)
if err != nil {
panic(err)
@@ -109,14 +127,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
}
spacing := LayoutDiagram(ctx, g, graphInfo, coreLayout)
- // With the layout set, inject all the extracted graphs
- for n, nestedGraph := range extracted {
- if !extractedInfo[n].IsConstantNear {
- InjectNested(n, nestedGraph)
- PositionNested(n, nestedGraph)
- }
- }
-
// if there are
if len(constantNears) > 0 {
err := d2near.Layout(ctx, g, constantNears)
@@ -125,6 +135,15 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
}
}
+ // With the layout set, inject all the extracted graphs
+ for n, nestedGraph := range extracted {
+ // if !extractedInfo[n].IsConstantNear {
+ InjectNested(n, nestedGraph)
+ PositionNested(n, nestedGraph)
+ // }
+ }
+
+ log.Warn(ctx, "done", slog.F("rootlevel", g.RootLevel))
return spacing
}
@@ -152,6 +171,7 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) {
func ExtractSelf(container *d2graph.Object) *d2graph.Graph {
nestedGraph := d2graph.NewGraph()
nestedGraph.RootLevel = int(container.Level()) - 1
+ // nestedGraph.Root.Box = &geo.Box{}
// separate out nested edges
g := container.Graph
@@ -255,13 +275,16 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) {
g.Objects = append(g.Objects, nestedGraph.Objects...)
g.Edges = append(g.Edges, nestedGraph.Edges...)
+ if g.Root.LabelPosition != nil {
+ container.LabelPosition = g.Root.LabelPosition
+ }
}
func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) {
- tl, _ := boundingBox(nestedGraph)
+ // _, _ := boundingBox(nestedGraph)
// Note: assumes nestedGraph's layout has contents positioned relative to 0,0
- dx := container.TopLeft.X - tl.X
- dy := container.TopLeft.Y - tl.Y
+ dx := container.TopLeft.X //- tl.X
+ dy := container.TopLeft.Y //- tl.Y
for _, o := range nestedGraph.Objects {
o.TopLeft.X += dx
o.TopLeft.Y += dy
@@ -279,6 +302,9 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) {
br = geo.NewPoint(math.Inf(-1), math.Inf(-1))
for _, obj := range g.Objects {
+ if obj.TopLeft == nil {
+ panic(obj.AbsID())
+ }
tl.X = math.Min(tl.X, obj.TopLeft.X)
tl.Y = math.Min(tl.Y, obj.TopLeft.Y)
br.X = math.Max(br.X, obj.TopLeft.X+obj.Width)
@@ -289,9 +315,17 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) {
}
func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding geo.Spacing) {
- tl, br := boundingBox(nestedGraph)
- container.Width = padding.Left + br.X - tl.X + padding.Right
- container.Height = padding.Top + br.Y - tl.Y + padding.Bottom
+ var width, height float64
+ // if nestedGraph.Root.Box != nil {
+ width = nestedGraph.Root.Width
+ height = nestedGraph.Root.Height
+ if width == 0 || height == 0 {
+ tl, br := boundingBox(nestedGraph)
+ width = br.X - tl.X
+ height = br.Y - tl.Y
+ }
+ container.Width = padding.Left + width + padding.Right
+ container.Height = padding.Top + height + padding.Bottom
}
// func LayoutDiagram(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing {
diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2
index 2bb6aaafd..701a8ff53 100644
--- a/e2etests/testdata/files/nested_diagram_types.d2
+++ b/e2etests/testdata/files/nested_diagram_types.d2
@@ -22,12 +22,12 @@ b: {
1 -> 2
# TODO This should work
- # near: bottom-left
+ near: bottom-right
#
2: {
# TODO compile error grid on sequence actor
- grid-rows: 3
+ # grid-rows: 3
x
y
z
@@ -36,7 +36,7 @@ b: {
1: {
x: {
# TODO compile error grid in sequence (anywhere)
- grid-rows: 3
+ # grid-rows: 3
u
v
w
diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json
index f4fa59d99..678409ed9 100644
--- a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json
+++ b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json
@@ -10,8 +10,8 @@
"x": 0,
"y": 0
},
- "width": 274,
- "height": 1394,
+ "width": 699,
+ "height": 393,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
@@ -40,7 +40,7 @@
"underline": false,
"labelWidth": 13,
"labelHeight": 36,
- "labelPosition": "INSIDE_TOP_CENTER",
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
@@ -48,8 +48,8 @@
"id": "c",
"type": "rectangle",
"pos": {
- "x": 334,
- "y": 664
+ "x": 759,
+ "y": 164
},
"width": 53,
"height": 66,
@@ -89,11 +89,11 @@
"id": "b.1",
"type": "rectangle",
"pos": {
- "x": 12,
- "y": 88
+ "x": 0,
+ "y": 0
},
- "width": 100,
- "height": 66,
+ "width": 617,
+ "height": 187,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -122,7 +122,7 @@
"underline": false,
"labelWidth": 7,
"labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
@@ -130,10 +130,10 @@
"id": "b.2",
"type": "rectangle",
"pos": {
- "x": 162,
- "y": 88
+ "x": 422,
+ "y": 327
},
- "width": 100,
+ "width": 277,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@@ -168,19 +168,19 @@
"level": 2
},
{
- "id": "b.2.x",
- "type": "page",
+ "id": "b.1.x",
+ "type": "rectangle",
"pos": {
- "x": 186,
- "y": 294
+ "x": 30,
+ "y": 31
},
- "width": 52,
- "height": 66,
+ "width": 342,
+ "height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "N7",
+ "fill": "B4",
"stroke": "B1",
"shadow": false,
"3d": false,
@@ -204,138 +204,16 @@
"underline": false,
"labelWidth": 7,
"labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
- "level": 3
- },
- {
- "id": "b.2.y",
- "type": "page",
- "pos": {
- "x": 185,
- "y": 430
- },
- "width": 53,
- "height": 66,
- "opacity": 1,
- "strokeDash": 0,
- "strokeWidth": 2,
- "borderRadius": 0,
- "fill": "N7",
- "stroke": "B1",
- "shadow": false,
- "3d": false,
- "multiple": false,
- "double-border": false,
- "tooltip": "",
- "link": "",
- "icon": null,
- "iconPosition": "",
- "blend": false,
- "fields": null,
- "methods": null,
- "columns": null,
- "label": "y",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N1",
- "italic": false,
- "bold": false,
- "underline": false,
- "labelWidth": 8,
- "labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
- "level": 3
- },
- {
- "id": "b.2.z",
- "type": "page",
- "pos": {
- "x": 186,
- "y": 566
- },
- "width": 52,
- "height": 66,
- "opacity": 1,
- "strokeDash": 0,
- "strokeWidth": 2,
- "borderRadius": 0,
- "fill": "N7",
- "stroke": "B1",
- "shadow": false,
- "3d": false,
- "multiple": false,
- "double-border": false,
- "tooltip": "",
- "link": "",
- "icon": null,
- "iconPosition": "",
- "blend": false,
- "fields": null,
- "methods": null,
- "columns": null,
- "label": "z",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N1",
- "italic": false,
- "bold": false,
- "underline": false,
- "labelWidth": 7,
- "labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
- "level": 3
- },
- {
- "id": "b.1.x",
- "type": "rectangle",
- "pos": {
- "x": 56,
- "y": 692
- },
- "width": 12,
- "height": 358,
- "opacity": 1,
- "strokeDash": 0,
- "strokeWidth": 2,
- "borderRadius": 0,
- "fill": "B4",
- "stroke": "B1",
- "shadow": false,
- "3d": false,
- "multiple": false,
- "double-border": false,
- "tooltip": "",
- "link": "",
- "icon": null,
- "iconPosition": "",
- "blend": false,
- "fields": null,
- "methods": null,
- "columns": null,
- "label": "",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N1",
- "italic": false,
- "bold": false,
- "underline": false,
- "labelWidth": 7,
- "labelHeight": 21,
- "zIndex": 2,
+ "labelPosition": "OUTSIDE_TOP_CENTER",
+ "zIndex": 0,
"level": 3
},
{
"id": "b.1.x.u",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 36,
- "y": 702
+ "x": 60,
+ "y": 61
},
"width": 52,
"height": 66,
@@ -368,15 +246,15 @@
"labelWidth": 7,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 4
},
{
"id": "b.1.x.v",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 35,
- "y": 838
+ "x": 172,
+ "y": 61
},
"width": 53,
"height": 66,
@@ -409,15 +287,15 @@
"labelWidth": 8,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 4
},
{
"id": "b.1.x.w",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 33,
- "y": 974
+ "x": 285,
+ "y": 61
},
"width": 57,
"height": 66,
@@ -450,15 +328,15 @@
"labelWidth": 12,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 4
},
{
"id": "b.1.y",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 35,
- "y": 1110
+ "x": 534,
+ "y": 61
},
"width": 53,
"height": 66,
@@ -491,15 +369,15 @@
"labelWidth": 8,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 3
},
{
"id": "b.1.z",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 36,
- "y": 1246
+ "x": 422,
+ "y": 61
},
"width": 52,
"height": 66,
@@ -532,18 +410,141 @@
"labelWidth": 7,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "b.2.x",
+ "type": "rectangle",
+ "pos": {
+ "x": 422,
+ "y": 327
+ },
+ "width": 52,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "x",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 7,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "b.2.y",
+ "type": "rectangle",
+ "pos": {
+ "x": 534,
+ "y": 327
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "y",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "b.2.z",
+ "type": "rectangle",
+ "pos": {
+ "x": 647,
+ "y": 327
+ },
+ "width": 52,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "z",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 7,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
"level": 3
},
{
"id": "a",
"type": "rectangle",
"pos": {
- "x": 407,
- "y": -478
+ "x": 832,
+ "y": -444
},
- "width": 345,
- "height": 458,
+ "width": 285,
+ "height": 398,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -580,10 +581,10 @@
"id": "a.1",
"type": "rectangle",
"pos": {
- "x": 467,
- "y": -418
+ "x": 892,
+ "y": -384
},
- "width": 225,
+ "width": 165,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@@ -621,10 +622,10 @@
"id": "a.2",
"type": "rectangle",
"pos": {
- "x": 467,
- "y": -312
+ "x": 892,
+ "y": -278
},
- "width": 225,
+ "width": 165,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@@ -662,11 +663,11 @@
"id": "a.3",
"type": "sequence_diagram",
"pos": {
- "x": 467,
- "y": -206
+ "x": 892,
+ "y": -172
},
- "width": 225,
- "height": 126,
+ "width": 165,
+ "height": 66,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
@@ -695,7 +696,7 @@
"underline": false,
"labelWidth": 11,
"labelHeight": 31,
- "labelPosition": "OUTSIDE_TOP_CENTER",
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
@@ -703,8 +704,8 @@
"id": "a.3.x",
"type": "rectangle",
"pos": {
- "x": 497,
- "y": -176
+ "x": 892,
+ "y": -172
},
"width": 52,
"height": 66,
@@ -744,8 +745,8 @@
"id": "a.3.y",
"type": "rectangle",
"pos": {
- "x": 609,
- "y": -176
+ "x": 1004,
+ "y": -172
},
"width": 53,
"height": 66,
@@ -808,94 +809,27 @@
"labelPercentage": 0,
"route": [
{
- "x": 62,
- "y": 224
+ "x": 560.5,
+ "y": 187
},
{
- "x": 212,
- "y": 224
+ "x": 560.5,
+ "y": 259
+ },
+ {
+ "x": 560.5,
+ "y": 287
+ },
+ {
+ "x": 560.5,
+ "y": 327
}
],
+ "isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 4
- },
- {
- "id": "(b.1 -- )[0]",
- "src": "b.1",
- "srcArrow": "none",
- "dst": "1-lifeline-end-1719232319",
- "dstArrow": "none",
- "opacity": 1,
- "strokeDash": 6,
- "strokeWidth": 2,
- "stroke": "B2",
- "borderRadius": 10,
- "label": "",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N2",
- "italic": true,
- "bold": false,
- "underline": false,
- "labelWidth": 0,
- "labelHeight": 0,
- "labelPosition": "",
- "labelPercentage": 0,
- "route": [
- {
- "x": 62,
- "y": 154
- },
- {
- "x": 62,
- "y": 1382
- }
- ],
- "animated": false,
- "tooltip": "",
- "icon": null,
- "zIndex": 1
- },
- {
- "id": "(b.2 -- )[0]",
- "src": "b.2",
- "srcArrow": "none",
- "dst": "2-lifeline-end-1739547740",
- "dstArrow": "none",
- "opacity": 1,
- "strokeDash": 6,
- "strokeWidth": 2,
- "stroke": "B2",
- "borderRadius": 10,
- "label": "",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N2",
- "italic": true,
- "bold": false,
- "underline": false,
- "labelWidth": 0,
- "labelHeight": 0,
- "labelPosition": "",
- "labelPercentage": 0,
- "route": [
- {
- "x": 212,
- "y": 154
- },
- {
- "x": 212,
- "y": 1382
- }
- ],
- "animated": false,
- "tooltip": "",
- "icon": null,
- "zIndex": 1
+ "zIndex": 0
}
],
"root": {
diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg
index 9c4b87f3c..10abb5e04 100644
--- a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg
+++ b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg
@@ -1,16 +1,16 @@
-
\ No newline at end of file
diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json
index 3ca671d1c..8f5124b95 100644
--- a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json
+++ b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json
@@ -10,8 +10,8 @@
"x": 12,
"y": 12
},
- "width": 274,
- "height": 1394,
+ "width": 547,
+ "height": 402,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
@@ -40,7 +40,7 @@
"underline": false,
"labelWidth": 13,
"labelHeight": 36,
- "labelPosition": "INSIDE_TOP_CENTER",
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 1
},
@@ -48,8 +48,8 @@
"id": "c",
"type": "rectangle",
"pos": {
- "x": 306,
- "y": 676
+ "x": 579,
+ "y": 180
},
"width": 53,
"height": 66,
@@ -89,11 +89,11 @@
"id": "b.1",
"type": "rectangle",
"pos": {
- "x": 24,
- "y": 100
+ "x": 12,
+ "y": 12
},
- "width": 100,
- "height": 66,
+ "width": 547,
+ "height": 266,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -122,7 +122,7 @@
"underline": false,
"labelWidth": 7,
"labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
@@ -130,10 +130,10 @@
"id": "b.2",
"type": "rectangle",
"pos": {
- "x": 174,
- "y": 100
+ "x": 187,
+ "y": 348
},
- "width": 100,
+ "width": 197,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@@ -168,19 +168,19 @@
"level": 2
},
{
- "id": "b.2.x",
- "type": "page",
+ "id": "b.1.x",
+ "type": "rectangle",
"pos": {
- "x": 198,
- "y": 306
+ "x": 62,
+ "y": 62
},
- "width": 52,
- "height": 66,
+ "width": 302,
+ "height": 166,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
- "fill": "N7",
+ "fill": "B4",
"stroke": "B1",
"shadow": false,
"3d": false,
@@ -204,138 +204,16 @@
"underline": false,
"labelWidth": 7,
"labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
- "level": 3
- },
- {
- "id": "b.2.y",
- "type": "page",
- "pos": {
- "x": 197,
- "y": 442
- },
- "width": 53,
- "height": 66,
- "opacity": 1,
- "strokeDash": 0,
- "strokeWidth": 2,
- "borderRadius": 0,
- "fill": "N7",
- "stroke": "B1",
- "shadow": false,
- "3d": false,
- "multiple": false,
- "double-border": false,
- "tooltip": "",
- "link": "",
- "icon": null,
- "iconPosition": "",
- "blend": false,
- "fields": null,
- "methods": null,
- "columns": null,
- "label": "y",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N1",
- "italic": false,
- "bold": false,
- "underline": false,
- "labelWidth": 8,
- "labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
- "level": 3
- },
- {
- "id": "b.2.z",
- "type": "page",
- "pos": {
- "x": 198,
- "y": 578
- },
- "width": 52,
- "height": 66,
- "opacity": 1,
- "strokeDash": 0,
- "strokeWidth": 2,
- "borderRadius": 0,
- "fill": "N7",
- "stroke": "B1",
- "shadow": false,
- "3d": false,
- "multiple": false,
- "double-border": false,
- "tooltip": "",
- "link": "",
- "icon": null,
- "iconPosition": "",
- "blend": false,
- "fields": null,
- "methods": null,
- "columns": null,
- "label": "z",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N1",
- "italic": false,
- "bold": false,
- "underline": false,
- "labelWidth": 7,
- "labelHeight": 21,
- "labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
- "level": 3
- },
- {
- "id": "b.1.x",
- "type": "rectangle",
- "pos": {
- "x": 68,
- "y": 704
- },
- "width": 12,
- "height": 358,
- "opacity": 1,
- "strokeDash": 0,
- "strokeWidth": 2,
- "borderRadius": 0,
- "fill": "B4",
- "stroke": "B1",
- "shadow": false,
- "3d": false,
- "multiple": false,
- "double-border": false,
- "tooltip": "",
- "link": "",
- "icon": null,
- "iconPosition": "",
- "blend": false,
- "fields": null,
- "methods": null,
- "columns": null,
- "label": "",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N1",
- "italic": false,
- "bold": false,
- "underline": false,
- "labelWidth": 7,
- "labelHeight": 21,
- "zIndex": 2,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
"level": 3
},
{
"id": "b.1.x.u",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 48,
- "y": 714
+ "x": 112,
+ "y": 112
},
"width": 52,
"height": 66,
@@ -368,15 +246,15 @@
"labelWidth": 7,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 4
},
{
"id": "b.1.x.v",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 47,
- "y": 850
+ "x": 184,
+ "y": 112
},
"width": 53,
"height": 66,
@@ -409,15 +287,15 @@
"labelWidth": 8,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 4
},
{
"id": "b.1.x.w",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 45,
- "y": 986
+ "x": 257,
+ "y": 112
},
"width": 57,
"height": 66,
@@ -450,15 +328,15 @@
"labelWidth": 12,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 4
},
{
"id": "b.1.y",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 47,
- "y": 1122
+ "x": 384,
+ "y": 112
},
"width": 53,
"height": 66,
@@ -491,15 +369,15 @@
"labelWidth": 8,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
"level": 3
},
{
"id": "b.1.z",
- "type": "page",
+ "type": "rectangle",
"pos": {
- "x": 48,
- "y": 1258
+ "x": 457,
+ "y": 112
},
"width": 52,
"height": 66,
@@ -532,18 +410,141 @@
"labelWidth": 7,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
- "zIndex": 5,
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "b.2.x",
+ "type": "rectangle",
+ "pos": {
+ "x": 187,
+ "y": 348
+ },
+ "width": 52,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "x",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 7,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "b.2.y",
+ "type": "rectangle",
+ "pos": {
+ "x": 259,
+ "y": 348
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "y",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 3
+ },
+ {
+ "id": "b.2.z",
+ "type": "rectangle",
+ "pos": {
+ "x": 332,
+ "y": 348
+ },
+ "width": 52,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "z",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 7,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
"level": 3
},
{
"id": "a",
"type": "rectangle",
"pos": {
- "x": 379,
- "y": -506
+ "x": 652,
+ "y": -406
},
- "width": 345,
- "height": 498,
+ "width": 245,
+ "height": 398,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
@@ -580,10 +581,10 @@
"id": "a.1",
"type": "rectangle",
"pos": {
- "x": 439,
- "y": -446
+ "x": 712,
+ "y": -346
},
- "width": 225,
+ "width": 125,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@@ -621,10 +622,10 @@
"id": "a.2",
"type": "rectangle",
"pos": {
- "x": 439,
- "y": -340
+ "x": 712,
+ "y": -240
},
- "width": 225,
+ "width": 125,
"height": 66,
"opacity": 1,
"strokeDash": 0,
@@ -662,11 +663,11 @@
"id": "a.3",
"type": "sequence_diagram",
"pos": {
- "x": 439,
- "y": -234
+ "x": 712,
+ "y": -134
},
- "width": 225,
- "height": 166,
+ "width": 125,
+ "height": 66,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
@@ -695,7 +696,7 @@
"underline": false,
"labelWidth": 11,
"labelHeight": 31,
- "labelPosition": "INSIDE_TOP_CENTER",
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
@@ -703,8 +704,8 @@
"id": "a.3.x",
"type": "rectangle",
"pos": {
- "x": 489,
- "y": -184
+ "x": 712,
+ "y": -134
},
"width": 52,
"height": 66,
@@ -744,8 +745,8 @@
"id": "a.3.y",
"type": "rectangle",
"pos": {
- "x": 561,
- "y": -184
+ "x": 784,
+ "y": -134
},
"width": 53,
"height": 66,
@@ -808,94 +809,18 @@
"labelPercentage": 0,
"route": [
{
- "x": 74,
- "y": 236
+ "x": 285.5,
+ "y": 278
},
{
- "x": 224,
- "y": 236
+ "x": 285.5,
+ "y": 348
}
],
"animated": false,
"tooltip": "",
"icon": null,
- "zIndex": 4
- },
- {
- "id": "(b.1 -- )[0]",
- "src": "b.1",
- "srcArrow": "none",
- "dst": "1-lifeline-end-1719232319",
- "dstArrow": "none",
- "opacity": 1,
- "strokeDash": 6,
- "strokeWidth": 2,
- "stroke": "B2",
- "borderRadius": 10,
- "label": "",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N2",
- "italic": true,
- "bold": false,
- "underline": false,
- "labelWidth": 0,
- "labelHeight": 0,
- "labelPosition": "",
- "labelPercentage": 0,
- "route": [
- {
- "x": 74,
- "y": 166
- },
- {
- "x": 74,
- "y": 1394
- }
- ],
- "animated": false,
- "tooltip": "",
- "icon": null,
- "zIndex": 1
- },
- {
- "id": "(b.2 -- )[0]",
- "src": "b.2",
- "srcArrow": "none",
- "dst": "2-lifeline-end-1739547740",
- "dstArrow": "none",
- "opacity": 1,
- "strokeDash": 6,
- "strokeWidth": 2,
- "stroke": "B2",
- "borderRadius": 10,
- "label": "",
- "fontSize": 16,
- "fontFamily": "DEFAULT",
- "language": "",
- "color": "N2",
- "italic": true,
- "bold": false,
- "underline": false,
- "labelWidth": 0,
- "labelHeight": 0,
- "labelPosition": "",
- "labelPercentage": 0,
- "route": [
- {
- "x": 224,
- "y": 166
- },
- {
- "x": 224,
- "y": 1394
- }
- ],
- "animated": false,
- "tooltip": "",
- "icon": null,
- "zIndex": 1
+ "zIndex": 0
}
],
"root": {
diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg
index 7979d68d6..0bc4e994d 100644
--- a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg
+++ b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg
@@ -1,16 +1,16 @@
-bca12123xy xyzyzuvw
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ .d2-1680302338 .fill-N1{fill:#0A0F25;}
+ .d2-1680302338 .fill-N2{fill:#676C7E;}
+ .d2-1680302338 .fill-N3{fill:#9499AB;}
+ .d2-1680302338 .fill-N4{fill:#CFD2DD;}
+ .d2-1680302338 .fill-N5{fill:#DEE1EB;}
+ .d2-1680302338 .fill-N6{fill:#EEF1F8;}
+ .d2-1680302338 .fill-N7{fill:#FFFFFF;}
+ .d2-1680302338 .fill-B1{fill:#0D32B2;}
+ .d2-1680302338 .fill-B2{fill:#0D32B2;}
+ .d2-1680302338 .fill-B3{fill:#E3E9FD;}
+ .d2-1680302338 .fill-B4{fill:#E3E9FD;}
+ .d2-1680302338 .fill-B5{fill:#EDF0FD;}
+ .d2-1680302338 .fill-B6{fill:#F7F8FE;}
+ .d2-1680302338 .fill-AA2{fill:#4A6FF3;}
+ .d2-1680302338 .fill-AA4{fill:#EDF0FD;}
+ .d2-1680302338 .fill-AA5{fill:#F7F8FE;}
+ .d2-1680302338 .fill-AB4{fill:#EDF0FD;}
+ .d2-1680302338 .fill-AB5{fill:#F7F8FE;}
+ .d2-1680302338 .stroke-N1{stroke:#0A0F25;}
+ .d2-1680302338 .stroke-N2{stroke:#676C7E;}
+ .d2-1680302338 .stroke-N3{stroke:#9499AB;}
+ .d2-1680302338 .stroke-N4{stroke:#CFD2DD;}
+ .d2-1680302338 .stroke-N5{stroke:#DEE1EB;}
+ .d2-1680302338 .stroke-N6{stroke:#EEF1F8;}
+ .d2-1680302338 .stroke-N7{stroke:#FFFFFF;}
+ .d2-1680302338 .stroke-B1{stroke:#0D32B2;}
+ .d2-1680302338 .stroke-B2{stroke:#0D32B2;}
+ .d2-1680302338 .stroke-B3{stroke:#E3E9FD;}
+ .d2-1680302338 .stroke-B4{stroke:#E3E9FD;}
+ .d2-1680302338 .stroke-B5{stroke:#EDF0FD;}
+ .d2-1680302338 .stroke-B6{stroke:#F7F8FE;}
+ .d2-1680302338 .stroke-AA2{stroke:#4A6FF3;}
+ .d2-1680302338 .stroke-AA4{stroke:#EDF0FD;}
+ .d2-1680302338 .stroke-AA5{stroke:#F7F8FE;}
+ .d2-1680302338 .stroke-AB4{stroke:#EDF0FD;}
+ .d2-1680302338 .stroke-AB5{stroke:#F7F8FE;}
+ .d2-1680302338 .background-color-N1{background-color:#0A0F25;}
+ .d2-1680302338 .background-color-N2{background-color:#676C7E;}
+ .d2-1680302338 .background-color-N3{background-color:#9499AB;}
+ .d2-1680302338 .background-color-N4{background-color:#CFD2DD;}
+ .d2-1680302338 .background-color-N5{background-color:#DEE1EB;}
+ .d2-1680302338 .background-color-N6{background-color:#EEF1F8;}
+ .d2-1680302338 .background-color-N7{background-color:#FFFFFF;}
+ .d2-1680302338 .background-color-B1{background-color:#0D32B2;}
+ .d2-1680302338 .background-color-B2{background-color:#0D32B2;}
+ .d2-1680302338 .background-color-B3{background-color:#E3E9FD;}
+ .d2-1680302338 .background-color-B4{background-color:#E3E9FD;}
+ .d2-1680302338 .background-color-B5{background-color:#EDF0FD;}
+ .d2-1680302338 .background-color-B6{background-color:#F7F8FE;}
+ .d2-1680302338 .background-color-AA2{background-color:#4A6FF3;}
+ .d2-1680302338 .background-color-AA4{background-color:#EDF0FD;}
+ .d2-1680302338 .background-color-AA5{background-color:#F7F8FE;}
+ .d2-1680302338 .background-color-AB4{background-color:#EDF0FD;}
+ .d2-1680302338 .background-color-AB5{background-color:#F7F8FE;}
+ .d2-1680302338 .color-N1{color:#0A0F25;}
+ .d2-1680302338 .color-N2{color:#676C7E;}
+ .d2-1680302338 .color-N3{color:#9499AB;}
+ .d2-1680302338 .color-N4{color:#CFD2DD;}
+ .d2-1680302338 .color-N5{color:#DEE1EB;}
+ .d2-1680302338 .color-N6{color:#EEF1F8;}
+ .d2-1680302338 .color-N7{color:#FFFFFF;}
+ .d2-1680302338 .color-B1{color:#0D32B2;}
+ .d2-1680302338 .color-B2{color:#0D32B2;}
+ .d2-1680302338 .color-B3{color:#E3E9FD;}
+ .d2-1680302338 .color-B4{color:#E3E9FD;}
+ .d2-1680302338 .color-B5{color:#EDF0FD;}
+ .d2-1680302338 .color-B6{color:#F7F8FE;}
+ .d2-1680302338 .color-AA2{color:#4A6FF3;}
+ .d2-1680302338 .color-AA4{color:#EDF0FD;}
+ .d2-1680302338 .color-AA5{color:#F7F8FE;}
+ .d2-1680302338 .color-AB4{color:#EDF0FD;}
+ .d2-1680302338 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>bca12123xyzxyzxyuvw
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file