diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md
index 4c987851e..083a5db15 100644
--- a/ci/release/changelogs/next.md
+++ b/ci/release/changelogs/next.md
@@ -1,6 +1,7 @@
#### Features π
- Multi-board SVG outputs with internal links go to their output paths [#1116](https://github.com/terrastruct/d2/pull/1116)
+- New grid layout to place nodes in rows and columns [#1122](https://github.com/terrastruct/d2/pull/1122)
#### Improvements π§Ή
diff --git a/d2compiler/compile.go b/d2compiler/compile.go
index 28288795d..c3d721bc7 100644
--- a/d2compiler/compile.go
+++ b/d2compiler/compile.go
@@ -73,6 +73,7 @@ func (c *compiler) compileBoard(g *d2graph.Graph, ir *d2ir.Map) *d2graph.Graph {
c.validateKeys(g.Root, ir)
}
c.validateNear(g)
+ c.validateEdges(g)
c.compileBoardsField(g, ir, "layers")
c.compileBoardsField(g, ir, "scenarios")
@@ -362,6 +363,32 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) {
}
attrs.Constraint.Value = scalar.ScalarString()
attrs.Constraint.MapKey = f.LastPrimaryKey()
+ case "grid-rows":
+ v, err := strconv.Atoi(scalar.ScalarString())
+ if err != nil {
+ c.errorf(scalar, "non-integer grid-rows %#v: %s", scalar.ScalarString(), err)
+ return
+ }
+ if v <= 0 {
+ c.errorf(scalar, "grid-rows must be a positive integer: %#v", scalar.ScalarString())
+ return
+ }
+ attrs.GridRows = &d2graph.Scalar{}
+ attrs.GridRows.Value = scalar.ScalarString()
+ attrs.GridRows.MapKey = f.LastPrimaryKey()
+ case "grid-columns":
+ v, err := strconv.Atoi(scalar.ScalarString())
+ if err != nil {
+ c.errorf(scalar, "non-integer grid-columns %#v: %s", scalar.ScalarString(), err)
+ return
+ }
+ if v <= 0 {
+ c.errorf(scalar, "grid-columns must be a positive integer: %#v", scalar.ScalarString())
+ return
+ }
+ attrs.GridColumns = &d2graph.Scalar{}
+ attrs.GridColumns.Value = scalar.ScalarString()
+ attrs.GridColumns.MapKey = f.LastPrimaryKey()
}
if attrs.Link != nil && attrs.Tooltip != nil {
@@ -678,6 +705,13 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) {
if !in && arrowheadIn {
c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid shape, can only set "%s" for arrowheads`, obj.Attributes.Shape.Value))
}
+ case "grid-rows", "grid-columns":
+ for _, child := range obj.ChildrenArray {
+ if child.IsContainer() {
+ c.errorf(f.LastPrimaryKey(),
+ fmt.Sprintf(`%#v can only be used on containers with one level of nesting right now. (%#v has nested %#v)`, keyword, child.AbsID(), child.ChildrenArray[0].ID))
+ }
+ }
}
return
}
@@ -761,6 +795,19 @@ func (c *compiler) validateNear(g *d2graph.Graph) {
}
}
+func (c *compiler) validateEdges(g *d2graph.Graph) {
+ for _, edge := range g.Edges {
+ if gd := edge.Src.Parent.ClosestGridDiagram(); gd != nil {
+ c.errorf(edge.GetAstEdge(), "edges in grid diagrams are not supported yet")
+ continue
+ }
+ if gd := edge.Dst.Parent.ClosestGridDiagram(); gd != nil {
+ c.errorf(edge.GetAstEdge(), "edges in grid diagrams are not supported yet")
+ continue
+ }
+ }
+}
+
func (c *compiler) validateBoardLinks(g *d2graph.Graph) {
for _, obj := range g.Objects {
if obj.Attributes.Link == nil {
diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go
index 53e33e22f..89b8b04f2 100644
--- a/d2compiler/compile_test.go
+++ b/d2compiler/compile_test.go
@@ -2268,6 +2268,56 @@ obj {
`,
expErr: `d2/testdata/d2compiler/TestCompile/near_near_const.d2:7:8: near keys cannot be set to an object with a constant near key`,
},
+ {
+ name: "grid",
+ text: `hey: {
+ grid-rows: 200
+ grid-columns: 230
+}
+`,
+ assertions: func(t *testing.T, g *d2graph.Graph) {
+ tassert.Equal(t, "200", g.Objects[0].Attributes.GridRows.Value)
+ },
+ },
+ {
+ name: "grid_negative",
+ text: `hey: {
+ grid-rows: 200
+ grid-columns: -200
+}
+`,
+ expErr: `d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:16: grid-columns must be a positive integer: "-200"`,
+ },
+ {
+ name: "grid_edge",
+ text: `hey: {
+ grid-rows: 1
+ a -> b
+}
+ c -> hey.b
+ hey.a -> c
+
+ hey -> c: ok
+`,
+ expErr: `d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edges in grid diagrams are not supported yet
+d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edges in grid diagrams are not supported yet
+d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are not supported yet`,
+ },
+ {
+ name: "grid_nested",
+ text: `hey: {
+ grid-rows: 200
+ grid-columns: 200
+
+ a
+ b
+ c
+ d.invalid descendant
+}
+`,
+ expErr: `d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: "grid-rows" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant")
+d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: "grid-columns" can only be used on containers with one level of nesting right now. ("hey.d" has nested "invalid descendant")`,
+ },
}
for _, tc := range testCases {
diff --git a/d2exporter/export_test.go b/d2exporter/export_test.go
index effcc07a8..bc6f47010 100644
--- a/d2exporter/export_test.go
+++ b/d2exporter/export_test.go
@@ -16,6 +16,7 @@ import (
"oss.terrastruct.com/d2/d2compiler"
"oss.terrastruct.com/d2/d2exporter"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
+ "oss.terrastruct.com/d2/d2layouts/d2grid"
"oss.terrastruct.com/d2/d2layouts/d2sequence"
"oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/lib/geo"
@@ -231,7 +232,7 @@ func run(t *testing.T, tc testCase) {
err = g.SetDimensions(nil, ruler, nil)
assert.JSON(t, nil, err)
- err = d2sequence.Layout(ctx, g, d2dagrelayout.DefaultLayout)
+ err = d2sequence.Layout(ctx, g, d2grid.Layout(ctx, g, d2dagrelayout.DefaultLayout))
if err != nil {
t.Fatal(err)
}
diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go
index a9c370620..be2892e97 100644
--- a/d2graph/d2graph.go
+++ b/d2graph/d2graph.go
@@ -1,6 +1,7 @@
package d2graph
import (
+ "context"
"errors"
"fmt"
"math"
@@ -67,6 +68,8 @@ func (g *Graph) RootBoard() *Graph {
return g
}
+type LayoutGraph func(context.Context, *Graph) error
+
// TODO consider having different Scalar types
// Right now we'll hold any types in Value and just convert, e.g. floats
type Scalar struct {
@@ -129,6 +132,9 @@ type Attributes struct {
Direction Scalar `json:"direction"`
Constraint Scalar `json:"constraint"`
+
+ GridRows *Scalar `json:"gridRows,omitempty"`
+ GridColumns *Scalar `json:"gridColumns,omitempty"`
}
// TODO references at the root scope should have their Scope set to root graph AST
@@ -1007,6 +1013,10 @@ type EdgeReference struct {
ScopeObj *Object `json:"-"`
}
+func (e *Edge) GetAstEdge() *d2ast.Edge {
+ return e.References[0].Edge
+}
+
func (e *Edge) GetStroke(dashGapSize interface{}) string {
if dashGapSize != 0.0 {
return color.B2
@@ -1521,19 +1531,21 @@ var ReservedKeywords2 map[string]struct{}
// Non Style/Holder keywords.
var SimpleReservedKeywords = map[string]struct{}{
- "label": {},
- "desc": {},
- "shape": {},
- "icon": {},
- "constraint": {},
- "tooltip": {},
- "link": {},
- "near": {},
- "width": {},
- "height": {},
- "direction": {},
- "top": {},
- "left": {},
+ "label": {},
+ "desc": {},
+ "shape": {},
+ "icon": {},
+ "constraint": {},
+ "tooltip": {},
+ "link": {},
+ "near": {},
+ "width": {},
+ "height": {},
+ "direction": {},
+ "top": {},
+ "left": {},
+ "grid-rows": {},
+ "grid-columns": {},
}
// ReservedKeywordHolders are reserved keywords that are meaningless on its own and exist solely to hold a set of reserved keywords
diff --git a/d2graph/grid_diagram.go b/d2graph/grid_diagram.go
new file mode 100644
index 000000000..6c40667a5
--- /dev/null
+++ b/d2graph/grid_diagram.go
@@ -0,0 +1,16 @@
+package d2graph
+
+func (obj *Object) IsGridDiagram() bool {
+ return obj != nil && obj.Attributes != nil &&
+ (obj.Attributes.GridRows != nil || obj.Attributes.GridColumns != nil)
+}
+
+func (obj *Object) ClosestGridDiagram() *Object {
+ if obj == nil {
+ return nil
+ }
+ if obj.IsGridDiagram() {
+ return obj
+ }
+ return obj.Parent.ClosestGridDiagram()
+}
diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go
new file mode 100644
index 000000000..264bc07cc
--- /dev/null
+++ b/d2layouts/d2grid/grid_diagram.go
@@ -0,0 +1,87 @@
+package d2grid
+
+import (
+ "strconv"
+ "strings"
+
+ "oss.terrastruct.com/d2/d2graph"
+)
+
+type gridDiagram struct {
+ root *d2graph.Object
+ objects []*d2graph.Object
+ rows int
+ columns int
+
+ // if true, place objects left to right along rows
+ // if false, place objects top to bottom along columns
+ rowDirected bool
+
+ width float64
+ height float64
+}
+
+func newGridDiagram(root *d2graph.Object) *gridDiagram {
+ gd := gridDiagram{root: root, objects: root.ChildrenArray}
+ if root.Attributes.GridRows != nil {
+ gd.rows, _ = strconv.Atoi(root.Attributes.GridRows.Value)
+ }
+ if root.Attributes.GridColumns != nil {
+ gd.columns, _ = strconv.Atoi(root.Attributes.GridColumns.Value)
+ }
+
+ if gd.rows != 0 && gd.columns != 0 {
+ // . row-directed column-directed
+ // . βββββββββ βββββββββ
+ // . β a b c β β a d g β
+ // . β d e f β β b e h β
+ // . β g h i β β c f i β
+ // . βββββββββ βββββββββ
+ // if keyword rows is first, make it row-directed, if columns is first it is column-directed
+ if root.Attributes.GridRows.MapKey.Range.Before(root.Attributes.GridColumns.MapKey.Range) {
+ gd.rowDirected = true
+ }
+
+ // rows and columns specified, but we want to continue naturally if user enters more objects
+ // e.g. 2 rows, 3 columns specified + g added: β with 3 columns, 2 rows:
+ // . original add row add column β original add row add column
+ // . βββββββββ βββββββββ βββββββββββ β βββββββββ βββββββββ βββββββββββ
+ // . β a b c β β a b c β β a b c d β β β a c e β β a d g β β a c e g β
+ // . β d e f β β d e f β β e f g β β β b d f β β b e β β b d f β
+ // . βββββββββ β g β βββββββββββ β βββββββββ β c f β βββββββββββ
+ // . βββββββββ β² β βββββββββ β²
+ // . β² ββexisting objects modifiedβ β² ββexisting columns preserved
+ // . ββexisting rows preserved β ββexisting objects modified
+ capacity := gd.rows * gd.columns
+ for capacity < len(gd.objects) {
+ if gd.rowDirected {
+ gd.rows++
+ capacity += gd.columns
+ } else {
+ gd.columns++
+ capacity += gd.rows
+ }
+ }
+ } else if gd.columns == 0 {
+ gd.rowDirected = true
+ }
+
+ return &gd
+}
+
+func (gd *gridDiagram) shift(dx, dy float64) {
+ for _, obj := range gd.objects {
+ obj.TopLeft.X += dx
+ obj.TopLeft.Y += dy
+ }
+}
+
+func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) {
+ obj.Children = make(map[string]*d2graph.Object)
+ obj.ChildrenArray = make([]*d2graph.Object, 0)
+ for _, child := range gd.objects {
+ obj.Children[strings.ToLower(child.ID)] = child
+ obj.ChildrenArray = append(obj.ChildrenArray, child)
+ }
+ graph.Objects = append(graph.Objects, gd.objects...)
+}
diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go
new file mode 100644
index 000000000..1edae9066
--- /dev/null
+++ b/d2layouts/d2grid/layout.go
@@ -0,0 +1,578 @@
+package d2grid
+
+import (
+ "context"
+ "math"
+ "sort"
+
+ "oss.terrastruct.com/d2/d2graph"
+ "oss.terrastruct.com/d2/lib/geo"
+ "oss.terrastruct.com/d2/lib/label"
+ "oss.terrastruct.com/util-go/go2"
+)
+
+const (
+ CONTAINER_PADDING = 60
+ HORIZONTAL_PAD = 40.
+ VERTICAL_PAD = 40.
+)
+
+// Layout runs the grid layout on containers with rows/columns
+// Note: children are not allowed edges or descendants
+//
+// 1. Traverse graph from root, skip objects with no rows/columns
+// 2. Construct a grid with the container children
+// 3. Remove the children from the main graph
+// 4. Run grid layout
+// 5. Set the resulting dimensions to the main graph shape
+// 6. Run core layouts (without grid children)
+// 7. Put grid children back in correct location
+func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d2graph.LayoutGraph {
+ return func(ctx context.Context, g *d2graph.Graph) error {
+ gridDiagrams, objectOrder, err := withoutGridDiagrams(ctx, g)
+ if err != nil {
+ return err
+ }
+
+ if g.Root.IsGridDiagram() && len(g.Root.ChildrenArray) != 0 {
+ g.Root.TopLeft = geo.NewPoint(0, 0)
+ } else if err := layout(ctx, g); err != nil {
+ return err
+ }
+
+ cleanup(g, gridDiagrams, objectOrder)
+ return nil
+ }
+}
+
+func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams map[string]*gridDiagram, objectOrder map[string]int, err error) {
+ toRemove := make(map[*d2graph.Object]struct{})
+ gridDiagrams = make(map[string]*gridDiagram)
+
+ if len(g.Objects) > 0 {
+ queue := make([]*d2graph.Object, 1, len(g.Objects))
+ queue[0] = g.Root
+ for len(queue) > 0 {
+ obj := queue[0]
+ queue = queue[1:]
+ if len(obj.ChildrenArray) == 0 {
+ continue
+ }
+ if !obj.IsGridDiagram() {
+ queue = append(queue, obj.ChildrenArray...)
+ continue
+ }
+
+ gd, err := layoutGrid(g, obj)
+ if err != nil {
+ return nil, nil, err
+ }
+ obj.Children = make(map[string]*d2graph.Object)
+ obj.ChildrenArray = nil
+
+ var dx, dy float64
+ width := gd.width + 2*CONTAINER_PADDING
+ labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING
+ if labelWidth > width {
+ dx = (labelWidth - width) / 2
+ width = labelWidth
+ }
+ height := gd.height + 2*CONTAINER_PADDING
+ labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING
+ if labelHeight > CONTAINER_PADDING {
+ // if the label doesn't fit within the padding, we need to add more
+ grow := labelHeight - CONTAINER_PADDING
+ dy = grow / 2
+ height += grow
+ }
+ // we need to center children if we have to expand to fit the container label
+ if dx != 0 || dy != 0 {
+ gd.shift(dx, dy)
+ }
+ obj.Box = geo.NewBox(nil, width, height)
+
+ obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
+ gridDiagrams[obj.AbsID()] = gd
+
+ for _, o := range gd.objects {
+ toRemove[o] = struct{}{}
+ }
+ }
+ }
+
+ objectOrder = make(map[string]int)
+ layoutObjects := make([]*d2graph.Object, 0, len(toRemove))
+ for i, obj := range g.Objects {
+ objectOrder[obj.AbsID()] = i
+ if _, exists := toRemove[obj]; !exists {
+ layoutObjects = append(layoutObjects, obj)
+ }
+ }
+ g.Objects = layoutObjects
+
+ return gridDiagrams, objectOrder, nil
+}
+
+func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) {
+ gd := newGridDiagram(obj)
+
+ if gd.rows != 0 && gd.columns != 0 {
+ gd.layoutEvenly(g, obj)
+ } else {
+ gd.layoutDynamic(g, obj)
+ }
+
+ // position labels and icons
+ for _, o := range gd.objects {
+ if o.Attributes.Icon != nil {
+ o.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
+ o.IconPosition = go2.Pointer(string(label.InsideMiddleCenter))
+ } else {
+ o.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
+ }
+ }
+
+ return gd, nil
+}
+
+func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) {
+ // layout objects in a grid with these 2 properties:
+ // all objects in the same row should have the same height
+ // all objects in the same column should have the same width
+
+ getObject := func(rowIndex, columnIndex int) *d2graph.Object {
+ var index int
+ if gd.rowDirected {
+ index = rowIndex*gd.columns + columnIndex
+ } else {
+ index = columnIndex*gd.rows + rowIndex
+ }
+ if index < len(gd.objects) {
+ return gd.objects[index]
+ }
+ return nil
+ }
+
+ rowHeights := make([]float64, 0, gd.rows)
+ colWidths := make([]float64, 0, gd.columns)
+ for i := 0; i < gd.rows; i++ {
+ rowHeight := 0.
+ for j := 0; j < gd.columns; j++ {
+ o := getObject(i, j)
+ if o == nil {
+ break
+ }
+ rowHeight = math.Max(rowHeight, o.Height)
+ }
+ rowHeights = append(rowHeights, rowHeight)
+ }
+ for j := 0; j < gd.columns; j++ {
+ columnWidth := 0.
+ for i := 0; i < gd.rows; i++ {
+ o := getObject(i, j)
+ if o == nil {
+ break
+ }
+ columnWidth = math.Max(columnWidth, o.Width)
+ }
+ colWidths = append(colWidths, columnWidth)
+ }
+
+ cursor := geo.NewPoint(0, 0)
+ if gd.rowDirected {
+ for i := 0; i < gd.rows; i++ {
+ for j := 0; j < gd.columns; j++ {
+ o := getObject(i, j)
+ if o == nil {
+ break
+ }
+ o.Width = colWidths[j]
+ o.Height = rowHeights[i]
+ o.TopLeft = cursor.Copy()
+ cursor.X += o.Width + HORIZONTAL_PAD
+ }
+ cursor.X = 0
+ cursor.Y += rowHeights[i] + VERTICAL_PAD
+ }
+ } else {
+ for j := 0; j < gd.columns; j++ {
+ for i := 0; i < gd.rows; i++ {
+ o := getObject(i, j)
+ if o == nil {
+ break
+ }
+ o.Width = colWidths[j]
+ o.Height = rowHeights[i]
+ o.TopLeft = cursor.Copy()
+ cursor.Y += o.Height + VERTICAL_PAD
+ }
+ cursor.X += colWidths[j] + HORIZONTAL_PAD
+ cursor.Y = 0
+ }
+ }
+
+ var totalWidth, totalHeight float64
+ for _, w := range colWidths {
+ totalWidth += w + HORIZONTAL_PAD
+ }
+ for _, h := range rowHeights {
+ totalHeight += h + VERTICAL_PAD
+ }
+ totalWidth -= HORIZONTAL_PAD
+ totalHeight -= VERTICAL_PAD
+ gd.width = totalWidth
+ gd.height = totalHeight
+}
+
+func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) {
+ // assume we have the following objects to layout:
+ // . βAβββββββββββββββ βBβββ βCββββββββββ βDβββββββββ βEβββββββββββββββββ
+ // . βββββββββββββββββ β β β β β β β β
+ // . β β ββββββββββββ β β β β
+ // . β β β β βββββββββββββββββββ
+ // . βββββ β β
+ // . βββββββββββ
+ // Note: if the grid is row dominant, all objects should be the same height (same width if column dominant)
+ // . βAββββββββββββββ βBβββ βCββββββββββ βDβββββββββ βEβββββββββββββββββ
+ // . β β β β β β β ββ€ β β β β β β β β
+ // . β β β β β β β β β ββ€ β β β β
+ // . β β β β β β β β β β β β β β β β β β€
+ // . β β β β β€ β β β β β β
+ // . ββββββββββββββββ βββββ ββββββββββββ βββββββββββ βββββββββββββββββββ
+
+ // we want to split up the total width across the N rows or columns as evenly as possible
+ var totalWidth, totalHeight float64
+ for _, o := range gd.objects {
+ totalWidth += o.Width
+ totalHeight += o.Height
+ }
+ totalWidth += HORIZONTAL_PAD * float64(len(gd.objects)-gd.rows)
+ totalHeight += VERTICAL_PAD * float64(len(gd.objects)-gd.columns)
+
+ var layout [][]*d2graph.Object
+ if gd.rowDirected {
+ targetWidth := totalWidth / float64(gd.rows)
+ layout = gd.getBestLayout(targetWidth, false)
+ } else {
+ targetHeight := totalHeight / float64(gd.columns)
+ layout = gd.getBestLayout(targetHeight, true)
+ }
+
+ cursor := geo.NewPoint(0, 0)
+ var maxY, maxX float64
+ if gd.rowDirected {
+ // if we have 2 rows, then each row's objects should have the same height
+ // . βAββββββββββββββ βBβββ βCββββββββββ β¬ maxHeight(A,B,C)
+ // . β β β β β β β ββ€ β β β β β
+ // . β β β β β β β β β ββ€ β
+ // . β β β β β β β
+ // . ββββββββββββββββ βββββ ββββββββββββ β΄
+ // . βDβββββββββ βEβββββββββββββββββ β¬ maxHeight(D,E)
+ // . β β β β β
+ // . β β β β β
+ // . β β β β β β β β β β β β€ β
+ // . β β β β β
+ // . βββββββββββ βββββββββββββββββββ β΄
+ rowWidths := []float64{}
+ for _, row := range layout {
+ rowHeight := 0.
+ for _, o := range row {
+ o.TopLeft = cursor.Copy()
+ cursor.X += o.Width + HORIZONTAL_PAD
+ rowHeight = math.Max(rowHeight, o.Height)
+ }
+ rowWidth := cursor.X - HORIZONTAL_PAD
+ rowWidths = append(rowWidths, rowWidth)
+ maxX = math.Max(maxX, rowWidth)
+
+ // set all objects in row to the same height
+ for _, o := range row {
+ o.Height = rowHeight
+ }
+
+ // new row
+ cursor.X = 0
+ cursor.Y += rowHeight + VERTICAL_PAD
+ }
+ maxY = cursor.Y - VERTICAL_PAD
+
+ // then expand thinnest objects to make each row the same width
+ // . βAββββββββββββββ βBβββ βCββββββββββ β¬ maxHeight(A,B,C)
+ // . β β β β β β β
+ // . β β β β β β β
+ // . β β β β β β β
+ // . ββββββββββββββββ βββββ ββββββββββββ β΄
+ // . βDβββββββββ¬βββββ βEβββββββββββββββββ β¬ maxHeight(D,E)
+ // . β β β β β
+ // . β β β β β β
+ // . β β β β β
+ // . β β β β β β
+ // . βββββββββββ΄βββββ βββββββββββββββββββ β΄
+ for i, row := range layout {
+ rowWidth := rowWidths[i]
+ if rowWidth == maxX {
+ continue
+ }
+ delta := maxX - rowWidth
+ objects := []*d2graph.Object{}
+ var widest float64
+ for _, o := range row {
+ widest = math.Max(widest, o.Width)
+ objects = append(objects, o)
+ }
+ sort.Slice(objects, func(i, j int) bool {
+ return objects[i].Width < objects[j].Width
+ })
+ // expand smaller objects to fill remaining space
+ for _, o := range objects {
+ if o.Width < widest {
+ var index int
+ for i, rowObj := range row {
+ if o == rowObj {
+ index = i
+ break
+ }
+ }
+ grow := math.Min(widest-o.Width, delta)
+ o.Width += grow
+ // shift following objects
+ for i := index + 1; i < len(row); i++ {
+ row[i].TopLeft.X += grow
+ }
+ delta -= grow
+ if delta <= 0 {
+ break
+ }
+ }
+ }
+ if delta > 0 {
+ grow := delta / float64(len(row))
+ for i := len(row) - 1; i >= 0; i-- {
+ o := row[i]
+ o.TopLeft.X += grow * float64(i)
+ o.Width += grow
+ delta -= grow
+ }
+ }
+ }
+ } else {
+ // if we have 3 columns, then each column's objects should have the same width
+ // . βmaxWidth(A,B)ββ€ βmaxW(C,D)ββ€ βmaxWidth(E)βββββββ€
+ // . βAββββββββββββββ βCββββββββββ βEβββββββββββββββββ
+ // . ββββββββββββββββ β β β β
+ // . βBβββ¬βββββββββββ ββββββββββββ β β
+ // . β β βDβββββββββ¬β βββββββββββββββββββ
+ // . β β β β β
+ // . β β β ββ
+ // . βββββ΄βββββββββββ β β
+ // . β ββ
+ // . βββββββββββ΄β
+ colHeights := []float64{}
+ for _, column := range layout {
+ colWidth := 0.
+ for _, o := range column {
+ o.TopLeft = cursor.Copy()
+ cursor.Y += o.Height + VERTICAL_PAD
+ colWidth = math.Max(colWidth, o.Width)
+ }
+ colHeight := cursor.Y - VERTICAL_PAD
+ colHeights = append(colHeights, colHeight)
+ maxY = math.Max(maxY, colHeight)
+ // set all objects in column to the same width
+ for _, o := range column {
+ o.Width = colWidth
+ }
+
+ // new column
+ cursor.Y = 0
+ cursor.X += colWidth + HORIZONTAL_PAD
+ }
+ maxX = cursor.X - HORIZONTAL_PAD
+ // then expand shortest objects to make each column the same height
+ // . βmaxWidth(A,B)ββ€ βmaxW(C,D)ββ€ βmaxWidth(E)βββββββ€
+ // . βAββββββββββββββ βCββββββββββ βEβββββββββββββββββ
+ // . β β β β β β β β€ β β β β
+ // . β β ββββββββββββ β β
+ // . ββββββββββββββββ βDββββββββββ β β β β β β β β β β€
+ // . βBββββββββββββββ β β β β
+ // . β β β β β β
+ // . β β β β β β
+ // . β β β β β β
+ // . ββββββββββββββββ ββββββββββββ βββββββββββββββββββ
+ for i, column := range layout {
+ colHeight := colHeights[i]
+ if colHeight == maxY {
+ continue
+ }
+ delta := maxY - colHeight
+ objects := []*d2graph.Object{}
+ var tallest float64
+ for _, o := range column {
+ tallest = math.Max(tallest, o.Height)
+ objects = append(objects, o)
+ }
+ sort.Slice(objects, func(i, j int) bool {
+ return objects[i].Height < objects[j].Height
+ })
+ // expand smaller objects to fill remaining space
+ for _, o := range objects {
+ if o.Height < tallest {
+ var index int
+ for i, colObj := range column {
+ if o == colObj {
+ index = i
+ break
+ }
+ }
+ grow := math.Min(tallest-o.Height, delta)
+ o.Height += grow
+ // shift following objects
+ for i := index + 1; i < len(column); i++ {
+ column[i].TopLeft.Y += grow
+ }
+ delta -= grow
+ if delta <= 0 {
+ break
+ }
+ }
+ }
+ if delta > 0 {
+ grow := delta / float64(len(column))
+ for i := len(column) - 1; i >= 0; i-- {
+ o := column[i]
+ o.TopLeft.Y += grow * float64(i)
+ o.Height += grow
+ delta -= grow
+ }
+ }
+ }
+ }
+ gd.width = maxX
+ gd.height = maxY
+}
+
+// generate the best layout of objects aiming for each row to be the targetSize width
+// if columns is true, each column aims to have the targetSize height
+func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2graph.Object {
+ var nCuts int
+ if columns {
+ nCuts = gd.columns - 1
+ } else {
+ nCuts = gd.rows - 1
+ }
+ if nCuts == 0 {
+ return genLayout(gd.objects, nil)
+ }
+
+ // get all options for where to place these cuts, preferring later cuts over earlier cuts
+ // with 5 objects and 2 cuts we have these options:
+ // . A B C β D β E <- these cuts would produce: βAββ βBββ βCββ
+ // . A B β C D β E ββββ ββββ ββββ
+ // . A β B C D β E βDββββββββββββ
+ // . A B β C β D E ββββββββββββββ
+ // . A β B C β D E βEββββββββββββ
+ // . A β B β C D E ββββββββββββββ
+ divisions := genDivisions(gd.objects, nCuts)
+
+ var bestLayout [][]*d2graph.Object
+ bestDist := math.MaxFloat64
+ // of these divisions, find the layout with rows closest to the targetSize
+ for _, division := range divisions {
+ layout := genLayout(gd.objects, division)
+ dist := getDistToTarget(layout, targetSize, columns)
+ if dist < bestDist {
+ bestLayout = layout
+ bestDist = dist
+ }
+ }
+
+ return bestLayout
+}
+
+// get all possible divisions of objects by the number of cuts
+func genDivisions(objects []*d2graph.Object, nCuts int) (divisions [][]int) {
+ if len(objects) < 2 || nCuts == 0 {
+ return nil
+ }
+ // we go in this order to prefer extra objects in starting rows rather than later ones
+ lastObj := len(objects) - 1
+ for index := lastObj; index >= nCuts; index-- {
+ if nCuts > 1 {
+ for _, inner := range genDivisions(objects[:index], nCuts-1) {
+ divisions = append(divisions, append(inner, index-1))
+ }
+ } else {
+ divisions = append(divisions, []int{index - 1})
+ }
+ }
+
+ return divisions
+}
+
+// generate a grid of objects from the given cut indices
+func genLayout(objects []*d2graph.Object, cutIndices []int) [][]*d2graph.Object {
+ layout := make([][]*d2graph.Object, len(cutIndices)+1)
+ objIndex := 0
+ for i := 0; i <= len(cutIndices); i++ {
+ var stop int
+ if i < len(cutIndices) {
+ stop = cutIndices[i]
+ } else {
+ stop = len(objects) - 1
+ }
+ for ; objIndex <= stop; objIndex++ {
+ layout[i] = append(layout[i], objects[objIndex])
+ }
+ }
+ return layout
+}
+
+func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, columns bool) float64 {
+ totalDelta := 0.
+ for _, row := range layout {
+ rowSize := 0.
+ for _, o := range row {
+ if columns {
+ rowSize += o.Height + VERTICAL_PAD
+ } else {
+ rowSize += o.Width + HORIZONTAL_PAD
+ }
+ }
+ totalDelta += math.Abs(rowSize - targetSize)
+ }
+ return totalDelta
+}
+
+// cleanup restores the graph after the core layout engine finishes
+// - translating the grid to its position placed by the core layout engine
+// - restore the children of the grid
+// - sorts objects to their original graph order
+func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objectsOrder map[string]int) {
+ defer func() {
+ sort.SliceStable(graph.Objects, func(i, j int) bool {
+ return objectsOrder[graph.Objects[i].AbsID()] < objectsOrder[graph.Objects[j].AbsID()]
+ })
+ }()
+
+ if graph.Root.IsGridDiagram() {
+ gd, exists := gridDiagrams[graph.Root.AbsID()]
+ if exists {
+ gd.cleanup(graph.Root, graph)
+ return
+ }
+ }
+
+ for _, obj := range graph.Objects {
+ gd, exists := gridDiagrams[obj.AbsID()]
+ if !exists {
+ continue
+ }
+ obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
+ // shift the grid from (0, 0)
+ gd.shift(
+ obj.TopLeft.X+CONTAINER_PADDING,
+ obj.TopLeft.Y+CONTAINER_PADDING,
+ )
+ gd.cleanup(obj, graph)
+ }
+}
diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go
index 082a0e296..695fda827 100644
--- a/d2layouts/d2near/layout.go
+++ b/d2layouts/d2near/layout.go
@@ -34,7 +34,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNears []*d2graph.Obje
if processCenters == strings.Contains(d2graph.Key(obj.Attributes.NearKey)[0], "-center") {
// The z-index for constant nears does not matter, as it will not collide
g.Objects = append(g.Objects, obj)
- obj.Parent.Children[obj.ID] = obj
+ obj.Parent.Children[strings.ToLower(obj.ID)] = obj
obj.Parent.ChildrenArray = append(obj.Parent.ChildrenArray, obj)
}
}
diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go
index 28755f3e0..0da870f19 100644
--- a/d2layouts/d2sequence/layout.go
+++ b/d2layouts/d2sequence/layout.go
@@ -13,6 +13,33 @@ import (
"oss.terrastruct.com/d2/lib/label"
)
+// Layout runs the sequence diagram layout engine on objects of shape sequence_diagram
+//
+// 1. Traverse graph from root, skip objects with shape not `sequence_diagram`
+// 2. Construct a sequence diagram from all descendant objects and edges
+// 3. Remove those objects and edges from the main graph
+// 4. Run layout on sequence diagrams
+// 5. Set the resulting dimensions to the main graph shape
+// 6. Run core layouts (still without sequence diagram innards)
+// 7. Put back sequence diagram innards in correct location
+func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) error {
+ sequenceDiagrams, objectOrder, edgeOrder, err := WithoutSequenceDiagrams(ctx, g)
+ if err != nil {
+ return err
+ }
+
+ if g.Root.IsSequenceDiagram() {
+ // the sequence diagram is the only layout engine if the whole diagram is
+ // shape: sequence_diagram
+ g.Root.TopLeft = geo.NewPoint(0, 0)
+ } else if err := layout(ctx, g); err != nil {
+ return err
+ }
+
+ cleanup(g, sequenceDiagrams, objectOrder, edgeOrder)
+ return nil
+}
+
func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]*sequenceDiagram, map[string]int, map[string]int, error) {
objectsToRemove := make(map[*d2graph.Object]struct{})
edgesToRemove := make(map[*d2graph.Edge]struct{})
@@ -69,33 +96,6 @@ func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]
return sequenceDiagrams, objectOrder, edgeOrder, nil
}
-// Layout runs the sequence diagram layout engine on objects of shape sequence_diagram
-//
-// 1. Traverse graph from root, skip objects with shape not `sequence_diagram`
-// 2. Construct a sequence diagram from all descendant objects and edges
-// 3. Remove those objects and edges from the main graph
-// 4. Run layout on sequence diagrams
-// 5. Set the resulting dimensions to the main graph shape
-// 6. Run core layouts (still without sequence diagram innards)
-// 7. Put back sequence diagram innards in correct location
-func Layout(ctx context.Context, g *d2graph.Graph, layout func(ctx context.Context, g *d2graph.Graph) error) error {
- sequenceDiagrams, objectOrder, edgeOrder, err := WithoutSequenceDiagrams(ctx, g)
- if err != nil {
- return err
- }
-
- if g.Root.IsSequenceDiagram() {
- // the sequence diagram is the only layout engine if the whole diagram is
- // shape: sequence_diagram
- g.Root.TopLeft = geo.NewPoint(0, 0)
- } else if err := layout(ctx, g); err != nil {
- return err
- }
-
- cleanup(g, sequenceDiagrams, objectOrder, edgeOrder)
- return nil
-}
-
// layoutSequenceDiagram finds the edges inside the sequence diagram and performs the layout on the object descendants
func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) (*sequenceDiagram, error) {
var edges []*d2graph.Edge
@@ -154,11 +154,11 @@ func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, obj
objects = g.Objects
}
for _, obj := range objects {
- if _, exists := sequenceDiagrams[obj.AbsID()]; !exists {
+ sd, exists := sequenceDiagrams[obj.AbsID()]
+ if !exists {
continue
}
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
- sd := sequenceDiagrams[obj.AbsID()]
// shift the sequence diagrams as they are always placed at (0, 0) with some padding
sd.shift(
@@ -171,22 +171,22 @@ func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, obj
obj.Children = make(map[string]*d2graph.Object)
obj.ChildrenArray = make([]*d2graph.Object, 0)
for _, child := range sd.actors {
- obj.Children[child.ID] = child
+ obj.Children[strings.ToLower(child.ID)] = child
obj.ChildrenArray = append(obj.ChildrenArray, child)
}
for _, child := range sd.groups {
if child.Parent.AbsID() == obj.AbsID() {
- obj.Children[child.ID] = child
+ obj.Children[strings.ToLower(child.ID)] = child
obj.ChildrenArray = append(obj.ChildrenArray, child)
}
}
- g.Edges = append(g.Edges, sequenceDiagrams[obj.AbsID()].messages...)
- g.Edges = append(g.Edges, sequenceDiagrams[obj.AbsID()].lifelines...)
- g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].actors...)
- g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].notes...)
- g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].groups...)
- g.Objects = append(g.Objects, sequenceDiagrams[obj.AbsID()].spans...)
+ g.Edges = append(g.Edges, sd.messages...)
+ g.Edges = append(g.Edges, sd.lifelines...)
+ g.Objects = append(g.Objects, sd.actors...)
+ g.Objects = append(g.Objects, sd.notes...)
+ g.Objects = append(g.Objects, sd.groups...)
+ g.Objects = append(g.Objects, sd.spans...)
}
// no new objects, so just keep the same position
diff --git a/d2lib/d2.go b/d2lib/d2.go
index 060204ea9..11638833a 100644
--- a/d2lib/d2.go
+++ b/d2lib/d2.go
@@ -10,6 +10,7 @@ import (
"oss.terrastruct.com/d2/d2exporter"
"oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
+ "oss.terrastruct.com/d2/d2layouts/d2grid"
"oss.terrastruct.com/d2/d2layouts/d2near"
"oss.terrastruct.com/d2/d2layouts/d2sequence"
"oss.terrastruct.com/d2/d2renderers/d2fonts"
@@ -70,7 +71,9 @@ func compile(ctx context.Context, g *d2graph.Graph, opts *CompileOptions) (*d2ta
constantNears := d2near.WithoutConstantNears(ctx, g)
- err = d2sequence.Layout(ctx, g, coreLayout)
+ layoutWithGrids := d2grid.Layout(ctx, g, coreLayout)
+
+ err = d2sequence.Layout(ctx, g, layoutWithGrids)
if err != nil {
return nil, err
}
@@ -110,7 +113,7 @@ func compile(ctx context.Context, g *d2graph.Graph, opts *CompileOptions) (*d2ta
return d, nil
}
-func getLayout(opts *CompileOptions) (func(context.Context, *d2graph.Graph) error, error) {
+func getLayout(opts *CompileOptions) (d2graph.LayoutGraph, error) {
if opts.Layout != nil {
return opts.Layout, nil
} else if os.Getenv("D2_LAYOUT") == "dagre" {
diff --git a/d2oracle/edit.go b/d2oracle/edit.go
index 668b6d4a0..58aaab1b6 100644
--- a/d2oracle/edit.go
+++ b/d2oracle/edit.go
@@ -314,6 +314,16 @@ func _set(g *d2graph.Graph, key string, tag, value *string) error {
attrs.Left.MapKey.SetScalar(mk.Value.ScalarBox())
return nil
}
+ case "grid-rows":
+ if attrs.GridRows != nil && attrs.GridRows.MapKey != nil {
+ attrs.GridRows.MapKey.SetScalar(mk.Value.ScalarBox())
+ return nil
+ }
+ case "grid-columns":
+ if attrs.GridColumns != nil && attrs.GridColumns.MapKey != nil {
+ attrs.GridColumns.MapKey.SetScalar(mk.Value.ScalarBox())
+ return nil
+ }
case "source-arrowhead", "target-arrowhead":
if reservedKey == "source-arrowhead" {
attrs = edge.SrcArrowhead
diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go
index 14d123267..274ec7e1b 100644
--- a/e2etests/stable_test.go
+++ b/e2etests/stable_test.go
@@ -2471,6 +2471,10 @@ scenarios: {
}`,
},
loadFromFile(t, "arrowhead_scaling"),
+ loadFromFile(t, "teleport_grid"),
+ loadFromFile(t, "dagger_grid"),
+ loadFromFile(t, "grid_tests"),
+ loadFromFile(t, "executive_grid"),
}
runa(t, tcs)
diff --git a/e2etests/testdata/files/dagger_grid.d2 b/e2etests/testdata/files/dagger_grid.d2
new file mode 100644
index 000000000..2f6167c06
--- /dev/null
+++ b/e2etests/testdata/files/dagger_grid.d2
@@ -0,0 +1,90 @@
+grid-rows: 5
+style.fill: black
+
+flow1: "" {
+ width: 120
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow2: "" {
+ width: 120
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow3: "" {
+ width: 120
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow4: "" {
+ width: 120
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow5: "" {
+ width: 120
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow6: "" {
+ width: 240
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow7: "" {
+ width: 80
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow8: "" {
+ width: 160
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+flow9: "" {
+ width: 160
+ style: {fill: white; stroke: cornflowerblue; stroke-width: 10}
+}
+
+DAGGER ENGINE: {
+ width: 800
+ style: {
+ fill: beige
+ stroke: darkcyan
+ font-color: blue
+ stroke-width: 8
+ }
+}
+
+ANY DOCKER COMPATIBLE RUNTIME: {
+ width: 800
+ style: {
+ fill: lightcyan
+ stroke: darkcyan
+ font-color: black
+ stroke-width: 8
+ }
+ icon: https://icons.terrastruct.com/dev%2Fdocker.svg
+}
+
+ANY CI: {
+ style: {
+ fill: gold
+ stroke: maroon
+ font-color: maroon
+ stroke-width: 8
+ }
+}
+
+WINDOWS.style: {
+ font-color: white
+ fill: darkcyan
+ stroke: black
+}
+LINUX.style: {
+ font-color: white
+ fill: darkcyan
+ stroke: black
+}
+MACOS.style: {
+ font-color: white
+ fill: darkcyan
+ stroke: black
+}
+KUBERNETES.style: {
+ font-color: white
+ fill: darkcyan
+ stroke: black
+}
diff --git a/e2etests/testdata/files/executive_grid.d2 b/e2etests/testdata/files/executive_grid.d2
new file mode 100644
index 000000000..a5178fbd6
--- /dev/null
+++ b/e2etests/testdata/files/executive_grid.d2
@@ -0,0 +1,16 @@
+grid-rows: 3
+
+Executive Services.width: 1000
+
+I/O\nManager.width: 100
+I/O\nManager.height: 200
+Security\nReference\nMonitor.width: 100
+IPC\nManager.width: 100
+Virtual\nMemory\nManager\n(VMM).width: 100
+Process\nManager.width: 100
+PnP\nManager.width: 100
+Power\nManager.width: 100
+# TODO recursive grids
+Window\nManager\n\nGDI.width: 100
+
+Object Manager.width: 1000
diff --git a/e2etests/testdata/files/grid_tests.d2 b/e2etests/testdata/files/grid_tests.d2
new file mode 100644
index 000000000..aab1481e9
--- /dev/null
+++ b/e2etests/testdata/files/grid_tests.d2
@@ -0,0 +1,134 @@
+rows 1: {
+ grid-rows: 1
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+columns 1: {
+ grid-columns: 1
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+rows 2: {
+ grid-rows: 2
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+columns 2: {
+ grid-columns: 2
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+rows 2 columns 2: {
+ grid-rows: 2
+ grid-columns: 2
+
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+columns 2 rows 2: {
+ grid-columns: 2
+ grid-rows: 2
+
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+rows 3 columns 3: {
+ grid-rows: 3
+ grid-columns: 3
+
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+columns 3 rows 3: {
+ grid-columns: 3
+ grid-rows: 3
+
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+rows 3: {
+ grid-rows: 3
+
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+columns 3: {
+ grid-columns: 3
+
+ a
+ b
+ c
+ d
+ e
+ f
+ g
+}
+
+widths heights: {
+ grid-rows: 3
+ grid-columns: 3
+
+ a w200.width: 200
+ b h300.height: 300
+ c
+ d h200.height: 200
+ e
+ f w400.width: 400
+ g
+ h
+ i
+}
diff --git a/e2etests/testdata/files/teleport_grid.d2 b/e2etests/testdata/files/teleport_grid.d2
new file mode 100644
index 000000000..d0e737513
--- /dev/null
+++ b/e2etests/testdata/files/teleport_grid.d2
@@ -0,0 +1,70 @@
+direction: right
+
+users -- via -- teleport
+
+teleport -> jita: "all connections audited and logged"
+teleport -> infra
+
+teleport -> identity provider
+teleport <- identity provider
+
+users: "" {
+ grid-columns: 1
+
+ Engineers: {
+ shape: circle
+ icon: https://icons.terrastruct.com/essentials%2F365-user.svg
+ }
+ Machines: {
+ shape: circle
+ icon: https://icons.terrastruct.com/aws%2FCompute%2FCompute.svg
+ }
+}
+
+via: "" {
+ grid-columns: 1
+
+ https: "HTTPS://"
+ kubectl: "> kubectl"
+ tsh: "> tsh"
+ api: "> api"
+ db clients: "DB Clients"
+}
+
+teleport: Teleport {
+ grid-rows: 2
+
+ inp: |md
+ # Identity Native Proxy
+ | {
+ width: 300
+ }
+
+ Audit Log.icon: https://icons.terrastruct.com/tech%2Flaptop.svg
+ Cert Authority.icon: https://icons.terrastruct.com/azure%2FWeb%20Service%20Color%2FApp%20Service%20Certificates.svg
+}
+
+jita: "Just-in-time Access via" {
+ grid-rows: 1
+
+ Slack.icon: https://icons.terrastruct.com/dev%2Fslack.svg
+ Mattermost
+ Jira
+ Pagerduty
+ Email.icon: https://icons.terrastruct.com/aws%2F_General%2FAWS-Email_light-bg.svg
+}
+
+infra: Infrastructure {
+ grid-rows: 2
+
+ ssh.icon: https://icons.terrastruct.com/essentials%2F112-server.svg
+ Kubernetes.icon: https://icons.terrastruct.com/azure%2F_Companies%2FKubernetes.svg
+ My SQL.icon: https://icons.terrastruct.com/dev%2Fmysql.svg
+ MongoDB.icon: https://icons.terrastruct.com/dev%2Fmongodb.svg
+ PSQL.icon: https://icons.terrastruct.com/dev%2Fpostgresql.svg
+ Windows.icon: https://icons.terrastruct.com/dev%2Fwindows.svg
+}
+
+identity provider: Indentity Provider {
+ icon: https://icons.terrastruct.com/azure%2FIdentity%20Service%20Color%2FIdentity%20governance.svg
+}
diff --git a/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json
new file mode 100644
index 000000000..b94be0069
--- /dev/null
+++ b/e2etests/testdata/stable/dagger_grid/dagre/board.exp.json
@@ -0,0 +1,716 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "flow1",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow2",
+ "type": "rectangle",
+ "pos": {
+ "x": 168,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow3",
+ "type": "rectangle",
+ "pos": {
+ "x": 336,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow4",
+ "type": "rectangle",
+ "pos": {
+ "x": 504,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow5",
+ "type": "rectangle",
+ "pos": {
+ "x": 672,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow6",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 140
+ },
+ "width": 240,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow7",
+ "type": "rectangle",
+ "pos": {
+ "x": 280,
+ "y": 140
+ },
+ "width": 120,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow8",
+ "type": "rectangle",
+ "pos": {
+ "x": 440,
+ "y": 140
+ },
+ "width": 160,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow9",
+ "type": "rectangle",
+ "pos": {
+ "x": 640,
+ "y": 140
+ },
+ "width": 160,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "DAGGER ENGINE",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 280
+ },
+ "width": 800,
+ "height": 61,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 8,
+ "borderRadius": 0,
+ "fill": "beige",
+ "stroke": "darkcyan",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "DAGGER ENGINE",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "blue",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 114,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "ANY DOCKER COMPATIBLE RUNTIME",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 381
+ },
+ "width": 800,
+ "height": 87,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 8,
+ "borderRadius": 0,
+ "fill": "lightcyan",
+ "stroke": "darkcyan",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/docker.svg",
+ "RawPath": "/dev%2Fdocker.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "ANY DOCKER COMPATIBLE RUNTIME",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "black",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 255,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "ANY CI",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 508
+ },
+ "width": 139,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 8,
+ "borderRadius": 0,
+ "fill": "gold",
+ "stroke": "maroon",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "ANY CI",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "maroon",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 46,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "WINDOWS",
+ "type": "rectangle",
+ "pos": {
+ "x": 179,
+ "y": 508
+ },
+ "width": 117,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "WINDOWS",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 72,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "LINUX",
+ "type": "rectangle",
+ "pos": {
+ "x": 336,
+ "y": 508
+ },
+ "width": 139,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "LINUX",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 43,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "MACOS",
+ "type": "rectangle",
+ "pos": {
+ "x": 515,
+ "y": 508
+ },
+ "width": 106,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "MACOS",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 50,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "KUBERNETES",
+ "type": "rectangle",
+ "pos": {
+ "x": 661,
+ "y": 508
+ },
+ "width": 139,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "KUBERNETES",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 94,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ }
+ ],
+ "connections": [],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "black",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg
new file mode 100644
index 000000000..cc62b273b
--- /dev/null
+++ b/e2etests/testdata/stable/dagger_grid/dagre/sketch.exp.svg
@@ -0,0 +1,95 @@
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/dagger_grid/elk/board.exp.json b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json
new file mode 100644
index 000000000..b94be0069
--- /dev/null
+++ b/e2etests/testdata/stable/dagger_grid/elk/board.exp.json
@@ -0,0 +1,716 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "flow1",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow2",
+ "type": "rectangle",
+ "pos": {
+ "x": 168,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow3",
+ "type": "rectangle",
+ "pos": {
+ "x": 336,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow4",
+ "type": "rectangle",
+ "pos": {
+ "x": 504,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow5",
+ "type": "rectangle",
+ "pos": {
+ "x": 672,
+ "y": 0
+ },
+ "width": 128,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow6",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 140
+ },
+ "width": 240,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow7",
+ "type": "rectangle",
+ "pos": {
+ "x": 280,
+ "y": 140
+ },
+ "width": 120,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow8",
+ "type": "rectangle",
+ "pos": {
+ "x": 440,
+ "y": 140
+ },
+ "width": 160,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "flow9",
+ "type": "rectangle",
+ "pos": {
+ "x": 640,
+ "y": 140
+ },
+ "width": 160,
+ "height": 100,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 10,
+ "borderRadius": 0,
+ "fill": "white",
+ "stroke": "cornflowerblue",
+ "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": true,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "DAGGER ENGINE",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 280
+ },
+ "width": 800,
+ "height": 61,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 8,
+ "borderRadius": 0,
+ "fill": "beige",
+ "stroke": "darkcyan",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "DAGGER ENGINE",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "blue",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 114,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "ANY DOCKER COMPATIBLE RUNTIME",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 381
+ },
+ "width": 800,
+ "height": 87,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 8,
+ "borderRadius": 0,
+ "fill": "lightcyan",
+ "stroke": "darkcyan",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/docker.svg",
+ "RawPath": "/dev%2Fdocker.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "ANY DOCKER COMPATIBLE RUNTIME",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "black",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 255,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "ANY CI",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 508
+ },
+ "width": 139,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 8,
+ "borderRadius": 0,
+ "fill": "gold",
+ "stroke": "maroon",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "ANY CI",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "maroon",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 46,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "WINDOWS",
+ "type": "rectangle",
+ "pos": {
+ "x": 179,
+ "y": 508
+ },
+ "width": 117,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "WINDOWS",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 72,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "LINUX",
+ "type": "rectangle",
+ "pos": {
+ "x": 336,
+ "y": 508
+ },
+ "width": 139,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "LINUX",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 43,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "MACOS",
+ "type": "rectangle",
+ "pos": {
+ "x": 515,
+ "y": 508
+ },
+ "width": 106,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "MACOS",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 50,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "KUBERNETES",
+ "type": "rectangle",
+ "pos": {
+ "x": 661,
+ "y": 508
+ },
+ "width": 139,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "darkcyan",
+ "stroke": "black",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "KUBERNETES",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "white",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 94,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ }
+ ],
+ "connections": [],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "black",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg
new file mode 100644
index 000000000..cc62b273b
--- /dev/null
+++ b/e2etests/testdata/stable/dagger_grid/elk/sketch.exp.svg
@@ -0,0 +1,95 @@
+DAGGER ENGINEANY DOCKER COMPATIBLE RUNTIMEANY CIWINDOWSLINUXMACOSKUBERNETES
+
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/executive_grid/dagre/board.exp.json b/e2etests/testdata/stable/executive_grid/dagre/board.exp.json
new file mode 100644
index 000000000..6ec7a989f
--- /dev/null
+++ b/e2etests/testdata/stable/executive_grid/dagre/board.exp.json
@@ -0,0 +1,458 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "Executive Services",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 1080,
+ "height": 61,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Executive Services",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 131,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"I/O\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "I/O\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Security\\nReference\\nMonitor\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 140,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Security\nReference\nMonitor",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 72,
+ "labelHeight": 53,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"IPC\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 280,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "IPC\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Virtual\\nMemory\\nManager\\n(VMM)\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 420,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Virtual\nMemory\nManager\n(VMM)",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 64,
+ "labelHeight": 69,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Process\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 560,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Process\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"PnP\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 700,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "PnP\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Power\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 840,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Power\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Window\\nManager\\n\\nGDI\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 980,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Window\nManager\n\nGDI",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 63,
+ "labelHeight": 69,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "Object Manager",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 341
+ },
+ "width": 1080,
+ "height": 61,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Object Manager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 112,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ }
+ ],
+ "connections": [],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg
new file mode 100644
index 000000000..8b27b5168
--- /dev/null
+++ b/e2etests/testdata/stable/executive_grid/dagre/sketch.exp.svg
@@ -0,0 +1,95 @@
+Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager
+
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/executive_grid/elk/board.exp.json b/e2etests/testdata/stable/executive_grid/elk/board.exp.json
new file mode 100644
index 000000000..6ec7a989f
--- /dev/null
+++ b/e2etests/testdata/stable/executive_grid/elk/board.exp.json
@@ -0,0 +1,458 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "Executive Services",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 1080,
+ "height": 61,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Executive Services",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 131,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"I/O\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "I/O\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Security\\nReference\\nMonitor\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 140,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Security\nReference\nMonitor",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 72,
+ "labelHeight": 53,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"IPC\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 280,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "IPC\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Virtual\\nMemory\\nManager\\n(VMM)\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 420,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Virtual\nMemory\nManager\n(VMM)",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 64,
+ "labelHeight": 69,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Process\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 560,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Process\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"PnP\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 700,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "PnP\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Power\\nManager\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 840,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Power\nManager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 37,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "\"Window\\nManager\\n\\nGDI\"",
+ "type": "rectangle",
+ "pos": {
+ "x": 980,
+ "y": 101
+ },
+ "width": 100,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Window\nManager\n\nGDI",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 63,
+ "labelHeight": 69,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "Object Manager",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 341
+ },
+ "width": 1080,
+ "height": 61,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "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": "Object Manager",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 112,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 1
+ }
+ ],
+ "connections": [],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg
new file mode 100644
index 000000000..8b27b5168
--- /dev/null
+++ b/e2etests/testdata/stable/executive_grid/elk/sketch.exp.svg
@@ -0,0 +1,95 @@
+Executive ServicesI/OManagerSecurityReferenceMonitorIPCManagerVirtualMemoryManager(VMM)ProcessManagerPnPManagerPowerManagerWindowManager GDIObject Manager
+
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/grid_tests/dagre/board.exp.json b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json
new file mode 100644
index 000000000..15c3df149
--- /dev/null
+++ b/e2etests/testdata/stable/grid_tests/dagre/board.exp.json
@@ -0,0 +1,3738 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "rows 1",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 318
+ },
+ "width": 731,
+ "height": 186,
+ "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": "rows 1",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 1.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 60,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 153,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 246,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 339,
+ "y": 378
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 433,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 526,
+ "y": 378
+ },
+ "width": 51,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 617,
+ "y": 378
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1",
+ "type": "rectangle",
+ "pos": {
+ "x": 791,
+ "y": 0
+ },
+ "width": 174,
+ "height": 822,
+ "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": "columns 1",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 119,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 1.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 60
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 166
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 272
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 378
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 484
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 590
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 851,
+ "y": 696
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 1025,
+ "y": 265
+ },
+ "width": 452,
+ "height": 292,
+ "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": "rows 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 1085,
+ "y": 325
+ },
+ "width": 84,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 1209,
+ "y": 325
+ },
+ "width": 84,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 1333,
+ "y": 325
+ },
+ "width": 84,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 1085,
+ "y": 431
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 1179,
+ "y": 431
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 1272,
+ "y": 431
+ },
+ "width": 51,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 1363,
+ "y": 431
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 1537,
+ "y": 159
+ },
+ "width": 268,
+ "height": 504,
+ "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": "columns 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 119,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 1597,
+ "y": 219
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 1597,
+ "y": 325
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 1597,
+ "y": 431
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 1597,
+ "y": 537
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 1691,
+ "y": 219
+ },
+ "width": 54,
+ "height": 101,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 1691,
+ "y": 360
+ },
+ "width": 54,
+ "height": 101,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 1691,
+ "y": 501
+ },
+ "width": 54,
+ "height": 101,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 1865,
+ "y": 159
+ },
+ "width": 268,
+ "height": 504,
+ "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": "rows 2 columns 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 200,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 2 columns 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 1925,
+ "y": 219
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 2019,
+ "y": 219
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 1925,
+ "y": 325
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 2019,
+ "y": 325
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 1925,
+ "y": 431
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 2019,
+ "y": 431
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 1925,
+ "y": 537
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 2193,
+ "y": 265
+ },
+ "width": 454,
+ "height": 292,
+ "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": "columns 2 rows 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 201,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 2 rows 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 2253,
+ "y": 325
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 2253,
+ "y": 431
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 2346,
+ "y": 325
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 2346,
+ "y": 431
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 2440,
+ "y": 325
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 2440,
+ "y": 431
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 2533,
+ "y": 325
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 2707,
+ "y": 212
+ },
+ "width": 360,
+ "height": 398,
+ "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": "rows 3 columns 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 200,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 3 columns 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 2767,
+ "y": 272
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 2861,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 2954,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 2767,
+ "y": 378
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 2861,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 2954,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 2767,
+ "y": 484
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 3127,
+ "y": 212
+ },
+ "width": 361,
+ "height": 398,
+ "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": "columns 3 rows 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 201,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 3 rows 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 3187,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 3187,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 3187,
+ "y": 484
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 3280,
+ "y": 272
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 3280,
+ "y": 378
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 3280,
+ "y": 484
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 3374,
+ "y": 272
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 3548,
+ "y": 212
+ },
+ "width": 359,
+ "height": 398,
+ "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": "rows 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 3608,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 3701,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 3794,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 3608,
+ "y": 378
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 3747,
+ "y": 378
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 3608,
+ "y": 484
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 3747,
+ "y": 484
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 3967,
+ "y": 212
+ },
+ "width": 361,
+ "height": 398,
+ "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": "columns 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 119,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 4027,
+ "y": 272
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 4027,
+ "y": 378
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 4027,
+ "y": 484
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 4120,
+ "y": 272
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 4120,
+ "y": 431
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 4214,
+ "y": 272
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 4214,
+ "y": 431
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights",
+ "type": "rectangle",
+ "pos": {
+ "x": 4388,
+ "y": 28
+ },
+ "width": 886,
+ "height": 766,
+ "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": "widths heights",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 171,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "widths heights.a w200",
+ "type": "rectangle",
+ "pos": {
+ "x": 4448,
+ "y": 88
+ },
+ "width": 200,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a w200",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 49,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.b h300",
+ "type": "rectangle",
+ "pos": {
+ "x": 4688,
+ "y": 88
+ },
+ "width": 86,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b h300",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 46,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 4814,
+ "y": 88
+ },
+ "width": 400,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.d h200",
+ "type": "rectangle",
+ "pos": {
+ "x": 4448,
+ "y": 428
+ },
+ "width": 200,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d h200",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 47,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 4688,
+ "y": 428
+ },
+ "width": 86,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.f w400",
+ "type": "rectangle",
+ "pos": {
+ "x": 4814,
+ "y": 428
+ },
+ "width": 400,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f w400",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 46,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 4448,
+ "y": 668
+ },
+ "width": 200,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.h",
+ "type": "rectangle",
+ "pos": {
+ "x": 4688,
+ "y": 668
+ },
+ "width": 86,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "h",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.i",
+ "type": "rectangle",
+ "pos": {
+ "x": 4814,
+ "y": 668
+ },
+ "width": 400,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "i",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 4,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ }
+ ],
+ "connections": [],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg
new file mode 100644
index 000000000..4f6c4484f
--- /dev/null
+++ b/e2etests/testdata/stable/grid_tests/dagre/sketch.exp.svg
@@ -0,0 +1,102 @@
+rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi
+
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/grid_tests/elk/board.exp.json b/e2etests/testdata/stable/grid_tests/elk/board.exp.json
new file mode 100644
index 000000000..95b4c1c12
--- /dev/null
+++ b/e2etests/testdata/stable/grid_tests/elk/board.exp.json
@@ -0,0 +1,3738 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "rows 1",
+ "type": "rectangle",
+ "pos": {
+ "x": 12,
+ "y": 330
+ },
+ "width": 731,
+ "height": 186,
+ "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": "rows 1",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 1.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 72,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 165,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 258,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 351,
+ "y": 390
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 445,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 538,
+ "y": 390
+ },
+ "width": 51,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 1.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 629,
+ "y": 390
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1",
+ "type": "rectangle",
+ "pos": {
+ "x": 763,
+ "y": 12
+ },
+ "width": 174,
+ "height": 822,
+ "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": "columns 1",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 119,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 1.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 72
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 178
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 284
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 390
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 496
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 602
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 1.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 823,
+ "y": 708
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 957,
+ "y": 277
+ },
+ "width": 452,
+ "height": 292,
+ "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": "rows 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 1017,
+ "y": 337
+ },
+ "width": 84,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 1141,
+ "y": 337
+ },
+ "width": 84,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 1265,
+ "y": 337
+ },
+ "width": 84,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 1017,
+ "y": 443
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 1111,
+ "y": 443
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 1204,
+ "y": 443
+ },
+ "width": 51,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 1295,
+ "y": 443
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 1429,
+ "y": 171
+ },
+ "width": 268,
+ "height": 504,
+ "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": "columns 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 119,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 1489,
+ "y": 231
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 1489,
+ "y": 337
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 1489,
+ "y": 443
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 1489,
+ "y": 549
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 1583,
+ "y": 231
+ },
+ "width": 54,
+ "height": 101,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 1583,
+ "y": 372
+ },
+ "width": 54,
+ "height": 101,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 1583,
+ "y": 513
+ },
+ "width": 54,
+ "height": 101,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 1717,
+ "y": 171
+ },
+ "width": 268,
+ "height": 504,
+ "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": "rows 2 columns 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 200,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 2 columns 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 1777,
+ "y": 231
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 1871,
+ "y": 231
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 1777,
+ "y": 337
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 1871,
+ "y": 337
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 1777,
+ "y": 443
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 1871,
+ "y": 443
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 2 columns 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 1777,
+ "y": 549
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2",
+ "type": "rectangle",
+ "pos": {
+ "x": 2005,
+ "y": 277
+ },
+ "width": 454,
+ "height": 292,
+ "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": "columns 2 rows 2",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 201,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 2 rows 2.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 2065,
+ "y": 337
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 2065,
+ "y": 443
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 2158,
+ "y": 337
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 2158,
+ "y": 443
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 2252,
+ "y": 337
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 2252,
+ "y": 443
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 2 rows 2.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 2345,
+ "y": 337
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 2479,
+ "y": 224
+ },
+ "width": 360,
+ "height": 398,
+ "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": "rows 3 columns 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 200,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 3 columns 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 2539,
+ "y": 284
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 2633,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 2726,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 2539,
+ "y": 390
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 2633,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 2726,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3 columns 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 2539,
+ "y": 496
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 2859,
+ "y": 224
+ },
+ "width": 361,
+ "height": 398,
+ "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": "columns 3 rows 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 201,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 3 rows 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 2919,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 2919,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 2919,
+ "y": 496
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 3012,
+ "y": 284
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 3012,
+ "y": 390
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 3012,
+ "y": 496
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3 rows 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 3106,
+ "y": 284
+ },
+ "width": 54,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 3240,
+ "y": 224
+ },
+ "width": 359,
+ "height": 398,
+ "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": "rows 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "rows 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 3300,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 3393,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 3486,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 3300,
+ "y": 390
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 3439,
+ "y": 390
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 3300,
+ "y": 496
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "rows 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 3439,
+ "y": 496
+ },
+ "width": 99,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3",
+ "type": "rectangle",
+ "pos": {
+ "x": 3619,
+ "y": 224
+ },
+ "width": 361,
+ "height": 398,
+ "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": "columns 3",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 119,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "columns 3.a",
+ "type": "rectangle",
+ "pos": {
+ "x": 3679,
+ "y": 284
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.b",
+ "type": "rectangle",
+ "pos": {
+ "x": 3679,
+ "y": 390
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 3679,
+ "y": 496
+ },
+ "width": 53,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.d",
+ "type": "rectangle",
+ "pos": {
+ "x": 3772,
+ "y": 284
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 3772,
+ "y": 443
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.f",
+ "type": "rectangle",
+ "pos": {
+ "x": 3866,
+ "y": 284
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 6,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "columns 3.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 3866,
+ "y": 443
+ },
+ "width": 54,
+ "height": 119,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights",
+ "type": "rectangle",
+ "pos": {
+ "x": 4000,
+ "y": 40
+ },
+ "width": 886,
+ "height": 766,
+ "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": "widths heights",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 171,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "widths heights.a w200",
+ "type": "rectangle",
+ "pos": {
+ "x": 4060,
+ "y": 100
+ },
+ "width": 200,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "a w200",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 49,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.b h300",
+ "type": "rectangle",
+ "pos": {
+ "x": 4300,
+ "y": 100
+ },
+ "width": 86,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "b h300",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 46,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.c",
+ "type": "rectangle",
+ "pos": {
+ "x": 4426,
+ "y": 100
+ },
+ "width": 400,
+ "height": 300,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "c",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.d h200",
+ "type": "rectangle",
+ "pos": {
+ "x": 4060,
+ "y": 440
+ },
+ "width": 200,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "d h200",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 47,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.e",
+ "type": "rectangle",
+ "pos": {
+ "x": 4300,
+ "y": 440
+ },
+ "width": 86,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "e",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.f w400",
+ "type": "rectangle",
+ "pos": {
+ "x": 4426,
+ "y": 440
+ },
+ "width": 400,
+ "height": 200,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "f w400",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 46,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.g",
+ "type": "rectangle",
+ "pos": {
+ "x": 4060,
+ "y": 680
+ },
+ "width": 200,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "g",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 9,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.h",
+ "type": "rectangle",
+ "pos": {
+ "x": 4300,
+ "y": 680
+ },
+ "width": 86,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "h",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 8,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "widths heights.i",
+ "type": "rectangle",
+ "pos": {
+ "x": 4426,
+ "y": 680
+ },
+ "width": 400,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "i",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 4,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ }
+ ],
+ "connections": [],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg
new file mode 100644
index 000000000..f85853334
--- /dev/null
+++ b/e2etests/testdata/stable/grid_tests/elk/sketch.exp.svg
@@ -0,0 +1,102 @@
+rows 1columns 1rows 2columns 2rows 2 columns 2columns 2 rows 2rows 3 columns 3columns 3 rows 3rows 3columns 3widths heightsabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefga w200b h300cd h200ef w400ghi
+
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json
new file mode 100644
index 000000000..6b5f7d1ad
--- /dev/null
+++ b/e2etests/testdata/stable/teleport_grid/dagre/board.exp.json
@@ -0,0 +1,1606 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "users",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 204
+ },
+ "width": 272,
+ "height": 461,
+ "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": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "via",
+ "type": "rectangle",
+ "pos": {
+ "x": 543,
+ "y": 130
+ },
+ "width": 236,
+ "height": 610,
+ "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": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "teleport",
+ "type": "rectangle",
+ "pos": {
+ "x": 1050,
+ "y": 283
+ },
+ "width": 473,
+ "height": 303,
+ "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": "Teleport",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 101,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "jita",
+ "type": "rectangle",
+ "pos": {
+ "x": 2025,
+ "y": 0
+ },
+ "width": 820,
+ "height": 212,
+ "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": "Just-in-time Access via",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 266,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "infra",
+ "type": "rectangle",
+ "pos": {
+ "x": 2144,
+ "y": 232
+ },
+ "width": 582,
+ "height": 344,
+ "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": "Infrastructure",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 160,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "identity provider",
+ "type": "rectangle",
+ "pos": {
+ "x": 2335,
+ "y": 596
+ },
+ "width": 201,
+ "height": 118,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/azure/Identity Service Color/Identity governance.svg",
+ "RawPath": "/azure%2FIdentity%20Service%20Color%2FIdentity%20governance.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Indentity Provider",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 130,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "users.Engineers",
+ "type": "oval",
+ "pos": {
+ "x": 60,
+ "y": 264
+ },
+ "width": 152,
+ "height": 152,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/essentials/365-user.svg",
+ "RawPath": "/essentials%2F365-user.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Engineers",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 69,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "users.Machines",
+ "type": "oval",
+ "pos": {
+ "x": 60,
+ "y": 456
+ },
+ "width": 152,
+ "height": 149,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/aws/Compute/Compute.svg",
+ "RawPath": "/aws%2FCompute%2FCompute.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Machines",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 66,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.https",
+ "type": "rectangle",
+ "pos": {
+ "x": 603,
+ "y": 190
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "HTTPS://",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.kubectl",
+ "type": "rectangle",
+ "pos": {
+ "x": 603,
+ "y": 296
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "> kubectl",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 66,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.tsh",
+ "type": "rectangle",
+ "pos": {
+ "x": 603,
+ "y": 402
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "> tsh",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 34,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.api",
+ "type": "rectangle",
+ "pos": {
+ "x": 603,
+ "y": 508
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "> api",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 34,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.db clients",
+ "type": "rectangle",
+ "pos": {
+ "x": 603,
+ "y": 614
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "DB Clients",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 71,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "teleport.inp",
+ "type": "text",
+ "pos": {
+ "x": 1110,
+ "y": 343
+ },
+ "width": 353,
+ "height": 51,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "transparent",
+ "stroke": "N1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "# Identity Native Proxy",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "markdown",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 302,
+ "labelHeight": 51,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "teleport.Audit Log",
+ "type": "rectangle",
+ "pos": {
+ "x": 1110,
+ "y": 434
+ },
+ "width": 140,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/tech/laptop.svg",
+ "RawPath": "/tech%2Flaptop.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Audit Log",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 69,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "teleport.Cert Authority",
+ "type": "rectangle",
+ "pos": {
+ "x": 1290,
+ "y": 434
+ },
+ "width": 173,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/azure/Web Service Color/App Service Certificates.svg",
+ "RawPath": "/azure%2FWeb%20Service%20Color%2FApp%20Service%20Certificates.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Cert Authority",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 102,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Slack",
+ "type": "rectangle",
+ "pos": {
+ "x": 2085,
+ "y": 60
+ },
+ "width": 110,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/slack.svg",
+ "RawPath": "/dev%2Fslack.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Slack",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 39,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Mattermost",
+ "type": "rectangle",
+ "pos": {
+ "x": 2235,
+ "y": 60
+ },
+ "width": 128,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "Mattermost",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 83,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Jira",
+ "type": "rectangle",
+ "pos": {
+ "x": 2403,
+ "y": 60
+ },
+ "width": 72,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "Jira",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 27,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Pagerduty",
+ "type": "rectangle",
+ "pos": {
+ "x": 2515,
+ "y": 60
+ },
+ "width": 119,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "Pagerduty",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Email",
+ "type": "rectangle",
+ "pos": {
+ "x": 2674,
+ "y": 60
+ },
+ "width": 111,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/aws/_General/AWS-Email_light-bg.svg",
+ "RawPath": "/aws%2F_General%2FAWS-Email_light-bg.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Email",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 40,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.ssh",
+ "type": "rectangle",
+ "pos": {
+ "x": 2204,
+ "y": 292
+ },
+ "width": 108,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/essentials/112-server.svg",
+ "RawPath": "/essentials%2F112-server.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "ssh",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 24,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.Kubernetes",
+ "type": "rectangle",
+ "pos": {
+ "x": 2352,
+ "y": 292
+ },
+ "width": 152,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/azure/_Companies/Kubernetes.svg",
+ "RawPath": "/azure%2F_Companies%2FKubernetes.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Kubernetes",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 81,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.My SQL",
+ "type": "rectangle",
+ "pos": {
+ "x": 2544,
+ "y": 292
+ },
+ "width": 122,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/mysql.svg",
+ "RawPath": "/dev%2Fmysql.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "My SQL",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 51,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.MongoDB",
+ "type": "rectangle",
+ "pos": {
+ "x": 2204,
+ "y": 424
+ },
+ "width": 138,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/mongodb.svg",
+ "RawPath": "/dev%2Fmongodb.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "MongoDB",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 67,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.PSQL",
+ "type": "rectangle",
+ "pos": {
+ "x": 2382,
+ "y": 424
+ },
+ "width": 108,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/postgresql.svg",
+ "RawPath": "/dev%2Fpostgresql.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "PSQL",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 37,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.Windows",
+ "type": "rectangle",
+ "pos": {
+ "x": 2530,
+ "y": 424
+ },
+ "width": 136,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/windows.svg",
+ "RawPath": "/dev%2Fwindows.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Windows",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 65,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ }
+ ],
+ "connections": [
+ {
+ "id": "(users -- via)[0]",
+ "src": "users",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "via",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 272,
+ "y": 434.5
+ },
+ {
+ "x": 380.4,
+ "y": 434.5
+ },
+ {
+ "x": 434.7,
+ "y": 434.5
+ },
+ {
+ "x": 543.5,
+ "y": 434.5
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(via -- teleport)[0]",
+ "src": "via",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "teleport",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 779,
+ "y": 434.5
+ },
+ {
+ "x": 887.4,
+ "y": 434.5
+ },
+ {
+ "x": 941.7,
+ "y": 434.5
+ },
+ {
+ "x": 1050.5,
+ "y": 434.5
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport -> jita)[0]",
+ "src": "teleport",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "jita",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "borderRadius": 10,
+ "label": "all connections audited and logged",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N2",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 231,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1511.3287671232877,
+ "y": 283
+ },
+ {
+ "x": 1721.4657534246576,
+ "y": 141.4
+ },
+ {
+ "x": 1824.2,
+ "y": 106
+ },
+ {
+ "x": 2025,
+ "y": 106
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport -> infra)[0]",
+ "src": "teleport",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "infra",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 1523,
+ "y": 419.70358974358976
+ },
+ {
+ "x": 1723.8,
+ "y": 407.14071794871796
+ },
+ {
+ "x": 1848,
+ "y": 404
+ },
+ {
+ "x": 2144,
+ "y": 404
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport -> identity provider)[0]",
+ "src": "teleport",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "identity provider",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 1523,
+ "y": 495.38358974358977
+ },
+ {
+ "x": 1723.8,
+ "y": 547.0767179487179
+ },
+ {
+ "x": 1886.1,
+ "y": 576.1111951588503
+ },
+ {
+ "x": 2334.5,
+ "y": 640.5559757942511
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport <- identity provider)[0]",
+ "src": "teleport",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "identity provider",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 1523,
+ "y": 556.2671794871795
+ },
+ {
+ "x": 1723.8,
+ "y": 659.6534358974359
+ },
+ {
+ "x": 1886.1,
+ "y": 680.3274583963691
+ },
+ {
+ "x": 2334.5,
+ "y": 659.6372919818457
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ }
+ ],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
new file mode 100644
index 000000000..1d2b16607
--- /dev/null
+++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
@@ -0,0 +1,852 @@
+TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB ClientsIdentity Native Proxy
+
Audit LogCert AuthoritySlackMattermostJiraEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged
+
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/teleport_grid/elk/board.exp.json b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json
new file mode 100644
index 000000000..3c2b5f426
--- /dev/null
+++ b/e2etests/testdata/stable/teleport_grid/elk/board.exp.json
@@ -0,0 +1,1576 @@
+{
+ "name": "",
+ "isFolderOnly": false,
+ "fontFamily": "SourceSansPro",
+ "shapes": [
+ {
+ "id": "users",
+ "type": "rectangle",
+ "pos": {
+ "x": 12,
+ "y": 196
+ },
+ "width": 272,
+ "height": 461,
+ "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": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "via",
+ "type": "rectangle",
+ "pos": {
+ "x": 354,
+ "y": 122
+ },
+ "width": 236,
+ "height": 610,
+ "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": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "teleport",
+ "type": "rectangle",
+ "pos": {
+ "x": 660,
+ "y": 275
+ },
+ "width": 473,
+ "height": 303,
+ "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": "Teleport",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 101,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "jita",
+ "type": "rectangle",
+ "pos": {
+ "x": 1915,
+ "y": 12
+ },
+ "width": 820,
+ "height": 212,
+ "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": "Just-in-time Access via",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 266,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "infra",
+ "type": "rectangle",
+ "pos": {
+ "x": 1263,
+ "y": 150
+ },
+ "width": 582,
+ "height": 344,
+ "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": "Infrastructure",
+ "fontSize": 28,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 160,
+ "labelHeight": 36,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "identity provider",
+ "type": "rectangle",
+ "pos": {
+ "x": 1263,
+ "y": 514
+ },
+ "width": 201,
+ "height": 118,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B6",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/azure/Identity Service Color/Identity governance.svg",
+ "RawPath": "/azure%2FIdentity%20Service%20Color%2FIdentity%20governance.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Indentity Provider",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 130,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 1
+ },
+ {
+ "id": "users.Engineers",
+ "type": "oval",
+ "pos": {
+ "x": 72,
+ "y": 256
+ },
+ "width": 152,
+ "height": 152,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/essentials/365-user.svg",
+ "RawPath": "/essentials%2F365-user.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Engineers",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 69,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "users.Machines",
+ "type": "oval",
+ "pos": {
+ "x": 72,
+ "y": 448
+ },
+ "width": 152,
+ "height": 149,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/aws/Compute/Compute.svg",
+ "RawPath": "/aws%2FCompute%2FCompute.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Machines",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 66,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.https",
+ "type": "rectangle",
+ "pos": {
+ "x": 414,
+ "y": 182
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "HTTPS://",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 62,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.kubectl",
+ "type": "rectangle",
+ "pos": {
+ "x": 414,
+ "y": 288
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "> kubectl",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 66,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.tsh",
+ "type": "rectangle",
+ "pos": {
+ "x": 414,
+ "y": 394
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "> tsh",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 34,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.api",
+ "type": "rectangle",
+ "pos": {
+ "x": 414,
+ "y": 500
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "> api",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 34,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "via.db clients",
+ "type": "rectangle",
+ "pos": {
+ "x": 414,
+ "y": 606
+ },
+ "width": 116,
+ "height": 66,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "DB Clients",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 71,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "teleport.inp",
+ "type": "text",
+ "pos": {
+ "x": 720,
+ "y": 335
+ },
+ "width": 353,
+ "height": 51,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "transparent",
+ "stroke": "N1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "# Identity Native Proxy",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "markdown",
+ "color": "N1",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 302,
+ "labelHeight": 51,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "teleport.Audit Log",
+ "type": "rectangle",
+ "pos": {
+ "x": 720,
+ "y": 426
+ },
+ "width": 140,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/tech/laptop.svg",
+ "RawPath": "/tech%2Flaptop.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Audit Log",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 69,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "teleport.Cert Authority",
+ "type": "rectangle",
+ "pos": {
+ "x": 900,
+ "y": 426
+ },
+ "width": 173,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/azure/Web Service Color/App Service Certificates.svg",
+ "RawPath": "/azure%2FWeb%20Service%20Color%2FApp%20Service%20Certificates.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Cert Authority",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 102,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Slack",
+ "type": "rectangle",
+ "pos": {
+ "x": 1975,
+ "y": 72
+ },
+ "width": 110,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/slack.svg",
+ "RawPath": "/dev%2Fslack.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Slack",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 39,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Mattermost",
+ "type": "rectangle",
+ "pos": {
+ "x": 2125,
+ "y": 72
+ },
+ "width": 128,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "Mattermost",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 83,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Jira",
+ "type": "rectangle",
+ "pos": {
+ "x": 2293,
+ "y": 72
+ },
+ "width": 72,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "Jira",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 27,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Pagerduty",
+ "type": "rectangle",
+ "pos": {
+ "x": 2405,
+ "y": 72
+ },
+ "width": 119,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "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": "Pagerduty",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 74,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "jita.Email",
+ "type": "rectangle",
+ "pos": {
+ "x": 2564,
+ "y": 72
+ },
+ "width": 111,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/aws/_General/AWS-Email_light-bg.svg",
+ "RawPath": "/aws%2F_General%2FAWS-Email_light-bg.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Email",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 40,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.ssh",
+ "type": "rectangle",
+ "pos": {
+ "x": 1323,
+ "y": 210
+ },
+ "width": 108,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/essentials/112-server.svg",
+ "RawPath": "/essentials%2F112-server.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "ssh",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 24,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.Kubernetes",
+ "type": "rectangle",
+ "pos": {
+ "x": 1471,
+ "y": 210
+ },
+ "width": 152,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/azure/_Companies/Kubernetes.svg",
+ "RawPath": "/azure%2F_Companies%2FKubernetes.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Kubernetes",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 81,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.My SQL",
+ "type": "rectangle",
+ "pos": {
+ "x": 1663,
+ "y": 210
+ },
+ "width": 122,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/mysql.svg",
+ "RawPath": "/dev%2Fmysql.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "My SQL",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 51,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.MongoDB",
+ "type": "rectangle",
+ "pos": {
+ "x": 1323,
+ "y": 342
+ },
+ "width": 138,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/mongodb.svg",
+ "RawPath": "/dev%2Fmongodb.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "MongoDB",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 67,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.PSQL",
+ "type": "rectangle",
+ "pos": {
+ "x": 1501,
+ "y": 342
+ },
+ "width": 108,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/postgresql.svg",
+ "RawPath": "/dev%2Fpostgresql.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "PSQL",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 37,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ },
+ {
+ "id": "infra.Windows",
+ "type": "rectangle",
+ "pos": {
+ "x": 1649,
+ "y": 342
+ },
+ "width": 136,
+ "height": 92,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "B5",
+ "stroke": "B1",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": {
+ "Scheme": "https",
+ "Opaque": "",
+ "User": null,
+ "Host": "icons.terrastruct.com",
+ "Path": "/dev/windows.svg",
+ "RawPath": "/dev%2Fwindows.svg",
+ "OmitHost": false,
+ "ForceQuery": false,
+ "RawQuery": "",
+ "Fragment": "",
+ "RawFragment": ""
+ },
+ "iconPosition": "INSIDE_MIDDLE_CENTER",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "Windows",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N1",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 65,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_TOP_CENTER",
+ "zIndex": 0,
+ "level": 2
+ }
+ ],
+ "connections": [
+ {
+ "id": "(users -- via)[0]",
+ "src": "users",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "via",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 284,
+ "y": 427.0333333333333
+ },
+ {
+ "x": 354,
+ "y": 427.0333333333333
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(via -- teleport)[0]",
+ "src": "via",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "teleport",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 590,
+ "y": 427.0333333333333
+ },
+ {
+ "x": 660,
+ "y": 427.0333333333333
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport -> jita)[0]",
+ "src": "teleport",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "jita",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "borderRadius": 10,
+ "label": "all connections audited and logged",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "N2",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 231,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1133,
+ "y": 336.1333333333333
+ },
+ {
+ "x": 1173,
+ "y": 336.1333333333333
+ },
+ {
+ "x": 1173,
+ "y": 118
+ },
+ {
+ "x": 1915,
+ "y": 118
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport -> infra)[0]",
+ "src": "teleport",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "infra",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 1133,
+ "y": 396.7333333333333
+ },
+ {
+ "x": 1263,
+ "y": 396.7333333333333
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport -> identity provider)[0]",
+ "src": "teleport",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "identity provider",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 1133,
+ "y": 457.3333333333333
+ },
+ {
+ "x": 1223,
+ "y": 457.3333333333333
+ },
+ {
+ "x": 1223,
+ "y": 553.3333333333333
+ },
+ {
+ "x": 1263,
+ "y": 553.3333333333333
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ },
+ {
+ "id": "(teleport <- identity provider)[0]",
+ "src": "teleport",
+ "srcArrow": "triangle",
+ "srcLabel": "",
+ "dst": "identity provider",
+ "dstArrow": "none",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "B1",
+ "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": 1133,
+ "y": 517.9333333333333
+ },
+ {
+ "x": 1173,
+ "y": 517.9333333333333
+ },
+ {
+ "x": 1173,
+ "y": 592.6666666666666
+ },
+ {
+ "x": 1263,
+ "y": 592.6666666666666
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null,
+ "zIndex": 0
+ }
+ ],
+ "root": {
+ "id": "",
+ "type": "",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 0,
+ "height": 0,
+ "opacity": 0,
+ "strokeDash": 0,
+ "strokeWidth": 0,
+ "borderRadius": 0,
+ "fill": "N7",
+ "stroke": "",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "double-border": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "blend": false,
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "",
+ "fontSize": 0,
+ "fontFamily": "",
+ "language": "",
+ "color": "",
+ "italic": false,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "zIndex": 0,
+ "level": 0
+ }
+}
diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg
new file mode 100644
index 000000000..f5b39beb8
--- /dev/null
+++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg
@@ -0,0 +1,852 @@
+TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB ClientsIdentity Native Proxy
+Audit LogCert AuthoritySlackMattermostJiraEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged
+
+
+
\ No newline at end of file
diff --git a/testdata/d2compiler/TestCompile/grid.exp.json b/testdata/d2compiler/TestCompile/grid.exp.json
new file mode 100644
index 000000000..8b4e621bc
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/grid.exp.json
@@ -0,0 +1,180 @@
+{
+ "graph": {
+ "name": "",
+ "isFolderOnly": false,
+ "ast": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-4:0:44",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-3:1:43",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3",
+ "value": [
+ {
+ "string": "hey",
+ "raw_string": "hey"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "map": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:5:5-3:0:42",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:15:22",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:10:17",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:1:8-1:10:17",
+ "value": [
+ {
+ "string": "grid-rows",
+ "raw_string": "grid-rows"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "number": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,1:12:19-1:15:22",
+ "raw": "200",
+ "value": "200"
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:24-2:18:41",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:24-2:13:36",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:1:24-2:13:36",
+ "value": [
+ {
+ "string": "grid-columns",
+ "raw_string": "grid-columns"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "number": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,2:15:38-2:18:41",
+ "raw": "230",
+ "value": "230"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "root": {
+ "id": "",
+ "id_val": "",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": ""
+ },
+ "direction": {
+ "value": ""
+ },
+ "constraint": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
+ },
+ "edges": null,
+ "objects": [
+ {
+ "id": "hey",
+ "id_val": "hey",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "references": [
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/grid.d2,0:0:0-0:3:3",
+ "value": [
+ {
+ "string": "hey",
+ "raw_string": "hey"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": -1
+ }
+ ],
+ "attributes": {
+ "label": {
+ "value": "hey"
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": "rectangle"
+ },
+ "direction": {
+ "value": ""
+ },
+ "constraint": {
+ "value": ""
+ },
+ "gridRows": {
+ "value": "200"
+ },
+ "gridColumns": {
+ "value": "230"
+ }
+ },
+ "zIndex": 0
+ }
+ ]
+ },
+ "err": null
+}
diff --git a/testdata/d2compiler/TestCompile/grid_edge.exp.json b/testdata/d2compiler/TestCompile/grid_edge.exp.json
new file mode 100644
index 000000000..52a77accb
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/grid_edge.exp.json
@@ -0,0 +1,20 @@
+{
+ "graph": null,
+ "err": {
+ "ioerr": null,
+ "errs": [
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,2:1:22-2:7:28",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:3:2: edges in grid diagrams are not supported yet"
+ },
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,4:1:32-4:11:42",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:5:2: edges in grid diagrams are not supported yet"
+ },
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/grid_edge.d2,5:1:44-5:11:54",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/grid_edge.d2:6:2: edges in grid diagrams are not supported yet"
+ }
+ ]
+ }
+}
diff --git a/testdata/d2compiler/TestCompile/grid_negative.exp.json b/testdata/d2compiler/TestCompile/grid_negative.exp.json
new file mode 100644
index 000000000..7999bc2b6
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/grid_negative.exp.json
@@ -0,0 +1,12 @@
+{
+ "graph": null,
+ "err": {
+ "ioerr": null,
+ "errs": [
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/grid_negative.d2,2:15:38-2:19:42",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/grid_negative.d2:3:16: grid-columns must be a positive integer: \"-200\""
+ }
+ ]
+ }
+}
diff --git a/testdata/d2compiler/TestCompile/grid_nested.exp.json b/testdata/d2compiler/TestCompile/grid_nested.exp.json
new file mode 100644
index 000000000..c8db27f4f
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/grid_nested.exp.json
@@ -0,0 +1,16 @@
+{
+ "graph": null,
+ "err": {
+ "ioerr": null,
+ "errs": [
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,1:1:8-1:15:22",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:2:2: \"grid-rows\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")"
+ },
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/grid_nested.d2,2:1:24-2:18:41",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/grid_nested.d2:3:2: \"grid-columns\" can only be used on containers with one level of nesting right now. (\"hey.d\" has nested \"invalid descendant\")"
+ }
+ ]
+ }
+}