This commit is contained in:
Gavin Nishizawa 2023-09-15 22:07:06 -07:00
parent e83ac4c3ac
commit b7791c83ea
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
8 changed files with 810 additions and 757 deletions

View file

@ -1925,7 +1925,7 @@ func (g *Graph) PrintString() string {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
fmt.Fprint(buf, "Objects: [") fmt.Fprint(buf, "Objects: [")
for _, obj := range g.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, "]") fmt.Fprint(buf, "]")
return buf.String() return buf.String()

View file

@ -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) { 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{}) toRemove := make(map[*d2graph.Object]struct{})
edgeToRemove := make(map[*d2graph.Edge]struct{}) edgeToRemove := make(map[*d2graph.Edge]struct{})

View file

@ -5,11 +5,13 @@ import (
"math" "math"
"strings" "strings"
"cdr.dev/slog"
"oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2layouts/d2grid" "oss.terrastruct.com/d2/d2layouts/d2grid"
"oss.terrastruct.com/d2/d2layouts/d2near" "oss.terrastruct.com/d2/d2layouts/d2near"
"oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2layouts/d2sequence"
"oss.terrastruct.com/d2/lib/geo" "oss.terrastruct.com/d2/lib/geo"
"oss.terrastruct.com/d2/lib/log"
) )
type DiagramType string 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 { 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. // Before we can layout these nodes, we need to handle all nested diagrams first.
extracted := make(map[*d2graph.Object]*d2graph.Graph) extracted := make(map[*d2graph.Object]*d2graph.Graph)
extractedInfo := make(map[*d2graph.Object]GraphInfo) 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 { for _, child := range queue {
if gi := NestedGraphInfo(child); !gi.isDefault() { if gi := NestedGraphInfo(child); !gi.isDefault() {
extractedInfo[child] = gi extractedInfo[child] = gi
// log.Warn(ctx, "nested", slog.F("child", child.AbsID()), slog.F("gi", gi))
var nestedGraph *d2graph.Graph // There is a nested diagram here, so extract its contents and process in the same way
if gi.IsConstantNear { nestedGraph := ExtractDescendants(child)
nestedGraph = ExtractSelf(child)
} else {
// There is a nested diagram here, so extract its contents and process in the same way
nestedGraph = ExtractDescendants(child)
}
// Layout of nestedGraph is completed // 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) spacing := LayoutNested(ctx, nestedGraph, gi, coreLayout)
if !gi.IsConstantNear { log.Warn(ctx, "fitting child", slog.F("child", child.AbsID()))
// Fit child to size of nested layout // Fit child to size of nested layout
FitToGraph(child, nestedGraph, spacing) 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 // We will restore the contents after running layout with child as the placeholder
if gi.IsConstantNear { if gi.IsConstantNear {
constantNears = append(constantNears, nestedGraph) constantNears = append(constantNears, nearGraph)
} else {
extracted[child] = nestedGraph
} }
extracted[child] = nestedGraph
} else if len(child.Children) > 0 { } else if len(child.Children) > 0 {
queue = append(queue, child.ChildrenArray...) queue = append(queue, child.ChildrenArray...)
} }
@ -89,17 +103,21 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
switch graphInfo.DiagramType { switch graphInfo.DiagramType {
case GridDiagram: case GridDiagram:
layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) log.Warn(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString()))
if err = layoutWithGrids(ctx, g); err != nil { // layoutWithGrids := d2grid.Layout2(ctx, g, coreLayout)
// layoutWithGrids(ctx, g)
if err = d2grid.Layout2(ctx, g); err != nil {
panic(err) panic(err)
} }
case SequenceDiagram: case SequenceDiagram:
log.Warn(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString()))
err = d2sequence.Layout2(ctx, g, coreLayout) err = d2sequence.Layout2(ctx, g, coreLayout)
if err != nil { if err != nil {
panic(err) panic(err)
} }
default: default:
log.Warn(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString()))
err := coreLayout(ctx, g) err := coreLayout(ctx, g)
if err != nil { if err != nil {
panic(err) panic(err)
@ -109,14 +127,6 @@ func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, co
} }
spacing := LayoutDiagram(ctx, g, graphInfo, coreLayout) 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 there are
if len(constantNears) > 0 { if len(constantNears) > 0 {
err := d2near.Layout(ctx, g, constantNears) 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 return spacing
} }
@ -152,6 +171,7 @@ func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) {
func ExtractSelf(container *d2graph.Object) *d2graph.Graph { func ExtractSelf(container *d2graph.Object) *d2graph.Graph {
nestedGraph := d2graph.NewGraph() nestedGraph := d2graph.NewGraph()
nestedGraph.RootLevel = int(container.Level()) - 1 nestedGraph.RootLevel = int(container.Level()) - 1
// nestedGraph.Root.Box = &geo.Box{}
// separate out nested edges // separate out nested edges
g := container.Graph g := container.Graph
@ -255,13 +275,16 @@ func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph) {
g.Objects = append(g.Objects, nestedGraph.Objects...) g.Objects = append(g.Objects, nestedGraph.Objects...)
g.Edges = append(g.Edges, nestedGraph.Edges...) 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) { 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 // Note: assumes nestedGraph's layout has contents positioned relative to 0,0
dx := container.TopLeft.X - tl.X dx := container.TopLeft.X //- tl.X
dy := container.TopLeft.Y - tl.Y dy := container.TopLeft.Y //- tl.Y
for _, o := range nestedGraph.Objects { for _, o := range nestedGraph.Objects {
o.TopLeft.X += dx o.TopLeft.X += dx
o.TopLeft.Y += dy 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)) br = geo.NewPoint(math.Inf(-1), math.Inf(-1))
for _, obj := range g.Objects { for _, obj := range g.Objects {
if obj.TopLeft == nil {
panic(obj.AbsID())
}
tl.X = math.Min(tl.X, obj.TopLeft.X) tl.X = math.Min(tl.X, obj.TopLeft.X)
tl.Y = math.Min(tl.Y, obj.TopLeft.Y) tl.Y = math.Min(tl.Y, obj.TopLeft.Y)
br.X = math.Max(br.X, obj.TopLeft.X+obj.Width) 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) { func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding geo.Spacing) {
tl, br := boundingBox(nestedGraph) var width, height float64
container.Width = padding.Left + br.X - tl.X + padding.Right // if nestedGraph.Root.Box != nil {
container.Height = padding.Top + br.Y - tl.Y + padding.Bottom 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 { // func LayoutDiagram(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) geo.Spacing {

View file

@ -22,12 +22,12 @@ b: {
1 -> 2 1 -> 2
# TODO This should work # TODO This should work
# near: bottom-left near: bottom-right
# #
2: { 2: {
# TODO compile error grid on sequence actor # TODO compile error grid on sequence actor
grid-rows: 3 # grid-rows: 3
x x
y y
z z
@ -36,7 +36,7 @@ b: {
1: { 1: {
x: { x: {
# TODO compile error grid in sequence (anywhere) # TODO compile error grid in sequence (anywhere)
grid-rows: 3 # grid-rows: 3
u u
v v
w w

View file

@ -10,8 +10,8 @@
"x": 0, "x": 0,
"y": 0 "y": 0
}, },
"width": 274, "width": 699,
"height": 1394, "height": 393,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 0, "strokeWidth": 0,
@ -40,7 +40,7 @@
"underline": false, "underline": false,
"labelWidth": 13, "labelWidth": 13,
"labelHeight": 36, "labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
@ -48,8 +48,8 @@
"id": "c", "id": "c",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 334, "x": 759,
"y": 664 "y": 164
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -89,11 +89,11 @@
"id": "b.1", "id": "b.1",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 0,
"y": 88 "y": 0
}, },
"width": 100, "width": 617,
"height": 66, "height": 187,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 2, "strokeWidth": 2,
@ -122,7 +122,7 @@
"underline": false, "underline": false,
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
}, },
@ -130,10 +130,10 @@
"id": "b.2", "id": "b.2",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 162, "x": 422,
"y": 88 "y": 327
}, },
"width": 100, "width": 277,
"height": 66, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
@ -168,19 +168,19 @@
"level": 2 "level": 2
}, },
{ {
"id": "b.2.x", "id": "b.1.x",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 186, "x": 30,
"y": 294 "y": 31
}, },
"width": 52, "width": 342,
"height": 66, "height": 126,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 2, "strokeWidth": 2,
"borderRadius": 0, "borderRadius": 0,
"fill": "N7", "fill": "B4",
"stroke": "B1", "stroke": "B1",
"shadow": false, "shadow": false,
"3d": false, "3d": false,
@ -204,138 +204,16 @@
"underline": false, "underline": false,
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 5, "zIndex": 0,
"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,
"level": 3 "level": 3
}, },
{ {
"id": "b.1.x.u", "id": "b.1.x.u",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 36, "x": 60,
"y": 702 "y": 61
}, },
"width": 52, "width": 52,
"height": 66, "height": 66,
@ -368,15 +246,15 @@
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 4 "level": 4
}, },
{ {
"id": "b.1.x.v", "id": "b.1.x.v",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 35, "x": 172,
"y": 838 "y": 61
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -409,15 +287,15 @@
"labelWidth": 8, "labelWidth": 8,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 4 "level": 4
}, },
{ {
"id": "b.1.x.w", "id": "b.1.x.w",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 33, "x": 285,
"y": 974 "y": 61
}, },
"width": 57, "width": 57,
"height": 66, "height": 66,
@ -450,15 +328,15 @@
"labelWidth": 12, "labelWidth": 12,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 4 "level": 4
}, },
{ {
"id": "b.1.y", "id": "b.1.y",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 35, "x": 534,
"y": 1110 "y": 61
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -491,15 +369,15 @@
"labelWidth": 8, "labelWidth": 8,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 3 "level": 3
}, },
{ {
"id": "b.1.z", "id": "b.1.z",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 36, "x": 422,
"y": 1246 "y": 61
}, },
"width": 52, "width": 52,
"height": 66, "height": 66,
@ -532,18 +410,141 @@
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "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 "level": 3
}, },
{ {
"id": "a", "id": "a",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 407, "x": 832,
"y": -478 "y": -444
}, },
"width": 345, "width": 285,
"height": 458, "height": 398,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 2, "strokeWidth": 2,
@ -580,10 +581,10 @@
"id": "a.1", "id": "a.1",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 467, "x": 892,
"y": -418 "y": -384
}, },
"width": 225, "width": 165,
"height": 66, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
@ -621,10 +622,10 @@
"id": "a.2", "id": "a.2",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 467, "x": 892,
"y": -312 "y": -278
}, },
"width": 225, "width": 165,
"height": 66, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
@ -662,11 +663,11 @@
"id": "a.3", "id": "a.3",
"type": "sequence_diagram", "type": "sequence_diagram",
"pos": { "pos": {
"x": 467, "x": 892,
"y": -206 "y": -172
}, },
"width": 225, "width": 165,
"height": 126, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 0, "strokeWidth": 0,
@ -695,7 +696,7 @@
"underline": false, "underline": false,
"labelWidth": 11, "labelWidth": 11,
"labelHeight": 31, "labelHeight": 31,
"labelPosition": "OUTSIDE_TOP_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
}, },
@ -703,8 +704,8 @@
"id": "a.3.x", "id": "a.3.x",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 497, "x": 892,
"y": -176 "y": -172
}, },
"width": 52, "width": 52,
"height": 66, "height": 66,
@ -744,8 +745,8 @@
"id": "a.3.y", "id": "a.3.y",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 609, "x": 1004,
"y": -176 "y": -172
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -808,94 +809,27 @@
"labelPercentage": 0, "labelPercentage": 0,
"route": [ "route": [
{ {
"x": 62, "x": 560.5,
"y": 224 "y": 187
}, },
{ {
"x": 212, "x": 560.5,
"y": 224 "y": 259
},
{
"x": 560.5,
"y": 287
},
{
"x": 560.5,
"y": 327
} }
], ],
"isCurve": true,
"animated": false, "animated": false,
"tooltip": "", "tooltip": "",
"icon": null, "icon": null,
"zIndex": 4 "zIndex": 0
},
{
"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
} }
], ],
"root": { "root": {

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -10,8 +10,8 @@
"x": 12, "x": 12,
"y": 12 "y": 12
}, },
"width": 274, "width": 547,
"height": 1394, "height": 402,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 0, "strokeWidth": 0,
@ -40,7 +40,7 @@
"underline": false, "underline": false,
"labelWidth": 13, "labelWidth": 13,
"labelHeight": 36, "labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
@ -48,8 +48,8 @@
"id": "c", "id": "c",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 306, "x": 579,
"y": 676 "y": 180
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -89,11 +89,11 @@
"id": "b.1", "id": "b.1",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 24, "x": 12,
"y": 100 "y": 12
}, },
"width": 100, "width": 547,
"height": 66, "height": 266,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 2, "strokeWidth": 2,
@ -122,7 +122,7 @@
"underline": false, "underline": false,
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
}, },
@ -130,10 +130,10 @@
"id": "b.2", "id": "b.2",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 174, "x": 187,
"y": 100 "y": 348
}, },
"width": 100, "width": 197,
"height": 66, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
@ -168,19 +168,19 @@
"level": 2 "level": 2
}, },
{ {
"id": "b.2.x", "id": "b.1.x",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 198, "x": 62,
"y": 306 "y": 62
}, },
"width": 52, "width": 302,
"height": 66, "height": 166,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 2, "strokeWidth": 2,
"borderRadius": 0, "borderRadius": 0,
"fill": "N7", "fill": "B4",
"stroke": "B1", "stroke": "B1",
"shadow": false, "shadow": false,
"3d": false, "3d": false,
@ -204,138 +204,16 @@
"underline": false, "underline": false,
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 5, "zIndex": 0,
"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,
"level": 3 "level": 3
}, },
{ {
"id": "b.1.x.u", "id": "b.1.x.u",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 48, "x": 112,
"y": 714 "y": 112
}, },
"width": 52, "width": 52,
"height": 66, "height": 66,
@ -368,15 +246,15 @@
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 4 "level": 4
}, },
{ {
"id": "b.1.x.v", "id": "b.1.x.v",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 47, "x": 184,
"y": 850 "y": 112
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -409,15 +287,15 @@
"labelWidth": 8, "labelWidth": 8,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 4 "level": 4
}, },
{ {
"id": "b.1.x.w", "id": "b.1.x.w",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 45, "x": 257,
"y": 986 "y": 112
}, },
"width": 57, "width": 57,
"height": 66, "height": 66,
@ -450,15 +328,15 @@
"labelWidth": 12, "labelWidth": 12,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 4 "level": 4
}, },
{ {
"id": "b.1.y", "id": "b.1.y",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 47, "x": 384,
"y": 1122 "y": 112
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -491,15 +369,15 @@
"labelWidth": 8, "labelWidth": 8,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5, "zIndex": 0,
"level": 3 "level": 3
}, },
{ {
"id": "b.1.z", "id": "b.1.z",
"type": "page", "type": "rectangle",
"pos": { "pos": {
"x": 48, "x": 457,
"y": 1258 "y": 112
}, },
"width": 52, "width": 52,
"height": 66, "height": 66,
@ -532,18 +410,141 @@
"labelWidth": 7, "labelWidth": 7,
"labelHeight": 21, "labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER", "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 "level": 3
}, },
{ {
"id": "a", "id": "a",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 379, "x": 652,
"y": -506 "y": -406
}, },
"width": 345, "width": 245,
"height": 498, "height": 398,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 2, "strokeWidth": 2,
@ -580,10 +581,10 @@
"id": "a.1", "id": "a.1",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 439, "x": 712,
"y": -446 "y": -346
}, },
"width": 225, "width": 125,
"height": 66, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
@ -621,10 +622,10 @@
"id": "a.2", "id": "a.2",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 439, "x": 712,
"y": -340 "y": -240
}, },
"width": 225, "width": 125,
"height": 66, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
@ -662,11 +663,11 @@
"id": "a.3", "id": "a.3",
"type": "sequence_diagram", "type": "sequence_diagram",
"pos": { "pos": {
"x": 439, "x": 712,
"y": -234 "y": -134
}, },
"width": 225, "width": 125,
"height": 166, "height": 66,
"opacity": 1, "opacity": 1,
"strokeDash": 0, "strokeDash": 0,
"strokeWidth": 0, "strokeWidth": 0,
@ -695,7 +696,7 @@
"underline": false, "underline": false,
"labelWidth": 11, "labelWidth": 11,
"labelHeight": 31, "labelHeight": 31,
"labelPosition": "INSIDE_TOP_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
}, },
@ -703,8 +704,8 @@
"id": "a.3.x", "id": "a.3.x",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 489, "x": 712,
"y": -184 "y": -134
}, },
"width": 52, "width": 52,
"height": 66, "height": 66,
@ -744,8 +745,8 @@
"id": "a.3.y", "id": "a.3.y",
"type": "rectangle", "type": "rectangle",
"pos": { "pos": {
"x": 561, "x": 784,
"y": -184 "y": -134
}, },
"width": 53, "width": 53,
"height": 66, "height": 66,
@ -808,94 +809,18 @@
"labelPercentage": 0, "labelPercentage": 0,
"route": [ "route": [
{ {
"x": 74, "x": 285.5,
"y": 236 "y": 278
}, },
{ {
"x": 224, "x": 285.5,
"y": 236 "y": 348
} }
], ],
"animated": false, "animated": false,
"tooltip": "", "tooltip": "",
"icon": null, "icon": null,
"zIndex": 4 "zIndex": 0
},
{
"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
} }
], ],
"root": { "root": {

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 20 KiB