Merge pull request #714 from nhooyr/scenarios-a407

d2compiler: Add support for layers, scenarios and steps
This commit is contained in:
Anmol Sethi 2023-02-02 12:36:54 -08:00 committed by GitHub
commit 371c9c200d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
804 changed files with 43930 additions and 14645 deletions

1
.gitignore vendored
View file

@ -5,3 +5,4 @@
*.got.svg *.got.svg
e2e_report.html e2e_report.html
bin bin
out

19
ci/cov.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/sh
set -eu
cd -- "$(dirname "$0")/.."
. ./ci/sub/lib.sh
main() {
if [ "$*" = "" ]; then
set ./...
fi
mkdir -p out
capcode ./ci/test.sh -covermode=atomic -coverprofile=out/cov.prof "$@"
go tool cover -html=out/cov.prof -o=out/cov.html
go tool cover -func=out/cov.prof | grep '^total:' \
| sed 's#^total:.*(statements)[[:space:]]*\([0-9.%]*\)#TOTAL:\t\1#'
return "$code"
}
main "$@"

View file

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export REPORT_OUTPUT="out/e2e_report.html" export REPORT_OUTPUT="./e2etests/out/e2e_report.html"
rm -f $REPORT_OUTPUT rm -f $REPORT_OUTPUT
export E2E_REPORT=1 export E2E_REPORT=1

View file

@ -6,6 +6,15 @@
- `d2 fmt` accepts multiple files to be formatted [#718](https://github.com/terrastruct/d2/issues/718) - `d2 fmt` accepts multiple files to be formatted [#718](https://github.com/terrastruct/d2/issues/718)
- You can now use the reserved keywords `layers`/`scenarios`/`steps` to define diagrams
with multiple levels of abstractions. [#714](https://github.com/terrastruct/d2/pull/714)
Docs to come soon
- [#416](https://github.com/terrastruct/d2/issues/416) was also fixed so you can no
longer use keywords intended for use under `style` outside and vice versa. e.g.
`obj.style.shape` and `obj.double-border` are now illegal. The correct uses are
`obj.shape` and `obj.style.double-border`.
- Many other minor compiler bugs were fixed.
#### Improvements 🧹 #### Improvements 🧹
- Code snippets use bold and italic font styles as determined by highlighter [#710](https://github.com/terrastruct/d2/issues/710), [#741](https://github.com/terrastruct/d2/issues/741) - Code snippets use bold and italic font styles as determined by highlighter [#710](https://github.com/terrastruct/d2/issues/710), [#741](https://github.com/terrastruct/d2/issues/741)

2
ci/sub

@ -1 +1 @@
Subproject commit 8ac704818b5d7ab519e4b87caf5eb79716493709 Subproject commit 2009cdd523e00cc2e9b8ba804095f71ca70d5671

View file

@ -1,3 +1,5 @@
// TODO: Remove boxes and cleanup like d2ir
//
// d2ast implements the d2 language's abstract syntax tree. // d2ast implements the d2 language's abstract syntax tree.
// //
// Special characters to think about in parser: // Special characters to think about in parser:
@ -149,6 +151,10 @@ func (r *Range) UnmarshalText(b []byte) (err error) {
return r.End.UnmarshalText(end) return r.End.UnmarshalText(end)
} }
func (r Range) Before(r2 Range) bool {
return r.Start.Before(r2.Start)
}
// Position represents a line:column and byte position in a file. // Position represents a line:column and byte position in a file.
// //
// note: Line and Column are zero indexed. // note: Line and Column are zero indexed.
@ -257,6 +263,10 @@ func (p Position) SubtractString(s string, byUTF16 bool) Position {
return p return p
} }
func (p Position) Before(p2 Position) bool {
return p.Byte < p2.Byte
}
// MapNode is implemented by nodes that may be children of Maps. // MapNode is implemented by nodes that may be children of Maps.
type MapNode interface { type MapNode interface {
Node Node
@ -402,7 +412,7 @@ func (s *SingleQuotedString) scalar() {}
func (s *BlockString) scalar() {} func (s *BlockString) scalar() {}
// TODO: mistake, move into parse.go // TODO: mistake, move into parse.go
func (n *Null) ScalarString() string { return n.Type() } func (n *Null) ScalarString() string { return "" }
func (b *Boolean) ScalarString() string { return strconv.FormatBool(b.Value) } func (b *Boolean) ScalarString() string { return strconv.FormatBool(b.Value) }
func (n *Number) ScalarString() string { return n.Raw } func (n *Number) ScalarString() string { return n.Raw }
func (s *UnquotedString) ScalarString() string { func (s *UnquotedString) ScalarString() string {
@ -648,6 +658,21 @@ type KeyPath struct {
Path []*StringBox `json:"path"` Path []*StringBox `json:"path"`
} }
func MakeKeyPath(a []string) *KeyPath {
kp := &KeyPath{}
for _, el := range a {
kp.Path = append(kp.Path, MakeValueBox(RawString(el, true)).StringBox())
}
return kp
}
func (kp *KeyPath) IDA() (ida []string) {
for _, el := range kp.Path {
ida = append(ida, el.Unbox().ScalarString())
}
return ida
}
type Edge struct { type Edge struct {
Range Range `json:"range"` Range Range `json:"range"`
@ -729,6 +754,37 @@ type ArrayNodeBox struct {
Map *Map `json:"map,omitempty"` Map *Map `json:"map,omitempty"`
} }
func MakeArrayNodeBox(an ArrayNode) ArrayNodeBox {
var ab ArrayNodeBox
switch an := an.(type) {
case *Comment:
ab.Comment = an
case *BlockComment:
ab.BlockComment = an
case *Substitution:
ab.Substitution = an
case *Null:
ab.Null = an
case *Boolean:
ab.Boolean = an
case *Number:
ab.Number = an
case *UnquotedString:
ab.UnquotedString = an
case *DoubleQuotedString:
ab.DoubleQuotedString = an
case *SingleQuotedString:
ab.SingleQuotedString = an
case *BlockString:
ab.BlockString = an
case *Array:
ab.Array = an
case *Map:
ab.Map = an
}
return ab
}
func (ab ArrayNodeBox) Unbox() ArrayNode { func (ab ArrayNodeBox) Unbox() ArrayNode {
switch { switch {
case ab.Comment != nil: case ab.Comment != nil:

View file

@ -18,10 +18,11 @@ import (
func GenDSL(maxi int) (_ string, err error) { func GenDSL(maxi int) (_ string, err error) {
gs := &dslGenState{ gs := &dslGenState{
rand: mathrand.New(mathrand.NewSource(time.Now().UnixNano())), rand: mathrand.New(mathrand.NewSource(time.Now().UnixNano())),
g: d2graph.NewGraph(&d2ast.Map{}), g: d2graph.NewGraph(),
nodeShapes: make(map[string]string), nodeShapes: make(map[string]string),
nodeContainer: make(map[string]string), nodeContainer: make(map[string]string),
} }
gs.g.AST = &d2ast.Map{}
err = gs.gen(maxi) err = gs.gen(maxi)
if err != nil { if err != nil {
return "", err return "", err

File diff suppressed because it is too large Load diff

View file

@ -8,12 +8,13 @@ import (
tassert "github.com/stretchr/testify/assert" tassert "github.com/stretchr/testify/assert"
"oss.terrastruct.com/util-go/assert"
"oss.terrastruct.com/util-go/diff"
"oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2compiler"
"oss.terrastruct.com/d2/d2format" "oss.terrastruct.com/d2/d2format"
"oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/util-go/assert"
"oss.terrastruct.com/util-go/diff"
) )
func TestCompile(t *testing.T) { func TestCompile(t *testing.T) {
@ -123,8 +124,7 @@ x: {
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/equal_dimensions_on_circle.d2:3:2: width and height must be equal for circle shapes expErr: `d2/testdata/d2compiler/TestCompile/equal_dimensions_on_circle.d2:3:2: width and height must be equal for circle shapes
d2/testdata/d2compiler/TestCompile/equal_dimensions_on_circle.d2:4:2: width and height must be equal for circle shapes d2/testdata/d2compiler/TestCompile/equal_dimensions_on_circle.d2:4:2: width and height must be equal for circle shapes`,
`,
}, },
{ {
name: "single_dimension_on_circle", name: "single_dimension_on_circle",
@ -207,8 +207,7 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:16:3: height c
d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:25:3: width cannot be used on container: containers.oval container d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:25:3: width cannot be used on container: containers.oval container
d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:26:3: height cannot be used on container: containers.oval container d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:26:3: height cannot be used on container: containers.oval container
d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:36:3: width cannot be used on container: containers.hexagon container d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:36:3: width cannot be used on container: containers.hexagon container
d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height cannot be used on container: containers.hexagon container d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height cannot be used on container: containers.hexagon container`,
`,
}, },
{ {
name: "dimension_with_style", name: "dimension_with_style",
@ -241,8 +240,7 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height c
} }
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/shape_unquoted_hex.d2:3:10: missing value after colon expErr: `d2/testdata/d2compiler/TestCompile/shape_unquoted_hex.d2:3:10: missing value after colon`,
`,
}, },
{ {
name: "edge_unquoted_hex", name: "edge_unquoted_hex",
@ -253,8 +251,7 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height c
} }
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/edge_unquoted_hex.d2:3:10: missing value after colon expErr: `d2/testdata/d2compiler/TestCompile/edge_unquoted_hex.d2:3:10: missing value after colon`,
`,
}, },
{ {
name: "blank_underscore", name: "blank_underscore",
@ -264,8 +261,7 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height c
_ _
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/blank_underscore.d2:3:3: invalid use of parent "_" expErr: `d2/testdata/d2compiler/TestCompile/blank_underscore.d2:3:3: field key must contain more than underscores`,
`,
}, },
{ {
name: "image_non_style", name: "image_non_style",
@ -276,8 +272,7 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height c
name: y name: y
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/image_non_style.d2:4:3: image shapes cannot have children. expErr: `d2/testdata/d2compiler/TestCompile/image_non_style.d2:4:3: image shapes cannot have children.`,
`,
}, },
{ {
name: "stroke-width", name: "stroke-width",
@ -302,8 +297,7 @@ d2/testdata/d2compiler/TestCompile/no_dimensions_on_containers.d2:37:3: height c
style.stroke-width: -1 style.stroke-width: -1
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/illegal-stroke-width.d2:2:23: expected "stroke-width" to be a number between 0 and 15 expErr: `d2/testdata/d2compiler/TestCompile/illegal-stroke-width.d2:2:23: expected "stroke-width" to be a number between 0 and 15`,
`,
}, },
{ {
name: "underscore_parent_create", name: "underscore_parent_create",
@ -340,8 +334,7 @@ x: {
`, `,
assertions: func(t *testing.T, g *d2graph.Graph) { assertions: func(t *testing.T, g *d2graph.Graph) {
tassert.Equal(t, "y", g.Objects[1].ID) tassert.Equal(t, "y", g.Objects[1].ID)
tassert.Equal(t, g.Root.AbsID(), g.Objects[1].References[0].ScopeObj.AbsID()) tassert.Equal(t, g.Objects[0].AbsID(), g.Objects[1].References[0].ScopeObj.AbsID())
tassert.Equal(t, g.Objects[0].AbsID(), g.Objects[1].References[0].UnresolvedScopeObj.AbsID())
}, },
}, },
{ {
@ -456,8 +449,7 @@ x: {
text: ` text: `
_.x _.x
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/underscore_parent_root.d2:2:1: parent "_" cannot be used in the root scope expErr: `d2/testdata/d2compiler/TestCompile/underscore_parent_root.d2:2:1: invalid underscore: no parent`,
`,
}, },
{ {
name: "underscore_parent_middle_path", name: "underscore_parent_middle_path",
@ -467,8 +459,7 @@ x: {
y._.z y._.z
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/underscore_parent_middle_path.d2:3:3: parent "_" can only be used in the beginning of paths, e.g. "_.x" expErr: `d2/testdata/d2compiler/TestCompile/underscore_parent_middle_path.d2:3:5: parent "_" can only be used in the beginning of paths, e.g. "_.x"`,
`,
}, },
{ {
name: "underscore_parent_sandwich_path", name: "underscore_parent_sandwich_path",
@ -478,8 +469,7 @@ x: {
_.z._ _.z._
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/underscore_parent_sandwich_path.d2:3:3: parent "_" can only be used in the beginning of paths, e.g. "_.x" expErr: `d2/testdata/d2compiler/TestCompile/underscore_parent_sandwich_path.d2:3:7: parent "_" can only be used in the beginning of paths, e.g. "_.x"`,
`,
}, },
{ {
name: "underscore_edge", name: "underscore_edge",
@ -996,8 +986,7 @@ x -> y: {
text: `x: {shape: triangle} text: `x: {shape: triangle}
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/object_arrowhead_shape.d2:1:5: invalid shape, can only set "triangle" for arrowheads expErr: `d2/testdata/d2compiler/TestCompile/object_arrowhead_shape.d2:1:5: invalid shape, can only set "triangle" for arrowheads`,
`,
}, },
{ {
name: "edge_flat_label_arrowhead", name: "edge_flat_label_arrowhead",
@ -1083,8 +1072,7 @@ x -> y: {
space -> stars space -> stars
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/nested_edge.d2:1:1: edges cannot be nested within another edge expErr: `d2/testdata/d2compiler/TestCompile/nested_edge.d2:2:3: cannot create edge inside edge`,
`,
}, },
{ {
name: "shape_edge_style", name: "shape_edge_style",
@ -1094,8 +1082,7 @@ x: {
style.animated: true style.animated: true
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/shape_edge_style.d2:3:2: key "animated" can only be applied to edges expErr: `d2/testdata/d2compiler/TestCompile/shape_edge_style.d2:3:2: key "animated" can only be applied to edges`,
`,
}, },
{ {
name: "edge_chain_map", name: "edge_chain_map",
@ -1351,8 +1338,7 @@ x -> y: {
z z
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/edge_map_non_reserved.d2:2:1: edge map keys must be reserved keywords expErr: `d2/testdata/d2compiler/TestCompile/edge_map_non_reserved.d2:3:3: edge map keys must be reserved keywords`,
`,
}, },
{ {
name: "url_link", name: "url_link",
@ -1397,8 +1383,7 @@ x -> y: {
text: `x.near: txop-center text: `x.near: txop-center
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/near_bad_constant.d2:1:1: near key "txop-center" must be the absolute path to a shape or one of the following constants: top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right expErr: `d2/testdata/d2compiler/TestCompile/near_bad_constant.d2:1:9: near key "txop-center" must be the absolute path to a shape or one of the following constants: top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right`,
`,
}, },
{ {
name: "near_bad_container", name: "near_bad_container",
@ -1408,8 +1393,7 @@ x -> y: {
y y
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/near_bad_container.d2:1:1: constant near keys cannot be set on shapes with children expErr: `d2/testdata/d2compiler/TestCompile/near_bad_container.d2:2:9: constant near keys cannot be set on shapes with children`,
`,
}, },
{ {
name: "near_bad_connected", name: "near_bad_connected",
@ -1419,16 +1403,14 @@ x -> y: {
} }
x -> y x -> y
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/near_bad_connected.d2:1:1: constant near keys cannot be set on connected shapes expErr: `d2/testdata/d2compiler/TestCompile/near_bad_connected.d2:2:9: constant near keys cannot be set on connected shapes`,
`,
}, },
{ {
name: "nested_near_constant", name: "nested_near_constant",
text: `x.y.near: top-center text: `x.y.near: top-center
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/nested_near_constant.d2:1:1: constant near keys can only be set on root level shapes expErr: `d2/testdata/d2compiler/TestCompile/nested_near_constant.d2:1:11: constant near keys can only be set on root level shapes`,
`,
}, },
{ {
name: "reserved_icon_near_style", name: "reserved_icon_near_style",
@ -1474,17 +1456,14 @@ y
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:3:9: bad icon url "::????:::%%orange": parse "::????:::%%orange": missing protocol scheme expErr: `d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:3:9: bad icon url "::????:::%%orange": parse "::????:::%%orange": missing protocol scheme
d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:4:18: expected "opacity" to be a number between 0.0 and 1.0
d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:5:18: expected "opacity" to be a number between 0.0 and 1.0 d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:5:18: expected "opacity" to be a number between 0.0 and 1.0
d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:1:1: near key "y" must be the absolute path to a shape or one of the following constants: top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:2:9: near key "y" must be the absolute path to a shape or one of the following constants: top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right`,
`,
}, },
{ {
name: "errors/missing_shape_icon", name: "errors/missing_shape_icon",
text: `x.shape: image`, text: `x.shape: image`,
expErr: `d2/testdata/d2compiler/TestCompile/errors/missing_shape_icon.d2:1:1: image shape must include an "icon" field expErr: `d2/testdata/d2compiler/TestCompile/errors/missing_shape_icon.d2:1:1: image shape must include an "icon" field`,
`,
}, },
{ {
name: "edge_in_column", name: "edge_in_column",
@ -1500,8 +1479,7 @@ d2/testdata/d2compiler/TestCompile/errors/reserved_icon_style.d2:1:1: near key "
text: `x: {style.opacity: 0.4} text: `x: {style.opacity: 0.4}
y -> x.style y -> x.style
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/edge_to_style.d2:2:1: cannot connect to reserved keyword expErr: `d2/testdata/d2compiler/TestCompile/edge_to_style.d2:2:8: reserved keywords are prohibited in edges`,
`,
}, },
{ {
name: "escaped_id", name: "escaped_id",
@ -1581,7 +1559,7 @@ b`, g.Objects[0].Attributes.Label.Value)
GetType(): string GetType(): string
style: { style: {
opacity: 0.4 opacity: 0.4
color: blue font-color: blue
} }
} }
`, `,
@ -1680,10 +1658,9 @@ x.y -> a.b: {
{ {
name: "3d_oval", name: "3d_oval",
text: `SVP1.style.shape: oval text: `SVP1.shape: oval
SVP1.style.3d: true`, SVP1.style.3d: true`,
expErr: `d2/testdata/d2compiler/TestCompile/3d_oval.d2:2:1: key "3d" can only be applied to squares and rectangles expErr: `d2/testdata/d2compiler/TestCompile/3d_oval.d2:2:1: key "3d" can only be applied to squares and rectangles`,
`,
}, { }, {
name: "edge_column_index", name: "edge_column_index",
text: `src: { text: `src: {
@ -1740,8 +1717,7 @@ dst.id <-> src.dst_id
} }
b -> x.a b -> x.a
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/leaky_sequence.d2:5:1: connections within sequence diagrams can connect only to other objects within the same sequence diagram expErr: `d2/testdata/d2compiler/TestCompile/leaky_sequence.d2:5:1: connections within sequence diagrams can connect only to other objects within the same sequence diagram`,
`,
}, },
{ {
name: "sequence_scoping", name: "sequence_scoping",
@ -1775,6 +1751,35 @@ choo: {
tassert.Equal(t, 3, len(g.Root.ChildrenArray)) tassert.Equal(t, 3, len(g.Root.ChildrenArray))
}, },
}, },
{
name: "sequence_container",
text: `shape: sequence_diagram
x.y.q -> j.y.p
ok: {
x.y.q -> j.y.p
}
`,
assertions: func(t *testing.T, g *d2graph.Graph) {
tassert.Equal(t, 7, len(g.Objects))
tassert.Equal(t, 3, len(g.Root.ChildrenArray))
},
},
{
name: "sequence_container_2",
text: `shape: sequence_diagram
x.y.q
ok: {
x.y.q -> j.y.p
meow
}
`,
assertions: func(t *testing.T, g *d2graph.Graph) {
tassert.Equal(t, 8, len(g.Objects))
tassert.Equal(t, 2, len(g.Root.ChildrenArray))
},
},
{ {
name: "root_direction", name: "root_direction",
@ -1818,8 +1823,7 @@ choo: {
text: `x: { text: `x: {
direction: diagonal direction: diagonal
}`, }`,
expErr: `d2/testdata/d2compiler/TestCompile/invalid_direction.d2:2:14: direction must be one of up, down, right, left, got "diagonal" expErr: `d2/testdata/d2compiler/TestCompile/invalid_direction.d2:2:14: direction must be one of up, down, right, left, got "diagonal"`,
`,
}, },
{ {
name: "self-referencing", name: "self-referencing",
@ -1868,8 +1872,7 @@ choo: {
test_id: varchar(64) {constraint: [primary_key, foreign_key]} test_id: varchar(64) {constraint: [primary_key, foreign_key]}
} }
`, `,
expErr: `d2/testdata/d2compiler/TestCompile/sql-panic.d2:3:27: constraint value must be a string expErr: `d2/testdata/d2compiler/TestCompile/sql-panic.d2:3:27: reserved field constraint does not accept composite`,
`,
}, },
{ {
name: "wrong_column_index", name: "wrong_column_index",
@ -1939,3 +1942,167 @@ Chinchillas_Collectibles.chinchilla -> Chinchillas.id`,
}) })
} }
} }
func TestCompile2(t *testing.T) {
t.Parallel()
t.Run("boards", testBoards)
t.Run("seqdiagrams", testSeqDiagrams)
}
func testBoards(t *testing.T) {
t.Parallel()
tca := []struct {
name string
run func(t *testing.T)
}{
{
name: "root",
run: func(t *testing.T) {
g := assertCompile(t, `base
layers: {
one: {
santa
}
two: {
clause
}
}
`, "")
assert.JSON(t, 2, len(g.Layers))
assert.JSON(t, "one", g.Layers[0].Name)
assert.JSON(t, "two", g.Layers[1].Name)
},
},
{
name: "recursive",
run: func(t *testing.T) {
g := assertCompile(t, `base
layers: {
one: {
santa
}
two: {
clause
steps: {
seinfeld: {
reindeer
}
missoula: {
montana
}
}
}
}
`, "")
assert.Equal(t, 2, len(g.Layers))
assert.Equal(t, "one", g.Layers[0].Name)
assert.Equal(t, "two", g.Layers[1].Name)
assert.Equal(t, 2, len(g.Layers[1].Steps))
},
},
{
name: "errs/duplicate_board",
run: func(t *testing.T) {
assertCompile(t, `base
layers: {
one: {
santa
}
}
steps: {
one: {
clause
}
}
`, `d2/testdata/d2compiler/TestCompile2/boards/errs/duplicate_board.d2:9:2: board name one already used by another board`)
},
},
}
for _, tc := range tca {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tc.run(t)
})
}
}
func testSeqDiagrams(t *testing.T) {
t.Parallel()
t.Run("errs", func(t *testing.T) {
t.Parallel()
tca := []struct {
name string
skip bool
run func(t *testing.T)
}{
{
name: "sequence_diagram_edge_between_edge_groups",
// New sequence diagram scoping implementation is disabled.
skip: true,
run: func(t *testing.T) {
assertCompile(t, `
Office chatter: {
shape: sequence_diagram
alice: Alice
bob: Bobby
awkward small talk: {
alice -> bob: uhm, hi
bob -> alice: oh, hello
icebreaker attempt: {
alice -> bob: what did you have for lunch?
}
unfortunate outcome: {
bob -> alice: that's personal
}
}
awkward small talk.icebreaker attempt.alice -> awkward small talk.unfortunate outcome.bob
}
`, "d2/testdata/d2compiler/TestCompile2/seqdiagrams/errs/sequence_diagram_edge_between_edge_groups.d2:16:3: edges between edge groups are not allowed")
},
},
}
for _, tc := range tca {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
if tc.skip {
t.SkipNow()
}
tc.run(t)
})
}
})
}
func assertCompile(t *testing.T, text string, expErr string) *d2graph.Graph {
d2Path := fmt.Sprintf("d2/testdata/d2compiler/%v.d2", t.Name())
g, err := d2compiler.Compile(d2Path, strings.NewReader(text), nil)
if expErr != "" {
assert.Error(t, err)
assert.ErrorString(t, err, expErr)
} else {
assert.Success(t, err)
}
got := struct {
Graph *d2graph.Graph `json:"graph"`
Err error `json:"err"`
}{
Graph: g,
Err: err,
}
err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2compiler", t.Name()), got)
assert.Success(t, err)
return g
}

View file

@ -4,18 +4,20 @@ import (
"context" "context"
"strconv" "strconv"
"oss.terrastruct.com/util-go/go2"
"oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/d2renderers/d2fonts"
"oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/d2themes" "oss.terrastruct.com/d2/d2themes"
"oss.terrastruct.com/d2/d2themes/d2themescatalog" "oss.terrastruct.com/d2/d2themes/d2themescatalog"
"oss.terrastruct.com/util-go/go2"
) )
func Export(ctx context.Context, g *d2graph.Graph, themeID int64, fontFamily *d2fonts.FontFamily) (*d2target.Diagram, error) { func Export(ctx context.Context, g *d2graph.Graph, themeID int64, fontFamily *d2fonts.FontFamily) (*d2target.Diagram, error) {
theme := d2themescatalog.Find(themeID) theme := d2themescatalog.Find(themeID)
diagram := d2target.NewDiagram() diagram := d2target.NewDiagram()
diagram.Name = g.Name
if fontFamily == nil { if fontFamily == nil {
fontFamily = go2.Pointer(d2fonts.SourceSansPro) fontFamily = go2.Pointer(d2fonts.SourceSansPro)
} }

View file

@ -397,3 +397,15 @@ func (p *printer) edgeIndex(ei *d2ast.EdgeIndex) {
} }
p.sb.WriteByte(']') p.sb.WriteByte(']')
} }
func KeyPath(kp *d2ast.KeyPath) (ida []string) {
for _, s := range kp.Path {
// We format each string of the key to ensure the resulting strings can be parsed
// correctly.
n := &d2ast.KeyPath{
Path: []*d2ast.StringBox{d2ast.MakeValueBox(d2ast.RawString(s.Unbox().ScalarString(), true)).StringBox()},
}
ida = append(ida, Format(n))
}
return ida
}

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"math" "math"
"net/url" "net/url"
"sort"
"strconv" "strconv"
"strings" "strings"
@ -24,25 +25,26 @@ import (
const INNER_LABEL_PADDING int = 5 const INNER_LABEL_PADDING int = 5
const DEFAULT_SHAPE_PADDING = 100. const DEFAULT_SHAPE_PADDING = 100.
// TODO: Refactor with a light abstract layer on top of AST implementing scenarios,
// variables, imports, substitutions and then a final set of structures representing
// a final graph.
type Graph struct { type Graph struct {
Name string `json:"name"`
AST *d2ast.Map `json:"ast"` AST *d2ast.Map `json:"ast"`
Root *Object `json:"root"` Root *Object `json:"root"`
Edges []*Edge `json:"edges"` Edges []*Edge `json:"edges"`
Objects []*Object `json:"objects"` Objects []*Object `json:"objects"`
Layers []*Graph `json:"layers,omitempty"`
Scenarios []*Graph `json:"scenarios,omitempty"`
Steps []*Graph `json:"steps,omitempty"`
} }
func NewGraph(ast *d2ast.Map) *Graph { func NewGraph() *Graph {
d := &Graph{ d := &Graph{}
AST: ast,
}
d.Root = &Object{ d.Root = &Object{
Graph: d, Graph: d,
Parent: nil, Parent: nil,
Children: make(map[string]*Object), Children: make(map[string]*Object),
Attributes: &Attributes{},
} }
return d return d
} }
@ -82,7 +84,7 @@ type Object struct {
Children map[string]*Object `json:"-"` Children map[string]*Object `json:"-"`
ChildrenArray []*Object `json:"-"` ChildrenArray []*Object `json:"-"`
Attributes Attributes `json:"attributes"` Attributes *Attributes `json:"attributes,omitempty"`
ZIndex int `json:"zIndex"` ZIndex int `json:"zIndex"`
} }
@ -106,6 +108,7 @@ type Attributes struct {
Shape Scalar `json:"shape"` Shape Scalar `json:"shape"`
Direction Scalar `json:"direction"` Direction Scalar `json:"direction"`
Constraint Scalar `json:"constraint"`
} }
// TODO references at the root scope should have their Scope set to root graph AST // TODO references at the root scope should have their Scope set to root graph AST
@ -116,9 +119,7 @@ type Reference struct {
MapKey *d2ast.Key `json:"-"` MapKey *d2ast.Key `json:"-"`
MapKeyEdgeIndex int `json:"map_key_edge_index"` MapKeyEdgeIndex int `json:"map_key_edge_index"`
Scope *d2ast.Map `json:"-"` Scope *d2ast.Map `json:"-"`
// The ScopeObj and UnresolvedScopeObj are the same except when the key contains underscores
ScopeObj *Object `json:"-"` ScopeObj *Object `json:"-"`
UnresolvedScopeObj *Object `json:"-"`
} }
func (r Reference) MapKeyEdgeDest() bool { func (r Reference) MapKeyEdgeDest() bool {
@ -500,10 +501,13 @@ func (obj *Object) newObject(id string) *Object {
child := &Object{ child := &Object{
ID: id, ID: id,
IDVal: idval, IDVal: idval,
Attributes: Attributes{ Attributes: &Attributes{
Label: Scalar{ Label: Scalar{
Value: idval, Value: idval,
}, },
Shape: Scalar{
Value: d2target.ShapeRectangle,
},
}, },
Graph: obj.Graph, Graph: obj.Graph,
@ -523,6 +527,9 @@ func (obj *Object) newObject(id string) *Object {
} }
func (obj *Object) HasChild(ids []string) (*Object, bool) { func (obj *Object) HasChild(ids []string) (*Object, bool) {
if len(ids) == 0 {
return obj, true
}
if len(ids) == 1 && ids[0] != "style" { if len(ids) == 1 && ids[0] != "style" {
_, ok := ReservedKeywords[ids[0]] _, ok := ReservedKeywords[ids[0]]
if ok { if ok {
@ -557,6 +564,7 @@ func (obj *Object) HasEdge(mk *d2ast.Key) (*Edge, bool) {
return nil, false return nil, false
} }
// TODO: remove once not used anywhere
func ResolveUnderscoreKey(ida []string, obj *Object) (resolvedObj *Object, resolvedIDA []string, _ error) { func ResolveUnderscoreKey(ida []string, obj *Object) (resolvedObj *Object, resolvedIDA []string, _ error) {
if len(ida) > 0 && !obj.IsSequenceDiagram() { if len(ida) > 0 && !obj.IsSequenceDiagram() {
objSD := obj.OuterSequenceDiagram() objSD := obj.OuterSequenceDiagram()
@ -637,34 +645,71 @@ func (obj *Object) FindEdges(mk *d2ast.Key) ([]*Edge, bool) {
return ea, true return ea, true
} }
func (obj *Object) ensureChildEdge(ida []string) *Object {
for i := range ida {
switch obj.Attributes.Shape.Value {
case d2target.ShapeClass, d2target.ShapeSQLTable:
// This will only be called for connecting edges where we want to truncate to the
// container.
return obj
default:
obj = obj.EnsureChild(ida[i : i+1])
}
}
return obj
}
// EnsureChild grabs the child by ids or creates it if it does not exist including all // EnsureChild grabs the child by ids or creates it if it does not exist including all
// intermediate nodes. // intermediate nodes.
func (obj *Object) EnsureChild(ids []string) *Object { func (obj *Object) EnsureChild(ida []string) *Object {
_, is := ReservedKeywordHolders[ids[0]] seq := obj.OuterSequenceDiagram()
if len(ids) == 1 && !is { if seq != nil {
_, ok := ReservedKeywords[ids[0]] for _, c := range seq.ChildrenArray {
if c.ID == ida[0] {
if obj.ID == ida[0] {
// In cases of a.a where EnsureChild is called on the parent a, the second a should
// be created as a child of a and not as a child of the diagram. This is super
// unfortunate code but alas.
break
}
obj = seq
break
}
}
}
if len(ida) == 0 {
return obj
}
_, is := ReservedKeywordHolders[ida[0]]
if len(ida) == 1 && !is {
_, ok := ReservedKeywords[ida[0]]
if ok { if ok {
return obj return obj
} }
} }
id := ids[0] id := ida[0]
ids = ids[1:] ida = ida[1:]
if id == "_" {
return obj.Parent.EnsureChild(ida)
}
child, ok := obj.Children[strings.ToLower(id)] child, ok := obj.Children[strings.ToLower(id)]
if !ok { if !ok {
child = obj.newObject(id) child = obj.newObject(id)
} }
if len(ids) >= 1 { if len(ida) >= 1 {
return child.EnsureChild(ids) return child.EnsureChild(ida)
} }
return child return child
} }
func (obj *Object) AppendReferences(ida []string, ref Reference, unresolvedObj *Object) { func (obj *Object) AppendReferences(ida []string, ref Reference, unresolvedObj *Object) {
ref.ScopeObj = obj ref.ScopeObj = unresolvedObj
ref.UnresolvedScopeObj = unresolvedObj
numUnderscores := 0 numUnderscores := 0
for i := range ida { for i := range ida {
if ida[i] == "_" { if ida[i] == "_" {
@ -866,7 +911,7 @@ type Edge struct {
DstArrowhead *Attributes `json:"dstArrowhead,omitempty"` DstArrowhead *Attributes `json:"dstArrowhead,omitempty"`
References []EdgeReference `json:"references,omitempty"` References []EdgeReference `json:"references,omitempty"`
Attributes Attributes `json:"attributes"` Attributes *Attributes `json:"attributes,omitempty"`
ZIndex int `json:"zIndex"` ZIndex int `json:"zIndex"`
} }
@ -938,15 +983,6 @@ func (e *Edge) AbsID() string {
} }
func (obj *Object) Connect(srcID, dstID []string, srcArrow, dstArrow bool, label string) (*Edge, error) { func (obj *Object) Connect(srcID, dstID []string, srcArrow, dstArrow bool, label string) (*Edge, error) {
srcObj, srcID, err := ResolveUnderscoreKey(srcID, obj)
if err != nil {
return nil, err
}
dstObj, dstID, err := ResolveUnderscoreKey(dstID, obj)
if err != nil {
return nil, err
}
for _, id := range [][]string{srcID, dstID} { for _, id := range [][]string{srcID, dstID} {
for _, p := range id { for _, p := range id {
if _, ok := ReservedKeywords[p]; ok { if _, ok := ReservedKeywords[p]; ok {
@ -955,15 +991,15 @@ func (obj *Object) Connect(srcID, dstID []string, srcArrow, dstArrow bool, label
} }
} }
src := srcObj.EnsureChild(srcID) src := obj.ensureChildEdge(srcID)
dst := dstObj.EnsureChild(dstID) dst := obj.ensureChildEdge(dstID)
if src.OuterSequenceDiagram() != dst.OuterSequenceDiagram() { if src.OuterSequenceDiagram() != dst.OuterSequenceDiagram() {
return nil, errors.New("connections within sequence diagrams can connect only to other objects within the same sequence diagram") return nil, errors.New("connections within sequence diagrams can connect only to other objects within the same sequence diagram")
} }
edge := &Edge{ e := &Edge{
Attributes: Attributes{ Attributes: &Attributes{
Label: Scalar{ Label: Scalar{
Value: label, Value: label,
}, },
@ -973,10 +1009,47 @@ func (obj *Object) Connect(srcID, dstID []string, srcArrow, dstArrow bool, label
Dst: dst, Dst: dst,
DstArrow: dstArrow, DstArrow: dstArrow,
} }
edge.initIndex() e.initIndex()
obj.Graph.Edges = append(obj.Graph.Edges, edge) addSQLTableColumnIndices(e, srcID, dstID, obj, src, dst)
return edge, nil
obj.Graph.Edges = append(obj.Graph.Edges, e)
return e, nil
}
func addSQLTableColumnIndices(e *Edge, srcID, dstID []string, obj, src, dst *Object) {
if src.Attributes.Shape.Value == d2target.ShapeSQLTable {
if src == dst {
// Ignore edge to column inside table.
return
}
objAbsID := obj.AbsIDArray()
srcAbsID := src.AbsIDArray()
if len(objAbsID)+len(srcID) > len(srcAbsID) {
for i, d2col := range src.SQLTable.Columns {
if d2col.Name.Label == srcID[len(srcID)-1] {
d2col.Reference = dst.AbsID()
e.SrcTableColumnIndex = new(int)
*e.SrcTableColumnIndex = i
break
}
}
}
}
if dst.Attributes.Shape.Value == d2target.ShapeSQLTable {
objAbsID := obj.AbsIDArray()
dstAbsID := dst.AbsIDArray()
if len(objAbsID)+len(dstID) > len(dstAbsID) {
for i, d2col := range dst.SQLTable.Columns {
if d2col.Name.Label == dstID[len(dstID)-1] {
d2col.Reference = dst.AbsID()
e.DstTableColumnIndex = new(int)
*e.DstTableColumnIndex = i
break
}
}
}
}
} }
// TODO: Treat undirectional/bidirectional edge here and in HasEdge flipped. Same with // TODO: Treat undirectional/bidirectional edge here and in HasEdge flipped. Same with
@ -1252,19 +1325,17 @@ func (g *Graph) Texts() []*d2target.MText {
} }
func Key(k *d2ast.KeyPath) []string { func Key(k *d2ast.KeyPath) []string {
var ids []string return d2format.KeyPath(k)
for _, s := range k.Path {
// We format each string of the key to ensure the resulting strings can be parsed
// correctly.
n := &d2ast.KeyPath{
Path: []*d2ast.StringBox{d2ast.MakeValueBox(d2ast.RawString(s.Unbox().ScalarString(), true)).StringBox()},
}
ids = append(ids, d2format.Format(n))
}
return ids
} }
var ReservedKeywords = map[string]struct{}{ // All reserved keywords. See init below.
var ReservedKeywords map[string]struct{}
// All reserved keywords not including style keywords.
var ReservedKeywords2 map[string]struct{}
// Non Style/Holder keywords.
var SimpleReservedKeywords = map[string]struct{}{
"label": {}, "label": {},
"desc": {}, "desc": {},
"shape": {}, "shape": {},
@ -1331,15 +1402,88 @@ var NearConstantsArray = []string{
} }
var NearConstants map[string]struct{} var NearConstants map[string]struct{}
// BoardKeywords contains the keywords that create new boards.
var BoardKeywords = map[string]struct{}{
"layers": {},
"scenarios": {},
"steps": {},
}
func init() { func init() {
ReservedKeywords = make(map[string]struct{})
for k, v := range SimpleReservedKeywords {
ReservedKeywords[k] = v
}
for k, v := range StyleKeywords { for k, v := range StyleKeywords {
ReservedKeywords[k] = v ReservedKeywords[k] = v
} }
for k, v := range ReservedKeywordHolders { for k, v := range ReservedKeywordHolders {
ReservedKeywords[k] = v ReservedKeywords[k] = v
} }
for k, v := range BoardKeywords {
ReservedKeywords[k] = v
}
ReservedKeywords2 = make(map[string]struct{})
for k, v := range SimpleReservedKeywords {
ReservedKeywords2[k] = v
}
for k, v := range ReservedKeywordHolders {
ReservedKeywords2[k] = v
}
for k, v := range BoardKeywords {
ReservedKeywords2[k] = v
}
NearConstants = make(map[string]struct{}, len(NearConstantsArray)) NearConstants = make(map[string]struct{}, len(NearConstantsArray))
for _, k := range NearConstantsArray { for _, k := range NearConstantsArray {
NearConstants[k] = struct{}{} NearConstants[k] = struct{}{}
} }
} }
func (g *Graph) GetBoard(name string) *Graph {
for _, l := range g.Layers {
if l.Name == name {
return l
}
}
for _, l := range g.Scenarios {
if l.Name == name {
return l
}
}
for _, l := range g.Steps {
if l.Name == name {
return l
}
}
return nil
}
func (g *Graph) SortObjectsByAST() {
objects := append([]*Object(nil), g.Objects...)
sort.Slice(objects, func(i, j int) bool {
o1 := objects[i]
o2 := objects[j]
if len(o1.References) == 0 || len(o2.References) == 0 {
return i < j
}
r1 := o1.References[0]
r2 := o2.References[0]
return r1.Key.Path[r1.KeyPathIndex].Unbox().GetRange().Before(r2.Key.Path[r2.KeyPathIndex].Unbox().GetRange())
})
g.Objects = objects
}
func (g *Graph) SortEdgesByAST() {
edges := append([]*Edge(nil), g.Edges...)
sort.Slice(edges, func(i, j int) bool {
e1 := edges[i]
e2 := edges[j]
if len(e1.References) == 0 || len(e2.References) == 0 {
return i < j
}
return e1.References[0].Edge.Range.Before(e2.References[0].Edge.Range)
})
g.Edges = edges
}

View file

@ -3,7 +3,7 @@ package d2graph
import "oss.terrastruct.com/d2/d2target" import "oss.terrastruct.com/d2/d2target"
func (obj *Object) IsSequenceDiagram() bool { func (obj *Object) IsSequenceDiagram() bool {
return obj != nil && obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram return obj != nil && obj.Attributes != nil && obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram
} }
func (obj *Object) OuterSequenceDiagram() *Object { func (obj *Object) OuterSequenceDiagram() *Object {
@ -65,7 +65,7 @@ func (obj *Object) ContainsAnyObject(objects []*Object) bool {
func (o *Object) ContainedBy(obj *Object) bool { func (o *Object) ContainedBy(obj *Object) bool {
for _, ref := range o.References { for _, ref := range o.References {
curr := ref.UnresolvedScopeObj curr := ref.ScopeObj
for curr != nil { for curr != nil {
if curr == obj { if curr == obj {
return true return true

252
d2ir/compile.go Normal file
View file

@ -0,0 +1,252 @@
package d2ir
import (
"oss.terrastruct.com/d2/d2ast"
"oss.terrastruct.com/d2/d2parser"
)
type compiler struct {
err d2parser.ParseError
}
func (c *compiler) errorf(n d2ast.Node, f string, v ...interface{}) {
c.err.Errors = append(c.err.Errors, d2parser.Errorf(n, f, v...).(d2ast.Error))
}
func Compile(ast *d2ast.Map) (*Map, error) {
c := &compiler{}
m := &Map{}
m.initRoot()
m.parent.(*Field).References[0].Context.Scope = ast
c.compileMap(m, ast)
c.compileScenarios(m)
c.compileSteps(m)
if !c.err.Empty() {
return nil, c.err
}
return m, nil
}
func (c *compiler) compileScenarios(m *Map) {
scenariosf := m.GetField("scenarios")
if scenariosf == nil {
return
}
scenarios := scenariosf.Map()
if scenarios == nil {
return
}
for _, sf := range scenarios.Fields {
if sf.Map() == nil {
continue
}
base := m.CopyBase(sf)
OverlayMap(base, sf.Map())
sf.Composite = base
c.compileScenarios(sf.Map())
c.compileSteps(sf.Map())
}
}
func (c *compiler) compileSteps(m *Map) {
stepsf := m.GetField("steps")
if stepsf == nil {
return
}
steps := stepsf.Map()
if steps == nil {
return
}
for i, sf := range steps.Fields {
if sf.Map() == nil {
continue
}
var base *Map
if i == 0 {
base = m.CopyBase(sf)
} else {
base = steps.Fields[i-1].Map().CopyBase(sf)
}
OverlayMap(base, sf.Map())
sf.Composite = base
c.compileScenarios(sf.Map())
c.compileSteps(sf.Map())
}
}
func (c *compiler) compileMap(dst *Map, ast *d2ast.Map) {
for _, n := range ast.Nodes {
switch {
case n.MapKey != nil:
c.compileKey(&RefContext{
Key: n.MapKey,
Scope: ast,
ScopeMap: dst,
})
case n.Substitution != nil:
panic("TODO")
}
}
}
func (c *compiler) compileKey(refctx *RefContext) {
if len(refctx.Key.Edges) == 0 {
c.compileField(refctx.ScopeMap, refctx.Key.Key, refctx)
} else {
c.compileEdges(refctx)
}
}
func (c *compiler) compileField(dst *Map, kp *d2ast.KeyPath, refctx *RefContext) {
f, err := dst.EnsureField(kp, refctx)
if err != nil {
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
return
}
if refctx.Key.Primary.Unbox() != nil {
f.Primary_ = &Scalar{
parent: f,
Value: refctx.Key.Primary.Unbox(),
}
}
if refctx.Key.Value.Array != nil {
a := &Array{
parent: f,
}
c.compileArray(a, refctx.Key.Value.Array)
f.Composite = a
} else if refctx.Key.Value.Map != nil {
if f.Map() == nil {
f.Composite = &Map{
parent: f,
}
}
c.compileMap(f.Map(), refctx.Key.Value.Map)
} else if refctx.Key.Value.ScalarBox().Unbox() != nil {
f.Primary_ = &Scalar{
parent: f,
Value: refctx.Key.Value.ScalarBox().Unbox(),
}
}
}
func (c *compiler) compileEdges(refctx *RefContext) {
if refctx.Key.Key != nil {
f, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx)
if err != nil {
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
return
}
if _, ok := f.Composite.(*Array); ok {
c.errorf(refctx.Key.Key, "cannot index into array")
return
}
if f.Map() == nil {
f.Composite = &Map{
parent: f,
}
}
refctx.ScopeMap = f.Map()
}
eida := NewEdgeIDs(refctx.Key)
for i, eid := range eida {
refctx = refctx.Copy()
refctx.Edge = refctx.Key.Edges[i]
var e *Edge
if eid.Index != nil {
ea := refctx.ScopeMap.GetEdges(eid)
if len(ea) == 0 {
c.errorf(refctx.Edge, "indexed edge does not exist")
continue
}
e = ea[0]
e.References = append(e.References, &EdgeReference{
Context: refctx,
})
refctx.ScopeMap.appendFieldReferences(0, refctx.Edge.Src, refctx)
refctx.ScopeMap.appendFieldReferences(0, refctx.Edge.Dst, refctx)
} else {
_, err := refctx.ScopeMap.EnsureField(refctx.Edge.Src, refctx)
if err != nil {
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
continue
}
_, err = refctx.ScopeMap.EnsureField(refctx.Edge.Dst, refctx)
if err != nil {
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
continue
}
e, err = refctx.ScopeMap.CreateEdge(eid, refctx)
if err != nil {
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
continue
}
}
if refctx.Key.EdgeKey != nil {
if e.Map_ == nil {
e.Map_ = &Map{
parent: e,
}
}
c.compileField(e.Map_, refctx.Key.EdgeKey, refctx)
} else {
if refctx.Key.Primary.Unbox() != nil {
e.Primary_ = &Scalar{
parent: e,
Value: refctx.Key.Primary.Unbox(),
}
}
if refctx.Key.Value.Array != nil {
c.errorf(refctx.Key.Value.Unbox(), "edges cannot be assigned arrays")
continue
} else if refctx.Key.Value.Map != nil {
if e.Map_ == nil {
e.Map_ = &Map{
parent: e,
}
}
c.compileMap(e.Map_, refctx.Key.Value.Map)
} else if refctx.Key.Value.ScalarBox().Unbox() != nil {
e.Primary_ = &Scalar{
parent: e,
Value: refctx.Key.Value.ScalarBox().Unbox(),
}
}
}
}
}
func (c *compiler) compileArray(dst *Array, a *d2ast.Array) {
for _, an := range a.Nodes {
var irv Value
switch v := an.Unbox().(type) {
case *d2ast.Array:
ira := &Array{
parent: dst,
}
c.compileArray(ira, v)
irv = ira
case *d2ast.Map:
irm := &Map{
parent: dst,
}
c.compileMap(irm, v)
irv = irm
case d2ast.Scalar:
irv = &Scalar{
parent: dst,
Value: v,
}
case *d2ast.Substitution:
// panic("TODO")
}
dst.Values = append(dst.Values, irv)
}
}

476
d2ir/compile_test.go Normal file
View file

@ -0,0 +1,476 @@
package d2ir_test
import (
"fmt"
"math/big"
"path/filepath"
"strings"
"testing"
"oss.terrastruct.com/util-go/assert"
"oss.terrastruct.com/util-go/diff"
"oss.terrastruct.com/d2/d2ast"
"oss.terrastruct.com/d2/d2ir"
"oss.terrastruct.com/d2/d2parser"
)
func TestCompile(t *testing.T) {
t.Parallel()
t.Run("fields", testCompileFields)
t.Run("edges", testCompileEdges)
t.Run("layers", testCompileLayers)
t.Run("scenarios", testCompileScenarios)
t.Run("steps", testCompileSteps)
}
type testCase struct {
name string
run func(testing.TB)
}
func runa(t *testing.T, tca []testCase) {
for _, tc := range tca {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tc.run(t)
})
}
}
func compile(t testing.TB, text string) (*d2ir.Map, error) {
t.Helper()
d2Path := fmt.Sprintf("%v.d2", t.Name())
ast, err := d2parser.Parse(d2Path, strings.NewReader(text), nil)
assert.Success(t, err)
m, err := d2ir.Compile(ast)
if err != nil {
return nil, err
}
err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2ir", t.Name()), m)
if err != nil {
return nil, err
}
return m, nil
}
func assertQuery(t testing.TB, n d2ir.Node, nfields, nedges int, primary interface{}, idStr string) d2ir.Node {
t.Helper()
m := n.Map()
p := n.Primary()
if idStr != "" {
var err error
n, err = m.Query(idStr)
assert.Success(t, err)
assert.NotEqual(t, n, nil)
p = n.Primary()
m = n.Map()
}
assert.Equal(t, nfields, m.FieldCountRecursive())
assert.Equal(t, nedges, m.EdgeCountRecursive())
if !makeScalar(p).Equal(makeScalar(primary)) {
t.Fatalf("expected primary %#v but got %s", primary, p)
}
return n
}
func makeScalar(v interface{}) *d2ir.Scalar {
s := &d2ir.Scalar{}
switch v := v.(type) {
case *d2ir.Scalar:
if v == nil {
s.Value = &d2ast.Null{}
return s
}
return v
case bool:
s.Value = &d2ast.Boolean{
Value: v,
}
case float64:
bv := &big.Rat{}
bv.SetFloat64(v)
s.Value = &d2ast.Number{
Value: bv,
}
case int:
s.Value = &d2ast.Number{
Value: big.NewRat(int64(v), 1),
}
case string:
s.Value = d2ast.FlatDoubleQuotedString(v)
default:
if v != nil {
panic(fmt.Sprintf("d2ir: unexpected type to makeScalar: %#v", v))
}
s.Value = &d2ast.Null{}
}
return s
}
func testCompileFields(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "root",
run: func(t testing.TB) {
m, err := compile(t, `x`)
assert.Success(t, err)
assertQuery(t, m, 1, 0, nil, "")
assertQuery(t, m, 0, 0, nil, "x")
},
},
{
name: "label",
run: func(t testing.TB) {
m, err := compile(t, `x: yes`)
assert.Success(t, err)
assertQuery(t, m, 1, 0, nil, "")
assertQuery(t, m, 0, 0, "yes", "x")
},
},
{
name: "nested",
run: func(t testing.TB) {
m, err := compile(t, `x.y: yes`)
assert.Success(t, err)
assertQuery(t, m, 2, 0, nil, "")
assertQuery(t, m, 1, 0, nil, "x")
assertQuery(t, m, 0, 0, "yes", "x.y")
},
},
{
name: "array",
run: func(t testing.TB) {
m, err := compile(t, `x: [1;2;3;4]`)
assert.Success(t, err)
assertQuery(t, m, 1, 0, nil, "")
f := assertQuery(t, m, 0, 0, nil, "x").(*d2ir.Field)
assert.String(t, `[1; 2; 3; 4]`, f.Composite.String())
},
},
{
name: "null",
run: func(t testing.TB) {
m, err := compile(t, `pq: pq
pq: null`)
assert.Success(t, err)
assertQuery(t, m, 1, 0, nil, "")
// null doesn't delete pq from *Map so that for language tooling
// we maintain the references.
// Instead d2compiler will ensure it doesn't get rendered.
assertQuery(t, m, 0, 0, nil, "pq")
},
},
}
runa(t, tca)
t.Run("primary", func(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "root",
run: func(t testing.TB) {
m, err := compile(t, `x: yes { pqrs }`)
assert.Success(t, err)
assertQuery(t, m, 2, 0, nil, "")
assertQuery(t, m, 1, 0, "yes", "x")
assertQuery(t, m, 0, 0, nil, "x.pqrs")
},
},
{
name: "nested",
run: func(t testing.TB) {
m, err := compile(t, `x.y: yes { pqrs }`)
assert.Success(t, err)
assertQuery(t, m, 3, 0, nil, "")
assertQuery(t, m, 2, 0, nil, "x")
assertQuery(t, m, 1, 0, "yes", "x.y")
assertQuery(t, m, 0, 0, nil, "x.y.pqrs")
},
},
}
runa(t, tca)
})
}
func testCompileEdges(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "root",
run: func(t testing.TB) {
m, err := compile(t, `x -> y`)
assert.Success(t, err)
assertQuery(t, m, 2, 1, nil, "")
assertQuery(t, m, 0, 0, nil, `(x -> y)[0]`)
assertQuery(t, m, 0, 0, nil, "x")
assertQuery(t, m, 0, 0, nil, "y")
},
},
{
name: "nested",
run: func(t testing.TB) {
m, err := compile(t, `x.y -> z.p`)
assert.Success(t, err)
assertQuery(t, m, 4, 1, nil, "")
assertQuery(t, m, 1, 0, nil, "x")
assertQuery(t, m, 0, 0, nil, "x.y")
assertQuery(t, m, 1, 0, nil, "z")
assertQuery(t, m, 0, 0, nil, "z.p")
assertQuery(t, m, 0, 0, nil, "(x.y -> z.p)[0]")
},
},
{
name: "underscore",
run: func(t testing.TB) {
m, err := compile(t, `p: { _.x -> z }`)
assert.Success(t, err)
assertQuery(t, m, 3, 1, nil, "")
assertQuery(t, m, 0, 0, nil, "x")
assertQuery(t, m, 1, 0, nil, "p")
assertQuery(t, m, 0, 0, nil, "(x -> p.z)[0]")
},
},
{
name: "chain",
run: func(t testing.TB) {
m, err := compile(t, `a -> b -> c -> d`)
assert.Success(t, err)
assertQuery(t, m, 4, 3, nil, "")
assertQuery(t, m, 0, 0, nil, "a")
assertQuery(t, m, 0, 0, nil, "b")
assertQuery(t, m, 0, 0, nil, "c")
assertQuery(t, m, 0, 0, nil, "d")
assertQuery(t, m, 0, 0, nil, "(a -> b)[0]")
assertQuery(t, m, 0, 0, nil, "(b -> c)[0]")
assertQuery(t, m, 0, 0, nil, "(c -> d)[0]")
},
},
}
runa(t, tca)
t.Run("errs", func(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "bad_edge",
run: func(t testing.TB) {
_, err := compile(t, `(x -> y): { p -> q }`)
assert.ErrorString(t, err, `TestCompile/edges/errs/bad_edge.d2:1:13: cannot create edge inside edge`)
},
},
}
runa(t, tca)
})
}
func testCompileLayers(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "root",
run: func(t testing.TB) {
m, err := compile(t, `x -> y
layers: {
bingo: { p.q.z }
}`)
assert.Success(t, err)
assertQuery(t, m, 7, 1, nil, "")
assertQuery(t, m, 0, 0, nil, `(x -> y)[0]`)
assertQuery(t, m, 0, 0, nil, "x")
assertQuery(t, m, 0, 0, nil, "y")
assertQuery(t, m, 3, 0, nil, "layers.bingo")
},
},
}
runa(t, tca)
t.Run("errs", func(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "1/bad_edge",
run: func(t testing.TB) {
_, err := compile(t, `layers.x -> layers.y`)
assert.ErrorString(t, err, `TestCompile/layers/errs/1/bad_edge.d2:1:1: cannot create edges between boards`)
},
},
{
name: "2/bad_edge",
run: func(t testing.TB) {
_, err := compile(t, `layers -> scenarios`)
assert.ErrorString(t, err, `TestCompile/layers/errs/2/bad_edge.d2:1:1: edge with board keyword alone doesn't make sense`)
},
},
{
name: "3/bad_edge",
run: func(t testing.TB) {
_, err := compile(t, `layers.x.y -> steps.z.p`)
assert.ErrorString(t, err, `TestCompile/layers/errs/3/bad_edge.d2:1:1: cannot create edges between boards`)
},
},
{
name: "4/good_edge",
run: func(t testing.TB) {
_, err := compile(t, `layers.x.y -> layers.x.y`)
assert.Success(t, err)
},
},
}
runa(t, tca)
})
}
func testCompileScenarios(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "root",
run: func(t testing.TB) {
m, err := compile(t, `x -> y
scenarios: {
bingo: { p.q.z }
nuclear: { quiche }
}`)
assert.Success(t, err)
assertQuery(t, m, 13, 3, nil, "")
assertQuery(t, m, 0, 0, nil, "x")
assertQuery(t, m, 0, 0, nil, "y")
assertQuery(t, m, 0, 0, nil, `(x -> y)[0]`)
assertQuery(t, m, 5, 1, nil, "scenarios.bingo")
assertQuery(t, m, 0, 0, nil, "scenarios.bingo.x")
assertQuery(t, m, 0, 0, nil, "scenarios.bingo.y")
assertQuery(t, m, 0, 0, nil, `scenarios.bingo.(x -> y)[0]`)
assertQuery(t, m, 2, 0, nil, "scenarios.bingo.p")
assertQuery(t, m, 1, 0, nil, "scenarios.bingo.p.q")
assertQuery(t, m, 0, 0, nil, "scenarios.bingo.p.q.z")
assertQuery(t, m, 3, 1, nil, "scenarios.nuclear")
assertQuery(t, m, 0, 0, nil, "scenarios.nuclear.x")
assertQuery(t, m, 0, 0, nil, "scenarios.nuclear.y")
assertQuery(t, m, 0, 0, nil, `scenarios.nuclear.(x -> y)[0]`)
assertQuery(t, m, 0, 0, nil, "scenarios.nuclear.quiche")
},
},
}
runa(t, tca)
}
func testCompileSteps(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "root",
run: func(t testing.TB) {
m, err := compile(t, `x -> y
steps: {
bingo: { p.q.z }
nuclear: { quiche }
}`)
assert.Success(t, err)
assertQuery(t, m, 16, 3, nil, "")
assertQuery(t, m, 0, 0, nil, "x")
assertQuery(t, m, 0, 0, nil, "y")
assertQuery(t, m, 0, 0, nil, `(x -> y)[0]`)
assertQuery(t, m, 5, 1, nil, "steps.bingo")
assertQuery(t, m, 0, 0, nil, "steps.bingo.x")
assertQuery(t, m, 0, 0, nil, "steps.bingo.y")
assertQuery(t, m, 0, 0, nil, `steps.bingo.(x -> y)[0]`)
assertQuery(t, m, 2, 0, nil, "steps.bingo.p")
assertQuery(t, m, 1, 0, nil, "steps.bingo.p.q")
assertQuery(t, m, 0, 0, nil, "steps.bingo.p.q.z")
assertQuery(t, m, 6, 1, nil, "steps.nuclear")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.x")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.y")
assertQuery(t, m, 0, 0, nil, `steps.nuclear.(x -> y)[0]`)
assertQuery(t, m, 2, 0, nil, "steps.nuclear.p")
assertQuery(t, m, 1, 0, nil, "steps.nuclear.p.q")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.p.q.z")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.quiche")
},
},
{
name: "recursive",
run: func(t testing.TB) {
m, err := compile(t, `x -> y
steps: {
bingo: { p.q.z }
nuclear: {
quiche
scenarios: {
bavarian: {
perseverance
}
}
}
}`)
assert.Success(t, err)
assertQuery(t, m, 25, 4, nil, "")
assertQuery(t, m, 0, 0, nil, "x")
assertQuery(t, m, 0, 0, nil, "y")
assertQuery(t, m, 0, 0, nil, `(x -> y)[0]`)
assertQuery(t, m, 5, 1, nil, "steps.bingo")
assertQuery(t, m, 0, 0, nil, "steps.bingo.x")
assertQuery(t, m, 0, 0, nil, "steps.bingo.y")
assertQuery(t, m, 0, 0, nil, `steps.bingo.(x -> y)[0]`)
assertQuery(t, m, 2, 0, nil, "steps.bingo.p")
assertQuery(t, m, 1, 0, nil, "steps.bingo.p.q")
assertQuery(t, m, 0, 0, nil, "steps.bingo.p.q.z")
assertQuery(t, m, 15, 2, nil, "steps.nuclear")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.x")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.y")
assertQuery(t, m, 0, 0, nil, `steps.nuclear.(x -> y)[0]`)
assertQuery(t, m, 2, 0, nil, "steps.nuclear.p")
assertQuery(t, m, 1, 0, nil, "steps.nuclear.p.q")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.p.q.z")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.quiche")
assertQuery(t, m, 7, 1, nil, "steps.nuclear.scenarios.bavarian")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.scenarios.bavarian.x")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.scenarios.bavarian.y")
assertQuery(t, m, 0, 0, nil, `steps.nuclear.scenarios.bavarian.(x -> y)[0]`)
assertQuery(t, m, 2, 0, nil, "steps.nuclear.scenarios.bavarian.p")
assertQuery(t, m, 1, 0, nil, "steps.nuclear.scenarios.bavarian.p.q")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.scenarios.bavarian.p.q.z")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.scenarios.bavarian.quiche")
assertQuery(t, m, 0, 0, nil, "steps.nuclear.scenarios.bavarian.perseverance")
},
},
}
runa(t, tca)
}

1061
d2ir/d2ir.go Normal file

File diff suppressed because it is too large Load diff

69
d2ir/d2ir_test.go Normal file
View file

@ -0,0 +1,69 @@
package d2ir_test
import (
"testing"
"oss.terrastruct.com/util-go/assert"
"oss.terrastruct.com/d2/d2ast"
"oss.terrastruct.com/d2/d2ir"
)
func TestCopy(t *testing.T) {
t.Parallel()
const scalStr = `Those who claim the dead never return to life haven't ever been around.`
s := &d2ir.Scalar{
Value: d2ast.FlatUnquotedString(scalStr),
}
a := &d2ir.Array{
Values: []d2ir.Value{
&d2ir.Scalar{
Value: &d2ast.Boolean{
Value: true,
},
},
},
}
m2 := &d2ir.Map{
Fields: []*d2ir.Field{
{Primary_: s},
},
}
const keyStr = `Absence makes the heart grow frantic.`
f := &d2ir.Field{
Name: keyStr,
Primary_: s,
Composite: a,
}
e := &d2ir.Edge{
Primary_: s,
Map_: m2,
}
m := &d2ir.Map{
Fields: []*d2ir.Field{f},
Edges: []*d2ir.Edge{e},
}
m = m.Copy(nil).(*d2ir.Map)
f.Name = `Many a wife thinks her husband is the world's greatest lover.`
assert.Equal(t, m, m.Fields[0].Parent())
assert.Equal(t, keyStr, m.Fields[0].Name)
assert.Equal(t, m.Fields[0], m.Fields[0].Primary_.Parent())
assert.Equal(t, m.Fields[0], m.Fields[0].Composite.(*d2ir.Array).Parent())
assert.Equal(t,
m.Fields[0].Composite,
m.Fields[0].Composite.(*d2ir.Array).Values[0].(*d2ir.Scalar).Parent(),
)
assert.Equal(t, m, m.Edges[0].Parent())
assert.Equal(t, m.Edges[0], m.Edges[0].Primary_.Parent())
assert.Equal(t, m.Edges[0], m.Edges[0].Map_.Parent())
assert.Equal(t, m.Edges[0].Map_, m.Edges[0].Map_.Fields[0].Parent())
assert.Equal(t, m.Edges[0].Map_.Fields[0], m.Edges[0].Map_.Fields[0].Primary_.Parent())
}

52
d2ir/merge.go Normal file
View file

@ -0,0 +1,52 @@
package d2ir
func OverlayMap(base, overlay *Map) {
for _, of := range overlay.Fields {
bf := base.GetField(of.Name)
if bf == nil {
base.Fields = append(base.Fields, of.Copy(base).(*Field))
continue
}
OverlayField(bf, of)
}
for _, oe := range overlay.Edges {
bea := base.GetEdges(oe.ID)
if len(bea) == 0 {
base.Edges = append(base.Edges, oe.Copy(base).(*Edge))
continue
}
be := bea[0]
OverlayEdge(be, oe)
}
}
func OverlayField(bf, of *Field) {
if of.Primary_ != nil {
bf.Primary_ = of.Primary_.Copy(bf).(*Scalar)
}
if of.Composite != nil {
if bf.Map() != nil && of.Map() != nil {
OverlayMap(bf.Map(), of.Map())
} else {
bf.Composite = of.Composite.Copy(bf).(*Map)
}
}
bf.References = append(bf.References, of.References...)
}
func OverlayEdge(be, oe *Edge) {
if oe.Primary_ != nil {
be.Primary_ = oe.Primary_.Copy(be).(*Scalar)
}
if oe.Map_ != nil {
if be.Map_ != nil {
OverlayMap(be.Map(), oe.Map_)
} else {
be.Map_ = oe.Map_.Copy(be).(*Map)
}
}
be.References = append(be.References, oe.References...)
}

62
d2ir/query.go Normal file
View file

@ -0,0 +1,62 @@
package d2ir
import (
"fmt"
"oss.terrastruct.com/d2/d2parser"
)
// QueryAll is only for tests and debugging.
func (m *Map) QueryAll(idStr string) (na []Node, _ error) {
k, err := d2parser.ParseMapKey(idStr)
if err != nil {
return nil, err
}
if k.Key != nil {
f := m.GetField(k.Key.IDA()...)
if f == nil {
return nil, nil
}
if len(k.Edges) == 0 {
na = append(na, f)
return na, nil
}
m = f.Map()
if m == nil {
return nil, nil
}
}
eida := NewEdgeIDs(k)
for _, eid := range eida {
ea := m.GetEdges(eid)
for _, e := range ea {
if k.EdgeKey == nil {
na = append(na, e)
} else if e.Map_ != nil {
f := e.Map_.GetField(k.EdgeKey.IDA()...)
if f != nil {
na = append(na, f)
}
}
}
}
return na, nil
}
// Query is only for tests and debugging.
func (m *Map) Query(idStr string) (Node, error) {
na, err := m.QueryAll(idStr)
if err != nil {
return nil, err
}
if len(na) == 0 {
return nil, nil
}
if len(na) > 1 {
return nil, fmt.Errorf("expected only one query result but got: %#v", err)
}
return na[0], nil
}

View file

@ -5,11 +5,12 @@ import (
"sort" "sort"
"strings" "strings"
"oss.terrastruct.com/util-go/go2"
"oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/lib/geo" "oss.terrastruct.com/d2/lib/geo"
"oss.terrastruct.com/d2/lib/label" "oss.terrastruct.com/d2/lib/label"
"oss.terrastruct.com/util-go/go2"
) )
func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]*sequenceDiagram, map[string]int, map[string]int, error) { func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]*sequenceDiagram, map[string]int, map[string]int, error) {
@ -113,6 +114,7 @@ func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) (*sequenceDiag
func getLayoutEdges(g *d2graph.Graph, toRemove map[*d2graph.Edge]struct{}) ([]*d2graph.Edge, map[string]int) { func getLayoutEdges(g *d2graph.Graph, toRemove map[*d2graph.Edge]struct{}) ([]*d2graph.Edge, map[string]int) {
edgeOrder := make(map[string]int) edgeOrder := make(map[string]int)
layoutEdges := make([]*d2graph.Edge, 0, len(g.Edges)-len(toRemove)) layoutEdges := make([]*d2graph.Edge, 0, len(g.Edges)-len(toRemove))
for i, edge := range g.Edges { for i, edge := range g.Edges {
edgeOrder[edge.AbsID()] = i edgeOrder[edge.AbsID()] = i
if _, exists := toRemove[edge]; !exists { if _, exists := toRemove[edge]; !exists {

View file

@ -377,7 +377,7 @@ container -> c: edge 1
} }
func TestSelfEdges(t *testing.T) { func TestSelfEdges(t *testing.T) {
g := d2graph.NewGraph(nil) g := d2graph.NewGraph()
g.Root.Attributes.Shape = d2graph.Scalar{Value: d2target.ShapeSequenceDiagram} g.Root.Attributes.Shape = d2graph.Scalar{Value: d2target.ShapeSequenceDiagram}
n1 := g.Root.EnsureChild([]string{"n1"}) n1 := g.Root.EnsureChild([]string{"n1"})
n1.Box = geo.NewBox(nil, 100, 100) n1.Box = geo.NewBox(nil, 100, 100)
@ -387,7 +387,7 @@ func TestSelfEdges(t *testing.T) {
Src: n1, Src: n1,
Dst: n1, Dst: n1,
Index: 0, Index: 0,
Attributes: d2graph.Attributes{ Attributes: &d2graph.Attributes{
Label: d2graph.Scalar{Value: "left to right"}, Label: d2graph.Scalar{Value: "left to right"},
}, },
}, },
@ -413,11 +413,11 @@ func TestSelfEdges(t *testing.T) {
} }
func TestSequenceToDescendant(t *testing.T) { func TestSequenceToDescendant(t *testing.T) {
g := d2graph.NewGraph(nil) g := d2graph.NewGraph()
g.Root.Attributes.Shape = d2graph.Scalar{Value: d2target.ShapeSequenceDiagram} g.Root.Attributes.Shape = d2graph.Scalar{Value: d2target.ShapeSequenceDiagram}
a := g.Root.EnsureChild([]string{"a"}) a := g.Root.EnsureChild([]string{"a"})
a.Box = geo.NewBox(nil, 100, 100) a.Box = geo.NewBox(nil, 100, 100)
a.Attributes = d2graph.Attributes{ a.Attributes = &d2graph.Attributes{
Shape: d2graph.Scalar{Value: shape.PERSON_TYPE}, Shape: d2graph.Scalar{Value: shape.PERSON_TYPE},
} }
a_t1 := a.EnsureChild([]string{"t1"}) a_t1 := a.EnsureChild([]string{"t1"})
@ -428,10 +428,12 @@ func TestSequenceToDescendant(t *testing.T) {
Src: a, Src: a,
Dst: a_t1, Dst: a_t1,
Index: 0, Index: 0,
Attributes: &d2graph.Attributes{},
}, { }, {
Src: a_t1, Src: a_t1,
Dst: a, Dst: a,
Index: 0, Index: 0,
Attributes: &d2graph.Attributes{},
}, },
} }

View file

@ -225,7 +225,7 @@ func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
for _, n := range sd.notes { for _, n := range sd.notes {
inGroup := false inGroup := false
for _, ref := range n.References { for _, ref := range n.References {
curr := ref.UnresolvedScopeObj curr := ref.ScopeObj
for curr != nil { for curr != nil {
if curr == group { if curr == group {
inGroup = true inGroup = true
@ -324,7 +324,7 @@ func (sd *sequenceDiagram) addLifelineEdges() {
actorLifelineEnd := actor.Center() actorLifelineEnd := actor.Center()
actorLifelineEnd.Y = endY actorLifelineEnd.Y = endY
sd.lifelines = append(sd.lifelines, &d2graph.Edge{ sd.lifelines = append(sd.lifelines, &d2graph.Edge{
Attributes: d2graph.Attributes{ Attributes: &d2graph.Attributes{
Style: d2graph.Style{ Style: d2graph.Style{
StrokeDash: &d2graph.Scalar{Value: fmt.Sprintf("%d", LIFELINE_STROKE_DASH)}, StrokeDash: &d2graph.Scalar{Value: fmt.Sprintf("%d", LIFELINE_STROKE_DASH)},
StrokeWidth: &d2graph.Scalar{Value: fmt.Sprintf("%d", LIFELINE_STROKE_WIDTH)}, StrokeWidth: &d2graph.Scalar{Value: fmt.Sprintf("%d", LIFELINE_STROKE_WIDTH)},

View file

@ -44,32 +44,65 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target
return nil, nil, err return nil, nil, err
} }
if len(g.Objects) > 0 { d, err := compile(ctx, g, opts)
err = g.SetDimensions(opts.MeasuredTexts, opts.Ruler, opts.FontFamily)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
return d, g, nil
}
func compile(ctx context.Context, g *d2graph.Graph, opts *CompileOptions) (*d2target.Diagram, error) {
if len(g.Objects) > 0 {
err := g.SetDimensions(opts.MeasuredTexts, opts.Ruler, opts.FontFamily)
if err != nil {
return nil, err
}
coreLayout, err := getLayout(opts) coreLayout, err := getLayout(opts)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
constantNears := d2near.WithoutConstantNears(ctx, g) constantNears := d2near.WithoutConstantNears(ctx, g)
err = d2sequence.Layout(ctx, g, coreLayout) err = d2sequence.Layout(ctx, g, coreLayout)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
err = d2near.Layout(ctx, g, constantNears) err = d2near.Layout(ctx, g, constantNears)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
} }
diagram, err := d2exporter.Export(ctx, g, opts.ThemeID, opts.FontFamily) d, err := d2exporter.Export(ctx, g, opts.ThemeID, opts.FontFamily)
return diagram, g, err if err != nil {
return nil, err
}
for _, l := range g.Layers {
ld, err := compile(ctx, l, opts)
if err != nil {
return nil, err
}
d.Layers = append(d.Layers, ld)
}
for _, l := range g.Scenarios {
ld, err := compile(ctx, l, opts)
if err != nil {
return nil, err
}
d.Scenarios = append(d.Scenarios, ld)
}
for _, l := range g.Steps {
ld, err := compile(ctx, l, opts)
if err != nil {
return nil, err
}
d.Steps = append(d.Steps, ld)
}
return d, nil
} }
func getLayout(opts *CompileOptions) (func(context.Context, *d2graph.Graph) error, error) { func getLayout(opts *CompileOptions) (func(context.Context, *d2graph.Graph) error, error) {

View file

@ -396,7 +396,6 @@ func Delete(g *d2graph.Graph, key string) (_ *d2graph.Graph, err error) {
if g != g2 { if g != g2 {
return g2, nil return g2, nil
} }
g = g2
if len(mk.Edges) == 1 { if len(mk.Edges) == 1 {
obj := g.Root obj := g.Root
@ -1109,7 +1108,7 @@ func move(g *d2graph.Graph, key, newKey string) (*d2graph.Graph, error) {
Key: detachedMK.Key, Key: detachedMK.Key,
MapKey: detachedMK, MapKey: detachedMK,
Scope: mostNestedRef.Scope, Scope: mostNestedRef.Scope,
}, mostNestedRef.UnresolvedScopeObj) }, mostNestedRef.ScopeObj)
} }
} }
@ -1284,8 +1283,8 @@ func move(g *d2graph.Graph, key, newKey string) (*d2graph.Graph, error) {
// We don't want this to be underscore-resolved scope. We want to ignore underscores // We don't want this to be underscore-resolved scope. We want to ignore underscores
var scopeak []string var scopeak []string
if ref.UnresolvedScopeObj != g.Root { if ref.ScopeObj != g.Root {
scopek, err := d2parser.ParseKey(ref.UnresolvedScopeObj.AbsID()) scopek, err := d2parser.ParseKey(ref.ScopeObj.AbsID())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -1373,12 +1373,12 @@ more.(ok.q.z -> p.k): "furbling, v.:"
{ {
name: "complex_edge_1", name: "complex_edge_1",
text: `a.b.(x -> y).q.z text: `a.b.(x -> y).style.animated
`, `,
key: "a.b", key: "a.b",
newName: "ooo", newName: "ooo",
exp: `a.ooo.(x -> y).q.z exp: `a.ooo.(x -> y).style.animated
`, `,
assertions: func(t *testing.T, g *d2graph.Graph) { assertions: func(t *testing.T, g *d2graph.Graph) {
if len(g.Objects) != 4 { if len(g.Objects) != 4 {
@ -1392,12 +1392,12 @@ more.(ok.q.z -> p.k): "furbling, v.:"
{ {
name: "complex_edge_2", name: "complex_edge_2",
text: `a.b.(x -> y).q.z text: `a.b.(x -> y).style.animated
`, `,
key: "a.b.x", key: "a.b.x",
newName: "papa", newName: "papa",
exp: `a.b.(papa -> y).q.z exp: `a.b.(papa -> y).style.animated
`, `,
assertions: func(t *testing.T, g *d2graph.Graph) { assertions: func(t *testing.T, g *d2graph.Graph) {
if len(g.Objects) != 4 { if len(g.Objects) != 4 {
@ -1454,12 +1454,12 @@ more.(ok.q.z -> p.k): "furbling, v.:"
{ {
name: "arrows_complex", name: "arrows_complex",
text: `a.b.(x -- y).q.z text: `a.b.(x -- y).style.animated
`, `,
key: "a.b.(x -- y)[0]", key: "a.b.(x -- y)[0]",
newName: "(x <-> y)[0]", newName: "(x <-> y)[0]",
exp: `a.b.(x <-> y).q.z exp: `a.b.(x <-> y).style.animated
`, `,
assertions: func(t *testing.T, g *d2graph.Graph) { assertions: func(t *testing.T, g *d2graph.Graph) {
if len(g.Objects) != 4 { if len(g.Objects) != 4 {
@ -3025,7 +3025,7 @@ d
if err == nil { if err == nil {
objectsAfter := len(g.Objects) objectsAfter := len(g.Objects)
if objectsBefore != objectsAfter { if objectsBefore != objectsAfter {
println(d2format.Format(g.AST)) t.Log(d2format.Format(g.AST))
return nil, fmt.Errorf("move cannot destroy or create objects: found %d objects before and %d objects after", objectsBefore, objectsAfter) return nil, fmt.Errorf("move cannot destroy or create objects: found %d objects before and %d objects after", objectsBefore, objectsAfter)
} }
} }

View file

@ -45,7 +45,7 @@ func Parse(path string, r io.RuneReader, opts *ParseOptions) (*d2ast.Map, error)
} }
m := p.parseMap(true) m := p.parseMap(true)
if !p.err.empty() { if !p.err.Empty() {
return m, p.err return m, p.err
} }
return m, nil return m, nil
@ -57,7 +57,7 @@ func ParseKey(key string) (*d2ast.KeyPath, error) {
} }
k := p.parseKey() k := p.parseKey()
if !p.err.empty() { if !p.err.Empty() {
return nil, fmt.Errorf("failed to parse key %q: %w", key, p.err) return nil, fmt.Errorf("failed to parse key %q: %w", key, p.err)
} }
if k == nil { if k == nil {
@ -72,7 +72,7 @@ func ParseMapKey(mapKey string) (*d2ast.Key, error) {
} }
mk := p.parseMapKey() mk := p.parseMapKey()
if !p.err.empty() { if !p.err.Empty() {
return nil, fmt.Errorf("failed to parse map key %q: %w", mapKey, p.err) return nil, fmt.Errorf("failed to parse map key %q: %w", mapKey, p.err)
} }
if mk == nil { if mk == nil {
@ -87,7 +87,7 @@ func ParseValue(value string) (d2ast.Value, error) {
} }
v := p.parseValue() v := p.parseValue()
if !p.err.empty() { if !p.err.Empty() {
return nil, fmt.Errorf("failed to parse value %q: %w", value, p.err) return nil, fmt.Errorf("failed to parse value %q: %w", value, p.err)
} }
if v.Unbox() == nil { if v.Unbox() == nil {
@ -130,7 +130,16 @@ type ParseError struct {
Errors []d2ast.Error `json:"errs"` Errors []d2ast.Error `json:"errs"`
} }
func (pe ParseError) empty() bool { func Errorf(n d2ast.Node, f string, v ...interface{}) error {
f = "%v: " + f
v = append([]interface{}{n.GetRange()}, v...)
return d2ast.Error{
Range: n.GetRange(),
Message: fmt.Sprintf(f, v...),
}
}
func (pe ParseError) Empty() bool {
return pe.IOError == nil && len(pe.Errors) == 0 return pe.IOError == nil && len(pe.Errors) == 0
} }
@ -138,11 +147,12 @@ func (pe ParseError) Error() string {
var sb strings.Builder var sb strings.Builder
if pe.IOError != nil { if pe.IOError != nil {
sb.WriteString(pe.IOError.Error()) sb.WriteString(pe.IOError.Error())
}
for i, err := range pe.Errors {
if pe.IOError != nil || i > 0 {
sb.WriteByte('\n') sb.WriteByte('\n')
} }
for _, err := range pe.Errors {
sb.WriteString(err.Error()) sb.WriteString(err.Error())
sb.WriteByte('\n')
} }
return sb.String() return sb.String()
} }

View file

@ -63,7 +63,7 @@ func TestSketch(t *testing.T) {
} }
People discovery: "People discovery \nservice" People discovery: "People discovery \nservice"
admixer: Ad mixer { admixer: Ad mixer {
fill: "#c1a2f3" style.fill: "#c1a2f3"
} }
onboarding service: "Onboarding \nservice" onboarding service: "Onboarding \nservice"
@ -107,7 +107,7 @@ Android: {
web -> twitter fe web -> twitter fe
timeline scorer: "Timeline\nScorer" { timeline scorer: "Timeline\nScorer" {
fill: "#ffdef1" style.fill "#ffdef1"
} }
home ranker: Home Ranker home ranker: Home Ranker
@ -119,7 +119,7 @@ timeline mixer -> home ranker: {
} }
timeline mixer -> timeline service timeline mixer -> timeline service
home mixer: Home mixer { home mixer: Home mixer {
# fill: "#c1a2f3" # style.fill "#c1a2f3"
} }
container0.graphql -> home mixer: { container0.graphql -> home mixer: {
style.stroke-dash: 4 style.stroke-dash: 4
@ -146,7 +146,7 @@ prediction service2: Prediction Service {
icon: https://cdn-icons-png.flaticon.com/512/6461/6461819.png icon: https://cdn-icons-png.flaticon.com/512/6461/6461819.png
} }
home scorer: Home Scorer { home scorer: Home Scorer {
fill: "#ffdef1" style.fill "#ffdef1"
} }
manhattan: Manhattan manhattan: Manhattan
memcache: Memcache { memcache: Memcache {
@ -154,15 +154,15 @@ memcache: Memcache {
} }
fetch: Fetch { fetch: Fetch {
multiple: true style.multiple: true
shape: step shape: step
} }
feature: Feature { feature: Feature {
multiple: true style.multiple: true
shape: step shape: step
} }
scoring: Scoring { scoring: Scoring {
multiple: true style.multiple: true
shape: step shape: step
} }
fetch -> feature fetch -> feature

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 253 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 304 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 248 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

View file

@ -809,9 +809,9 @@ width="1126" height="595" viewBox="-100 -102 1126 595"><style type="text/css">
</pattern> </pattern>
</defs><g id="x" style='opacity:0.400000'><g class="shape" ><path class="shape" transform="translate(132 0)" d="M-1.600310 -0.578379 L115.045551 1.811030 L114.253697 124.234072 L0.925556 127.532483" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><path class="shape" transform="translate(132 0)" d="M0.857263 0.963884 C22.480758 0.701114, 45.040901 -2.192221, 113.206405 0.392335 M-0.648665 0.264598 C25.673568 -0.170612, 50.554623 -0.740285, 113.419625 0.752815 M115.536704 -1.749433 C113.935365 28.635548, 114.626901 53.169790, 115.390547 125.130645 M114.297677 -0.799274 C115.035312 32.957747, 114.058843 67.663042, 114.406876 126.352243 M115.052801 125.786559 C90.443766 128.062482, 63.143081 127.518957, 1.836456 125.596476 M113.056573 125.856267 C71.058092 126.524785, 29.087853 126.253321, 0.938949 126.041844 M-0.720604 125.718532 C-0.568084 88.333645, -2.300517 53.904048, 0.591800 -1.206080 M0.217956 126.998223 C-2.326115 79.511511, -1.820061 33.430410, 0.440740 0.988030" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><rect class="sketch-overlay" transform="translate(132 0)" width="114" height="126" /></g><text class="text-bold" x="189.000000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text></g><g id="y" style='opacity:0.400000'><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="306.000000" y="51.000000" width="347" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>linux: because a PC is a terrible thing to waste</p> </defs><g id="x" style='opacity:0.400000'><g class="shape" ><path class="shape" transform="translate(132 0)" d="M-1.600310 -0.578379 L115.045551 1.811030 L114.253697 124.234072 L0.925556 127.532483" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><path class="shape" transform="translate(132 0)" d="M0.857263 0.963884 C22.480758 0.701114, 45.040901 -2.192221, 113.206405 0.392335 M-0.648665 0.264598 C25.673568 -0.170612, 50.554623 -0.740285, 113.419625 0.752815 M115.536704 -1.749433 C113.935365 28.635548, 114.626901 53.169790, 115.390547 125.130645 M114.297677 -0.799274 C115.035312 32.957747, 114.058843 67.663042, 114.406876 126.352243 M115.052801 125.786559 C90.443766 128.062482, 63.143081 127.518957, 1.836456 125.596476 M113.056573 125.856267 C71.058092 126.524785, 29.087853 126.253321, 0.938949 126.041844 M-0.720604 125.718532 C-0.568084 88.333645, -2.300517 53.904048, 0.591800 -1.206080 M0.217956 126.998223 C-2.326115 79.511511, -1.820061 33.430410, 0.440740 0.988030" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><rect class="sketch-overlay" transform="translate(132 0)" width="114" height="126" /></g><text class="text-bold" x="189.000000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text></g><g id="y" style='opacity:0.400000'><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="306.000000" y="51.000000" width="347" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>linux: because a PC is a terrible thing to waste</p>
</div></foreignObject></g></g><g id="users" style='opacity:0.400000'><g class="shape" ><path class="shape" transform="translate(713 27)" d="M-1.600310 -0.578379 L212.045551 1.811030 L211.253697 70.234072 L0.925556 73.532483" style="fill:#FFFFFF;stroke:#0A0F25;stroke-width:2;" /><path class="shape" transform="translate(713 27)" d="M0.755797 0.849798 C41.919041 0.271510, 83.908070 -2.279368, 210.300335 0.345898 M-0.571888 0.233280 C47.092687 -0.888816, 93.486665 -1.391062, 210.488319 0.663711 M212.536704 -1.749433 C211.434025 16.890424, 212.125561 29.679541, 212.390547 71.130645 M211.297677 -0.799274 C211.695335 18.464376, 210.718866 38.676301, 211.406876 72.352243 M211.928191 71.811822 C166.401573 75.510374, 118.501892 75.031181, 1.619092 71.644237 M210.168238 71.873280 C131.604972 72.658440, 53.066606 72.419106, 0.827814 72.036891 M-0.720604 71.718532 C0.215708 49.821348, -1.516724 30.879454, 0.591800 -1.206080 M0.217956 72.998223 C-1.661676 45.154890, -1.155622 18.717167, 0.440740 0.988030" style="fill:#FFFFFF;stroke:#0A0F25;stroke-width:2;" /><path class="class_header" transform="translate(713 27)" d="M-1.600310 -0.578379 L212.045551 1.811030 L211.253697 34.234072 L0.925556 37.532483" style="fill:#0A0F25" /><path class="class_header" transform="translate(713 27)" d="M0.755797 0.849798 C41.919041 0.271510, 83.908070 -2.279368, 210.300335 0.345898 M-0.571888 0.233280 C47.092687 -0.888816, 93.486665 -1.391062, 210.488319 0.663711 M212.536704 -1.749433 C211.766465 9.060341, 212.458000 14.019375, 212.390547 35.130645 M211.297677 -0.799274 C211.468683 8.802129, 210.492215 19.351806, 211.406876 36.352243 M211.928191 35.811822 C166.401573 39.510374, 118.501892 39.031181, 1.619092 35.644237 M210.168238 35.873280 C131.604972 36.658440, 53.066606 36.419106, 0.827814 36.036891 M-0.720604 35.718532 C0.738237 24.146483, -0.994195 15.529725, 0.591800 -1.206080 M0.217956 36.998223 C-1.218717 22.250475, -0.712663 8.908338, 0.440740 0.988030" style="fill:#0A0F25" /><text class="text" x="733.000000" y="54.000000" style="text-anchor:start;font-size:24px;fill:#FFFFFF">users</text><text class="text" x="723.000000" y="86.000000" style="text-anchor:start;font-size:20px;fill:#0D32B2">last_login</text> </div></foreignObject></g></g><g id="a"><g class="shape" ><path class="shape" transform="translate(132 265)" d="M-1.600310 -0.578379 L115.045551 1.811030 L114.253697 124.234072 L0.925556 127.532483" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><path class="shape" transform="translate(132 265)" d="M0.857263 0.963884 C22.480758 0.701114, 45.040901 -2.192221, 113.206405 0.392335 M-0.648665 0.264598 C25.673568 -0.170612, 50.554623 -0.740285, 113.419625 0.752815 M115.536704 -1.749433 C113.935365 28.635548, 114.626901 53.169790, 115.390547 125.130645 M114.297677 -0.799274 C115.035312 32.957747, 114.058843 67.663042, 114.406876 126.352243 M115.052801 125.786559 C90.443766 128.062482, 63.143081 127.518957, 1.836456 125.596476 M113.056573 125.856267 C71.058092 126.524785, 29.087853 126.253321, 0.938949 126.041844 M-0.720604 125.718532 C-0.568084 88.333645, -2.300517 53.904048, 0.591800 -1.206080 M0.217956 126.998223 C-2.326115 79.511511, -1.820061 33.430410, 0.440740 0.988030" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><rect class="sketch-overlay" transform="translate(132 265)" width="114" height="126" /></g><text class="text-bold" x="189.000000" y="331.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="users" style='opacity:0.400000'><g class="shape" ><path class="shape" transform="translate(713 27)" d="M-1.600310 -0.578379 L212.045551 1.811030 L211.253697 70.234072 L0.925556 73.532483" style="fill:#FFFFFF;stroke:#0A0F25;stroke-width:2;" /><path class="shape" transform="translate(713 27)" d="M0.755797 0.849798 C41.919041 0.271510, 83.908070 -2.279368, 210.300335 0.345898 M-0.571888 0.233280 C47.092687 -0.888816, 93.486665 -1.391062, 210.488319 0.663711 M212.536704 -1.749433 C211.434025 16.890424, 212.125561 29.679541, 212.390547 71.130645 M211.297677 -0.799274 C211.695335 18.464376, 210.718866 38.676301, 211.406876 72.352243 M211.928191 71.811822 C166.401573 75.510374, 118.501892 75.031181, 1.619092 71.644237 M210.168238 71.873280 C131.604972 72.658440, 53.066606 72.419106, 0.827814 72.036891 M-0.720604 71.718532 C0.215708 49.821348, -1.516724 30.879454, 0.591800 -1.206080 M0.217956 72.998223 C-1.661676 45.154890, -1.155622 18.717167, 0.440740 0.988030" style="fill:#FFFFFF;stroke:#0A0F25;stroke-width:2;" /><path class="class_header" transform="translate(713 27)" d="M-1.600310 -0.578379 L212.045551 1.811030 L211.253697 34.234072 L0.925556 37.532483" style="fill:#0A0F25" /><path class="class_header" transform="translate(713 27)" d="M0.755797 0.849798 C41.919041 0.271510, 83.908070 -2.279368, 210.300335 0.345898 M-0.571888 0.233280 C47.092687 -0.888816, 93.486665 -1.391062, 210.488319 0.663711 M212.536704 -1.749433 C211.766465 9.060341, 212.458000 14.019375, 212.390547 35.130645 M211.297677 -0.799274 C211.468683 8.802129, 210.492215 19.351806, 211.406876 36.352243 M211.928191 35.811822 C166.401573 39.510374, 118.501892 39.031181, 1.619092 35.644237 M210.168238 35.873280 C131.604972 36.658440, 53.066606 36.419106, 0.827814 36.036891 M-0.720604 35.718532 C0.738237 24.146483, -0.994195 15.529725, 0.591800 -1.206080 M0.217956 36.998223 C-1.218717 22.250475, -0.712663 8.908338, 0.440740 0.988030" style="fill:#0A0F25" /><text class="text" x="733.000000" y="54.000000" style="text-anchor:start;font-size:24px;fill:#FFFFFF">users</text><text class="text" x="723.000000" y="86.000000" style="text-anchor:start;font-size:20px;fill:#0D32B2">last_login</text>
<text class="text" x="826.000000" y="86.000000" style="text-anchor:start;font-size:20px;fill:#676C7E">datetime</text> <text class="text" x="826.000000" y="86.000000" style="text-anchor:start;font-size:20px;fill:#676C7E">datetime</text>
<text class="text" x="904.000000" y="86.000000" style="text-anchor:end;font-size:20px;fill:#4A6FF3;letter-spacing:2px;"></text><path d="M713.755797 99.849798 C754.919041 99.271510, 796.908070 96.720631, 923.300335 99.345898 M712.428111 99.233280 C760.092687 98.111183, 806.486665 97.608937, 923.488319 99.663711" style="fill:#0A0F25" /><rect class="sketch-overlay" transform="translate(713 27)" width="211" height="72" /></g></g><g id="a"><g class="shape" ><path class="shape" transform="translate(132 265)" d="M-1.600310 -0.578379 L115.045551 1.811030 L114.253697 124.234072 L0.925556 127.532483" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><path class="shape" transform="translate(132 265)" d="M0.857263 0.963884 C22.480758 0.701114, 45.040901 -2.192221, 113.206405 0.392335 M-0.648665 0.264598 C25.673568 -0.170612, 50.554623 -0.740285, 113.419625 0.752815 M115.536704 -1.749433 C113.935365 28.635548, 114.626901 53.169790, 115.390547 125.130645 M114.297677 -0.799274 C115.035312 32.957747, 114.058843 67.663042, 114.406876 126.352243 M115.052801 125.786559 C90.443766 128.062482, 63.143081 127.518957, 1.836456 125.596476 M113.056573 125.856267 C71.058092 126.524785, 29.087853 126.253321, 0.938949 126.041844 M-0.720604 125.718532 C-0.568084 88.333645, -2.300517 53.904048, 0.591800 -1.206080 M0.217956 126.998223 C-2.326115 79.511511, -1.820061 33.430410, 0.440740 0.988030" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /><rect class="sketch-overlay" transform="translate(132 265)" width="114" height="126" /></g><text class="text-bold" x="189.000000" y="331.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="(x -&gt; a)[0]" style='opacity:0.400000'><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path class="connection" fill="none" d="M187.000089 126.340129 M187.000089 126.340129 C189.963884 181.280246, 190.163171 208.939876, 189.405312 262.357263 M185.269924 125.546535 C188.429286 182.679289, 187.378336 210.161496, 189.490419 259.533797" style="stroke:#0D32B2;stroke-width:2;" mask="url(#2358965372)"/><path class="connection" d="M-8.527627 -3.097061 L1.749550 0.558791 L-8.562935 4.521533" style="fill:#0D32B2;stroke:none;stroke-width:0;" transform="translate(189.000000 261.500000) rotate(90)"/> <path class="connection" d="M-10.153731 -4.038897 C-7.293657 -2.964754, -5.552453 -3.126871, 0.222305 -0.654474 M-10.160117 -4.253535 C-7.616436 -2.677663, -5.569656 -2.320404, -0.086565 0.272291 M0.578048 -0.807164 C-2.240460 1.133634, -3.845699 1.135504, -9.579367 4.140709 M-0.217907 -0.322328 C-3.660571 0.941126, -7.003142 2.167050, -10.100296 3.840861 M-9.957758 4.629247 C-9.937438 2.794817, -10.508655 0.509238, -9.330834 -3.522818 M-10.354741 4.285014 C-9.712366 0.996453, -9.805329 -1.235319, -9.648840 -4.366524" style="fill:none;stroke:#0D32B2;stroke-width:2;" transform="translate(189.000000 261.500000) rotate(90)"/><text class="text-italic" x="189.000000" y="192.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E"><tspan x="189.000000" dy="0.000000">You don&#39;t have to know how the computer works,</tspan><tspan x="189.000000" dy="19.500000">just how to work the computer.</tspan></text></g><mask id="2358965372" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1126" height="595"> <text class="text" x="904.000000" y="86.000000" style="text-anchor:end;font-size:20px;fill:#4A6FF3;letter-spacing:2px;"></text><path d="M713.755797 99.849798 C754.919041 99.271510, 796.908070 96.720631, 923.300335 99.345898 M712.428111 99.233280 C760.092687 98.111183, 806.486665 97.608937, 923.488319 99.663711" style="fill:#0A0F25" /><rect class="sketch-overlay" transform="translate(713 27)" width="211" height="72" /></g></g><g id="(x -&gt; a)[0]" style='opacity:0.400000'><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path class="connection" fill="none" d="M187.000089 126.340129 M187.000089 126.340129 C189.963884 181.280246, 190.163171 208.939876, 189.405312 262.357263 M185.269924 125.546535 C188.429286 182.679289, 187.378336 210.161496, 189.490419 259.533797" style="stroke:#0D32B2;stroke-width:2;" mask="url(#1282959480)"/><path class="connection" d="M-8.527627 -3.097061 L1.749550 0.558791 L-8.562935 4.521533" style="fill:#0D32B2;stroke:none;stroke-width:0;" transform="translate(189.000000 261.500000) rotate(90)"/> <path class="connection" d="M-10.153731 -4.038897 C-7.293657 -2.964754, -5.552453 -3.126871, 0.222305 -0.654474 M-10.160117 -4.253535 C-7.616436 -2.677663, -5.569656 -2.320404, -0.086565 0.272291 M0.578048 -0.807164 C-2.240460 1.133634, -3.845699 1.135504, -9.579367 4.140709 M-0.217907 -0.322328 C-3.660571 0.941126, -7.003142 2.167050, -10.100296 3.840861 M-9.957758 4.629247 C-9.937438 2.794817, -10.508655 0.509238, -9.330834 -3.522818 M-10.354741 4.285014 C-9.712366 0.996453, -9.805329 -1.235319, -9.648840 -4.366524" style="fill:none;stroke:#0D32B2;stroke-width:2;" transform="translate(189.000000 261.500000) rotate(90)"/><text class="text-italic" x="189.000000" y="192.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E"><tspan x="189.000000" dy="0.000000">You don&#39;t have to know how the computer works,</tspan><tspan x="189.000000" dy="19.500000">just how to work the computer.</tspan></text></g><mask id="1282959480" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1126" height="595">
<rect x="-100" y="-100" width="1126" height="595" fill="white"></rect> <rect x="-100" y="-100" width="1126" height="595" fill="white"></rect>
<rect x="0.000000" y="176.000000" width="378" height="39" fill="black"></rect> <rect x="0.000000" y="176.000000" width="378" height="39" fill="black"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 310 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 388 KiB

After

Width:  |  Height:  |  Size: 388 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 803 KiB

After

Width:  |  Height:  |  Size: 803 KiB

View file

@ -40,7 +40,7 @@ width="565" height="803" viewBox="-102 -118 565 803"><style type="text/css">
} }
}); });
]]></script><a href="https://d2lang.com" xlink:href="https://d2lang.com"><g id="x"><g class="shape" ><rect x="1" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text><g transform="translate(98 -16)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">1</text></g></g></a><a href="https://terrastruct.com" xlink:href="https://terrastruct.com"><g id="y"><g class="shape" ><rect x="0" y="226" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.000000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">y</text><g transform="translate(98 210)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">2</text></g><title>Gee, I feel kind of LIGHT in the head now, ]]></script><a href="https://d2lang.com" xlink:href="https://d2lang.com"><g id="x"><g class="shape" ><rect x="1" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text><g transform="translate(98 -16)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">1</text></g></g></a><a href="https://terrastruct.com" xlink:href="https://terrastruct.com"><g id="y"><g class="shape" ><rect x="0" y="226" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.000000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">y</text><g transform="translate(98 210)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">2</text></g><title>Gee, I feel kind of LIGHT in the head now,
knowing I can't make my satellite dish PAYMENTS!</title><g transform="translate(66 210)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">3</text></g></g></a><g id="(x -&gt; y)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 57.000000 128.000000 C 57.000000 166.000000 57.000000 186.000000 57.000000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3293380647)"/></g><mask id="3293380647" maskUnits="userSpaceOnUse" x="-100" y="-100" width="334" height="572"> knowing I can't make my satellite dish PAYMENTS!</title><g transform="translate(66 210)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">3</text></g></g></a><g id="(x -&gt; y)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 57.000000 128.000000 C 57.000000 166.000000 57.000000 186.000000 57.000000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1205536357)"/></g><mask id="1205536357" maskUnits="userSpaceOnUse" x="-100" y="-100" width="334" height="572">
<rect x="-100" y="-100" width="334" height="572" fill="white"></rect> <rect x="-100" y="-100" width="334" height="572" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 651 KiB

After

Width:  |  Height:  |  Size: 651 KiB

View file

@ -40,7 +40,7 @@ width="566" height="751" viewBox="-102 -118 566 751"><style type="text/css">
} }
}); });
]]></script><g id="x"><g class="shape" ><rect x="1" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text><g transform="translate(98 -16)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">1</text></g><title>Total abstinence is easier than perfect moderation</title></g><g id="y"><g class="shape" ><rect x="0" y="226" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.000000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">y</text><g transform="translate(98 210)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">2</text></g><title>Gee, I feel kind of LIGHT in the head now, ]]></script><g id="x"><g class="shape" ><rect x="1" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text><g transform="translate(98 -16)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">1</text></g><title>Total abstinence is easier than perfect moderation</title></g><g id="y"><g class="shape" ><rect x="0" y="226" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="57.000000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">y</text><g transform="translate(98 210)" class="appendix-icon"><circle cx="16" cy="16" r="16" fill="white" stroke="#DEE1EB" /><text class="text-bold" x="16" y="21" style="font-size: 16px;text-anchor:middle;">2</text></g><title>Gee, I feel kind of LIGHT in the head now,
knowing I can't make my satellite dish PAYMENTS!</title></g><g id="(x -&gt; y)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 57.000000 128.000000 C 57.000000 166.000000 57.000000 186.000000 57.000000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1935937345)"/></g><mask id="1935937345" maskUnits="userSpaceOnUse" x="-100" y="-100" width="334" height="572"> knowing I can't make my satellite dish PAYMENTS!</title></g><g id="(x -&gt; y)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 57.000000 128.000000 C 57.000000 166.000000 57.000000 186.000000 57.000000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2863209817)"/></g><mask id="2863209817" maskUnits="userSpaceOnUse" x="-100" y="-100" width="334" height="572">
<rect x="-100" y="-100" width="334" height="572" fill="white"></rect> <rect x="-100" y="-100" width="334" height="572" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 650 KiB

After

Width:  |  Height:  |  Size: 650 KiB

View file

@ -37,6 +37,10 @@ type Diagram struct {
Shapes []Shape `json:"shapes"` Shapes []Shape `json:"shapes"`
Connections []Connection `json:"connections"` Connections []Connection `json:"connections"`
Layers []*Diagram `json:"layers,omitempty"`
Scenarios []*Diagram `json:"scenarios,omitempty"`
Steps []*Diagram `json:"steps,omitempty"`
} }
func (diagram Diagram) HashID() (string, error) { func (diagram Diagram) HashID() (string, error) {

View file

@ -17,6 +17,6 @@ If a change results in test diffs, you can run this script to generate a visual
report with the old vs new renders. report with the old vs new renders.
``` ```
go run ./e2etests/report/main.go go run ./e2etests/report/main.go -delta
open ./e2etests/out/e2e_report.html open ./e2etests/out/e2e_report.html
``` ```

View file

@ -12,7 +12,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
tassert "github.com/stretchr/testify/assert" trequire "github.com/stretchr/testify/require"
"oss.terrastruct.com/util-go/assert" "oss.terrastruct.com/util-go/assert"
"oss.terrastruct.com/util-go/diff" "oss.terrastruct.com/util-go/diff"
@ -101,18 +101,18 @@ func serde(t *testing.T, tc testCase, ruler *textmeasure.Ruler) {
g, err := d2compiler.Compile("", strings.NewReader(tc.script), &d2compiler.CompileOptions{ g, err := d2compiler.Compile("", strings.NewReader(tc.script), &d2compiler.CompileOptions{
UTF16: false, UTF16: false,
}) })
tassert.Nil(t, err) trequire.Nil(t, err)
if len(g.Objects) > 0 { if len(g.Objects) > 0 {
err = g.SetDimensions(nil, ruler, nil) err = g.SetDimensions(nil, ruler, nil)
tassert.Nil(t, err) trequire.Nil(t, err)
d2near.WithoutConstantNears(ctx, g) d2near.WithoutConstantNears(ctx, g)
d2sequence.WithoutSequenceDiagrams(ctx, g) d2sequence.WithoutSequenceDiagrams(ctx, g)
} }
b, err := d2graph.SerializeGraph(g) b, err := d2graph.SerializeGraph(g)
tassert.Nil(t, err) trequire.Nil(t, err)
var newG d2graph.Graph var newG d2graph.Graph
err = d2graph.DeserializeGraph(b, &newG) err = d2graph.DeserializeGraph(b, &newG)
tassert.Nil(t, err) trequire.Nil(t, err)
} }
func run(t *testing.T, tc testCase) { func run(t *testing.T, tc testCase) {
@ -124,9 +124,7 @@ func run(t *testing.T, tc testCase) {
var err error var err error
if tc.mtexts == nil { if tc.mtexts == nil {
ruler, err = textmeasure.NewRuler() ruler, err = textmeasure.NewRuler()
if !tassert.Nil(t, err) { trequire.Nil(t, err)
return
}
serde(t, tc, ruler) serde(t, tc, ruler)
} }
@ -150,9 +148,7 @@ func run(t *testing.T, tc testCase) {
ThemeID: 0, ThemeID: 0,
Layout: layout, Layout: layout,
}) })
if !tassert.Nil(t, err) { trequire.Nil(t, err)
return
}
if tc.assertions != nil { if tc.assertions != nil {
t.Run("assertions", func(t *testing.T) { t.Run("assertions", func(t *testing.T) {
@ -171,26 +167,19 @@ func run(t *testing.T, tc testCase) {
assert.Success(t, err) assert.Success(t, err)
err = ioutil.WriteFile(pathGotSVG, svgBytes, 0600) err = ioutil.WriteFile(pathGotSVG, svgBytes, 0600)
assert.Success(t, err) assert.Success(t, err)
// if running from e2ereport.sh, we want to keep .got.svg on a failure
forReport := os.Getenv("E2E_REPORT") != ""
if !forReport {
defer os.Remove(pathGotSVG)
}
// Check that it's valid SVG // Check that it's valid SVG
var xmlParsed interface{} var xmlParsed interface{}
err = xml.Unmarshal(svgBytes, &xmlParsed) err = xml.Unmarshal(svgBytes, &xmlParsed)
assert.Success(t, err) assert.Success(t, err)
var err2 error
err = diff.TestdataJSON(filepath.Join(dataPath, "board"), diagram) err = diff.TestdataJSON(filepath.Join(dataPath, "board"), diagram)
assert.Success(t, err)
if os.Getenv("SKIP_SVG_CHECK") == "" { if os.Getenv("SKIP_SVG_CHECK") == "" {
err = diff.Testdata(filepath.Join(dataPath, "sketch"), ".svg", svgBytes) err2 = diff.Testdata(filepath.Join(dataPath, "sketch"), ".svg", svgBytes)
}
assert.Success(t, err) assert.Success(t, err)
} assert.Success(t, err2)
if forReport {
os.Remove(pathGotSVG)
}
} }
} }

View file

@ -444,6 +444,27 @@ group 11: {
} }
b -> c b -> c
`,
},
{
name: "sequence_diagram_ambiguous_edge_group",
script: `
Office chatter: {
shape: sequence_diagram
alice: Alice
bob: Bobby
awkward small talk: {
awkward small talk.ok
alice -> bob: uhm, hi
bob -> alice: oh, hello
icebreaker attempt: {
alice -> bob: what did you have for lunch?
}
unfortunate outcome: {
bob -> alice: that's personal
}
}
}
`, `,
}, },
} }

View file

@ -6,6 +6,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
stdlog "log"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -38,6 +39,7 @@ func main() {
flag.BoolVar(&deltaFlag, "delta", false, "Generate the report only for cases that changed.") flag.BoolVar(&deltaFlag, "delta", false, "Generate the report only for cases that changed.")
flag.StringVar(&testSetFlag, "test-set", "", "Only run set of tests matching this string. e.g. regressions") flag.StringVar(&testSetFlag, "test-set", "", "Only run set of tests matching this string. e.g. regressions")
flag.StringVar(&testCaseFlag, "test-case", "", "Only run tests matching this string. e.g. all_shapes") flag.StringVar(&testCaseFlag, "test-case", "", "Only run tests matching this string. e.g. all_shapes")
skipTests := flag.Bool("skip-tests", false, "Skip running tests first")
flag.BoolVar(&vFlag, "v", false, "verbose") flag.BoolVar(&vFlag, "v", false, "verbose")
flag.Parse() flag.Parse()
@ -52,6 +54,7 @@ func main() {
testDir = "./e2etests" testDir = "./e2etests"
} }
if !*skipTests {
ctx := log.Stderr(context.Background()) ctx := log.Stderr(context.Background())
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel() defer cancel()
@ -64,6 +67,7 @@ func main() {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
log.Debug(ctx, cmd.String()) log.Debug(ctx, cmd.String())
_ = cmd.Run() _ = cmd.Run()
}
var tests []TestItem var tests []TestItem
err := filepath.Walk(filepath.Join(testDir, "testdata"), func(path string, info os.FileInfo, err error) error { err := filepath.Walk(filepath.Join(testDir, "testdata"), func(path string, info os.FileInfo, err error) error {
@ -144,6 +148,13 @@ func main() {
} }
path := os.Getenv("REPORT_OUTPUT") path := os.Getenv("REPORT_OUTPUT")
if path == "" {
path = filepath.Join(testDir, "./out/e2e_report.html")
}
err = os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
stdlog.Fatal(err)
}
f, err := os.Create(path) f, err := os.Create(path)
if err != nil { if err != nil {
panic(fmt.Errorf("error creating file `%s`. %v", path, err)) panic(fmt.Errorf("error creating file `%s`. %v", path, err))

View file

@ -1,16 +1,26 @@
<html> <html>
<title>E2E report</title> <title>E2E report</title>
<body> <body>
<h1>Table of Contents</h1>
<ul>
{{range .Tests}}
<li><a href="#{{.Name}}">{{.Name}}</a></li>
{{end}}
</ul>
<div class="cases"> <div class="cases">
{{range .Tests}} {{range .Tests}}
<div class="case"> <div class="case" id="{{.Name}}">
<h1><a href="../{{.GotSVG}}">{{.Name}}</a></h1> <h1><a href="../../{{.GotSVG}}">{{.Name}}</a></h1>
{{ if .ExpSVG }} {{ if .ExpSVG }}
<h2>Expected</h2> <h2 class="case-exp">Expected</h2>
<img src="../{{.ExpSVG}}" width="100%" />
<h2>Got</h2>
{{ end }} {{ end }}
<img src="../{{.GotSVG}}" width="100%" /> <h2 class="case-got">Got</h2>
<div class="case-img-wrapper">
{{ if .ExpSVG }}
<img src="../../{{.ExpSVG}}" width="100%" />
{{ end }}
<img src="../../{{.GotSVG}}" width="100%" />
</div>
</div> </div>
{{end}} {{end}}
</div> </div>
@ -20,17 +30,24 @@
flex-wrap: wrap; flex-wrap: wrap;
} }
.case { .case {
align-items: center; position: relative;
justify-content: center;
padding: 20px; padding: 20px;
width: 100%;
} }
.case svg { .case-img-wrapper {
width: 400px; display: flex;
height: 400px; align-items: center;
} }
.case pre { .case img {
font-size: 10pt; width: 600px;
width: 400px; }
.case-got {
position: absolute;
left: 600px;
}
.case h2 {
margin: 0;
display: inline;
} }
</style> </style>
</body> </body>

View file

@ -79,23 +79,23 @@ callout -> stored_data -> person
diamond -> oval -> circle diamond -> oval -> circle
hexagon -> cloud hexagon -> cloud
rectangle.multiple: true rectangle.style.multiple: true
square.multiple: true square.style.multiple: true
page.multiple: true page.style.multiple: true
parallelogram.multiple: true parallelogram.style.multiple: true
document.multiple: true document.style.multiple: true
cylinder.multiple: true cylinder.style.multiple: true
queue.multiple: true queue.style.multiple: true
package.multiple: true package.style.multiple: true
step.multiple: true step.style.multiple: true
callout.multiple: true callout.style.multiple: true
stored_data.multiple: true stored_data.style.multiple: true
person.multiple: true person.style.multiple: true
diamond.multiple: true diamond.style.multiple: true
oval.multiple: true oval.style.multiple: true
circle.multiple: true circle.style.multiple: true
hexagon.multiple: true hexagon.style.multiple: true
cloud.multiple: true cloud.style.multiple: true
`, `,
}, },
{ {
@ -126,23 +126,23 @@ callout -> stored_data -> person
diamond -> oval -> circle diamond -> oval -> circle
hexagon -> cloud hexagon -> cloud
rectangle.shadow: true rectangle.style.shadow: true
square.shadow: true square.style.shadow: true
page.shadow: true page.style.shadow: true
parallelogram.shadow: true parallelogram.style.shadow: true
document.shadow: true document.style.shadow: true
cylinder.shadow: true cylinder.style.shadow: true
queue.shadow: true queue.style.shadow: true
package.shadow: true package.style.shadow: true
step.shadow: true step.style.shadow: true
callout.shadow: true callout.style.shadow: true
stored_data.shadow: true stored_data.style.shadow: true
person.shadow: true person.style.shadow: true
diamond.shadow: true diamond.style.shadow: true
oval.shadow: true oval.style.shadow: true
circle.shadow: true circle.style.shadow: true
hexagon.shadow: true hexagon.style.shadow: true
cloud.shadow: true cloud.style.shadow: true
`, `,
}, },
{ {
@ -153,8 +153,8 @@ square: {shape: "square"}
rectangle -> square rectangle -> square
rectangle.3d: true rectangle.style.3d: true
square.3d: true square.style.3d: true
`, `,
}, },
{ {
@ -1109,17 +1109,17 @@ scorer.t -> itemOutcome.t3: setFeedback(missingConcepts)`,
script: `shape: sequence_diagram script: `shape: sequence_diagram
scorer: { scorer: {
stroke: red style.stroke: red
stroke-width: 5 style.stroke-width: 5
} }
scorer.abc: { scorer.abc: {
fill: yellow style.fill: yellow
stroke-width: 7 style.stroke-width: 7
} }
scorer -> itemResponse.a: { scorer -> itemResponse.a: {
stroke-width: 10 style.stroke-width: 10
} }
itemResponse.a -> item.a.b itemResponse.a -> item.a.b
item.a.b -> essayRubric.a.b.c item.a.b -> essayRubric.a.b.c
@ -1877,6 +1877,62 @@ a.sp1 -> a.sp2: redirect
a.sp2 -> b: bar a.sp2 -> b: bar
`, `,
}, },
{
name: "complex-layers",
script: `
desc: Multi-layer diagram of a home.
window: {
style.double-border: true
}
roof
garage
layers: {
window: {
blinds
glass
}
roof: {
shingles
starlink
utility hookup
}
garage: {
tools
vehicles
}
repair: {
desc: How to repair a home.
steps: {
1: {
find contractors: {
craigslist
facebook
}
}
2: {
find contractors -> solicit quotes
}
3: {
obtain quotes -> negotiate
}
4: {
negotiate -> book the best bid
}
}
}
}
scenarios: {
storm: {
water
rain
thunder
}
}`,
},
} }
runa(t, tcs) runa(t, tcs)

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0

View file

@ -39,7 +39,7 @@ width="304" height="304" viewBox="-102 -102 304 304"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="a"><g class="shape" ><rect x="0" y="0" width="100" height="100" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g></g><mask id="3624597608" maskUnits="userSpaceOnUse" x="-100" y="-100" width="304" height="304"> ]]></script><g id="a"><g class="shape" ><rect x="0" y="0" width="100" height="100" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g></g><mask id="4175712569" maskUnits="userSpaceOnUse" x="-100" y="-100" width="304" height="304">
<rect x="-100" y="-100" width="304" height="304" fill="white"></rect> <rect x="-100" y="-100" width="304" height="304" fill="white"></rect>
</mask><style type="text/css"><![CDATA[]]></style></svg> </mask><style type="text/css"><![CDATA[]]></style></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -43,91 +43,9 @@
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
{
"id": "a.c",
"type": "",
"pos": {
"x": 40,
"y": 359
},
"width": 478,
"height": 235,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "white",
"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": 24,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 15,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.c.d",
"type": "",
"pos": {
"x": 236,
"y": 413
},
"width": 114,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 14,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 3
},
{ {
"id": "a.b", "id": "a.b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 64, "x": 64,
"y": 55 "y": 55
@ -166,9 +84,50 @@
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
}, },
{
"id": "a.c",
"type": "rectangle",
"pos": {
"x": 40,
"y": 359
},
"width": 478,
"height": 235,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "white",
"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": 24,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 15,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
{ {
"id": "a.1", "id": "a.1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 237, "x": 237,
"y": 55 "y": 55
@ -209,7 +168,7 @@
}, },
{ {
"id": "a.2", "id": "a.2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 409, "x": 409,
"y": 55 "y": 55
@ -247,6 +206,47 @@
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
},
{
"id": "a.c.d",
"type": "rectangle",
"pos": {
"x": 236,
"y": 413
},
"width": 114,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 14,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 3
} }
], ],
"connections": [ "connections": [

View file

@ -39,7 +39,7 @@ width="775" height="852" viewBox="-102 -102 775 852"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="a"><g class="shape" ><rect x="0" y="0" width="571" height="648" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="285.500000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.c"><g class="shape" ><rect x="40" y="359" width="478" height="235" style="fill:#EDF0FD;stroke:white;stroke-width:2;" /></g><text class="text" x="279.000000" y="388.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">c</text></g><g id="a.b"><g class="shape" ><rect x="64" y="55" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="120.500000" y="121.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="a.1"><g class="shape" ><rect x="237" y="55" width="112" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="293.000000" y="121.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">1</text></g><g id="a.2"><g class="shape" ><rect x="409" y="55" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="465.500000" y="121.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">2</text></g><g id="a.c.d"><g class="shape" ><rect x="236" y="413" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="293.000000" y="479.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="a.(b -&gt; c)[0]"><marker id="mk-1065319532" markerWidth="24.200000" markerHeight="18.000000" refX="20.800000" refY="9.000000" viewBox="0.000000 0.000000 24.200000 18.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="white" stroke="red" stroke-width="2" points="0.000000,9.000000 11.000000,2.250000 22.000000,9.000000 11.000000,16.200000" /> </marker><path d="M 120.000000 183.500000 C 120.000000 251.900000 120.000000 287.500000 120.000000 355.500000" class="connection" style="fill:none;stroke:red;stroke-width:2;" marker-end="url(#mk-1065319532)" mask="url(#1474862432)"/><text class="text-italic" x="120.000000" y="252.000000" style="text-anchor:middle;font-size:16px;fill:red"><tspan x="120.000000" dy="0.000000">line 1</tspan><tspan x="120.000000" dy="17.250000">line 2</tspan><tspan x="120.000000" dy="17.250000">line 3</tspan><tspan x="120.000000" dy="17.250000">line 4</tspan></text></g><g id="a.(1 -&gt; c)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 292.500000 183.500000 C 292.500000 251.900000 292.500000 287.500000 292.500000 355.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1474862432)"/></g><g id="a.(2 &lt;-&gt; c)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 465.000000 185.500000 C 465.000000 251.900000 465.000000 287.500000 465.000000 355.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#1474862432)"/></g><mask id="1474862432" maskUnits="userSpaceOnUse" x="-100" y="-100" width="775" height="852"> ]]></script><g id="a"><g class="shape" ><rect x="0" y="0" width="571" height="648" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="285.500000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.b"><g class="shape" ><rect x="64" y="55" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="120.500000" y="121.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="a.c"><g class="shape" ><rect x="40" y="359" width="478" height="235" style="fill:#EDF0FD;stroke:white;stroke-width:2;" /></g><text class="text" x="279.000000" y="388.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">c</text></g><g id="a.1"><g class="shape" ><rect x="237" y="55" width="112" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="293.000000" y="121.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">1</text></g><g id="a.2"><g class="shape" ><rect x="409" y="55" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="465.500000" y="121.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">2</text></g><g id="a.c.d"><g class="shape" ><rect x="236" y="413" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="293.000000" y="479.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="a.(b -&gt; c)[0]"><marker id="mk-1065319532" markerWidth="24.200000" markerHeight="18.000000" refX="20.800000" refY="9.000000" viewBox="0.000000 0.000000 24.200000 18.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="white" stroke="red" stroke-width="2" points="0.000000,9.000000 11.000000,2.250000 22.000000,9.000000 11.000000,16.200000" /> </marker><path d="M 120.000000 183.500000 C 120.000000 251.900000 120.000000 287.500000 120.000000 355.500000" class="connection" style="fill:none;stroke:red;stroke-width:2;" marker-end="url(#mk-1065319532)" mask="url(#3375972788)"/><text class="text-italic" x="120.000000" y="252.000000" style="text-anchor:middle;font-size:16px;fill:red"><tspan x="120.000000" dy="0.000000">line 1</tspan><tspan x="120.000000" dy="17.250000">line 2</tspan><tspan x="120.000000" dy="17.250000">line 3</tspan><tspan x="120.000000" dy="17.250000">line 4</tspan></text></g><g id="a.(1 -&gt; c)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 292.500000 183.500000 C 292.500000 251.900000 292.500000 287.500000 292.500000 355.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3375972788)"/></g><g id="a.(2 &lt;-&gt; c)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 465.000000 185.500000 C 465.000000 251.900000 465.000000 287.500000 465.000000 355.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#3375972788)"/></g><mask id="3375972788" maskUnits="userSpaceOnUse" x="-100" y="-100" width="775" height="852">
<rect x="-100" y="-100" width="775" height="852" fill="white"></rect> <rect x="-100" y="-100" width="775" height="852" fill="white"></rect>
<rect x="102.000000" y="236.000000" width="36" height="69" fill="black"></rect> <rect x="102.000000" y="236.000000" width="36" height="69" fill="black"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 794 KiB

After

Width:  |  Height:  |  Size: 794 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -43,91 +43,9 @@
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
{
"id": "a.c",
"type": "",
"pos": {
"x": 106,
"y": 539
},
"width": 264,
"height": 276,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "white",
"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": 24,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 15,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "a.c.d",
"type": "",
"pos": {
"x": 181,
"y": 614
},
"width": 114,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 14,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 3
},
{ {
"id": "a.b", "id": "a.b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 87, "x": 87,
"y": 87 "y": 87
@ -166,9 +84,50 @@
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
}, },
{
"id": "a.c",
"type": "rectangle",
"pos": {
"x": 106,
"y": 539
},
"width": 264,
"height": 276,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "white",
"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": 24,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 15,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 2
},
{ {
"id": "a.1", "id": "a.1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 182, "x": 182,
"y": 313 "y": 313
@ -209,7 +168,7 @@
}, },
{ {
"id": "a.2", "id": "a.2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 314, "x": 314,
"y": 313 "y": 313
@ -247,6 +206,47 @@
"labelPosition": "INSIDE_MIDDLE_CENTER", "labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0, "zIndex": 0,
"level": 2 "level": 2
},
{
"id": "a.c.d",
"type": "rectangle",
"pos": {
"x": 181,
"y": 614
},
"width": 114,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#F7F8FE",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 14,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 3
} }
], ],
"connections": [ "connections": [

View file

@ -39,7 +39,7 @@ width="694" height="1082" viewBox="-90 -90 694 1082"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="a"><g class="shape" ><rect x="12" y="12" width="490" height="878" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="257.000000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.c"><g class="shape" ><rect x="106" y="539" width="264" height="276" style="fill:#EDF0FD;stroke:white;stroke-width:2;" /></g><text class="text" x="238.000000" y="568.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">c</text></g><g id="a.b"><g class="shape" ><rect x="87" y="87" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="143.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="a.1"><g class="shape" ><rect x="182" y="313" width="112" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="238.000000" y="379.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">1</text></g><g id="a.2"><g class="shape" ><rect x="314" y="313" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="370.500000" y="379.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">2</text></g><g id="a.c.d"><g class="shape" ><rect x="181" y="614" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="238.000000" y="680.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="a.(b -&gt; c)[0]"><marker id="mk-1065319532" markerWidth="24.200000" markerHeight="18.000000" refX="20.800000" refY="9.000000" viewBox="0.000000 0.000000 24.200000 18.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="white" stroke="red" stroke-width="2" points="0.000000,9.000000 11.000000,2.250000 22.000000,9.000000 11.000000,16.200000" /> </marker><path d="M 143.500000 215.000000 L 143.500000 479.000000 S 143.500000 489.000000 153.500000 489.000000 L 162.500000 489.000000 S 172.500000 489.000000 172.500000 499.000000 L 172.500000 535.000000" class="connection" style="fill:none;stroke:red;stroke-width:2;" marker-end="url(#mk-1065319532)" mask="url(#3390014606)"/><text class="text-italic" x="144.000000" y="372.000000" style="text-anchor:middle;font-size:16px;fill:red"><tspan x="144.000000" dy="0.000000">line 1</tspan><tspan x="144.000000" dy="17.250000">line 2</tspan><tspan x="144.000000" dy="17.250000">line 3</tspan><tspan x="144.000000" dy="17.250000">line 4</tspan></text></g><g id="a.(1 -&gt; c)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 238.500000 441.000000 L 238.500000 535.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3390014606)"/></g><g id="a.(2 &lt;-&gt; c)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 371.000000 443.000000 L 371.000000 479.000000 S 371.000000 489.000000 361.000000 489.000000 L 314.500000 489.000000 S 304.500000 489.000000 304.500000 499.000000 L 304.500000 535.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#3390014606)"/></g><mask id="3390014606" maskUnits="userSpaceOnUse" x="-100" y="-100" width="694" height="1082"> ]]></script><g id="a"><g class="shape" ><rect x="12" y="12" width="490" height="878" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="257.000000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">a</text></g><g id="a.b"><g class="shape" ><rect x="87" y="87" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="143.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="a.c"><g class="shape" ><rect x="106" y="539" width="264" height="276" style="fill:#EDF0FD;stroke:white;stroke-width:2;" /></g><text class="text" x="238.000000" y="568.000000" style="text-anchor:middle;font-size:24px;fill:#0A0F25">c</text></g><g id="a.1"><g class="shape" ><rect x="182" y="313" width="112" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="238.000000" y="379.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">1</text></g><g id="a.2"><g class="shape" ><rect x="314" y="313" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="370.500000" y="379.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">2</text></g><g id="a.c.d"><g class="shape" ><rect x="181" y="614" width="114" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="238.000000" y="680.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="a.(b -&gt; c)[0]"><marker id="mk-1065319532" markerWidth="24.200000" markerHeight="18.000000" refX="20.800000" refY="9.000000" viewBox="0.000000 0.000000 24.200000 18.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="white" stroke="red" stroke-width="2" points="0.000000,9.000000 11.000000,2.250000 22.000000,9.000000 11.000000,16.200000" /> </marker><path d="M 143.500000 215.000000 L 143.500000 479.000000 S 143.500000 489.000000 153.500000 489.000000 L 162.500000 489.000000 S 172.500000 489.000000 172.500000 499.000000 L 172.500000 535.000000" class="connection" style="fill:none;stroke:red;stroke-width:2;" marker-end="url(#mk-1065319532)" mask="url(#417073356)"/><text class="text-italic" x="144.000000" y="372.000000" style="text-anchor:middle;font-size:16px;fill:red"><tspan x="144.000000" dy="0.000000">line 1</tspan><tspan x="144.000000" dy="17.250000">line 2</tspan><tspan x="144.000000" dy="17.250000">line 3</tspan><tspan x="144.000000" dy="17.250000">line 4</tspan></text></g><g id="a.(1 -&gt; c)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 238.500000 441.000000 L 238.500000 535.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#417073356)"/></g><g id="a.(2 &lt;-&gt; c)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 371.000000 443.000000 L 371.000000 479.000000 S 371.000000 489.000000 361.000000 489.000000 L 314.500000 489.000000 S 304.500000 489.000000 304.500000 499.000000 L 304.500000 535.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#417073356)"/></g><mask id="417073356" maskUnits="userSpaceOnUse" x="-100" y="-100" width="694" height="1082">
<rect x="-100" y="-100" width="694" height="1082" fill="white"></rect> <rect x="-100" y="-100" width="694" height="1082" fill="white"></rect>
<rect x="126.000000" y="356.000000" width="36" height="69" fill="black"></rect> <rect x="126.000000" y="356.000000" width="36" height="69" fill="black"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 794 KiB

After

Width:  |  Height:  |  Size: 794 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "build_workflow", "id": "build_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -45,7 +45,7 @@
}, },
{ {
"id": "build_workflow.push", "id": "build_workflow.push",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 105, "x": 105,
"y": 50 "y": 50
@ -86,7 +86,7 @@
}, },
{ {
"id": "build_workflow.GHA", "id": "build_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 698, "x": 698,
"y": 50 "y": 50
@ -127,7 +127,7 @@
}, },
{ {
"id": "build_workflow.S3", "id": "build_workflow.S3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1314, "x": 1314,
"y": 50 "y": 50
@ -168,7 +168,7 @@
}, },
{ {
"id": "build_workflow.Terraform", "id": "build_workflow.Terraform",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1773, "x": 1773,
"y": 50 "y": 50
@ -209,7 +209,7 @@
}, },
{ {
"id": "build_workflow.AWS", "id": "build_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 2369, "x": 2369,
"y": 50 "y": 50

View file

@ -39,7 +39,7 @@ width="2832" height="441" viewBox="-102 -102 2832 441"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="build_workflow"><g class="shape" ><rect x="0" y="0" width="2628" height="237" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="1314.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">lambda-build.yaml</text></g><g id="build_workflow.push"><g class="shape" ><rect x="105" y="50" width="330" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="270.000000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Push to main branch</text></g><g id="build_workflow.GHA"><g class="shape" ><rect x="698" y="50" width="269" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="832.500000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">GitHub Actions</text></g><g id="build_workflow.S3"><g class="shape" ><rect x="1314" y="50" width="131" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1379.500000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">S3</text></g><g id="build_workflow.Terraform"><g class="shape" ><rect x="1773" y="50" width="218" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1882.000000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Terraform</text></g><g id="build_workflow.AWS"><g class="shape" ><rect x="2369" y="50" width="155" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="2446.500000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">AWS</text></g><g id="build_workflow.(push -&gt; GHA)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 437.500000 118.500000 C 539.900000 118.500000 592.300000 118.500000 693.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#351638657)"/><text class="text-italic" x="567.000000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Triggers</text></g><g id="build_workflow.(GHA -&gt; S3)[0]"><path d="M 968.500000 118.500000 C 1105.300000 118.500000 1174.700000 118.500000 1309.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#351638657)"/><text class="text-italic" x="1140.000000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Builds zip &amp; pushes it</text></g><g id="build_workflow.(S3 &lt;-&gt; Terraform)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 1449.500000 118.500000 C 1575.900000 118.500000 1641.300000 118.500000 1768.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#351638657)"/><text class="text-italic" x="1609.500000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Pulls zip to deploy</text></g><g id="build_workflow.(Terraform -&gt; AWS)[0]"><path d="M 1993.500000 118.500000 C 2141.900000 118.500000 2217.300000 118.500000 2364.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#351638657)"/><text class="text-italic" x="2180.500000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Changes the live lambdas</text></g><mask id="351638657" maskUnits="userSpaceOnUse" x="-100" y="-100" width="2832" height="441"> ]]></script><g id="build_workflow"><g class="shape" ><rect x="0" y="0" width="2628" height="237" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="1314.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">lambda-build.yaml</text></g><g id="build_workflow.push"><g class="shape" ><rect x="105" y="50" width="330" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="270.000000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Push to main branch</text></g><g id="build_workflow.GHA"><g class="shape" ><rect x="698" y="50" width="269" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="832.500000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">GitHub Actions</text></g><g id="build_workflow.S3"><g class="shape" ><rect x="1314" y="50" width="131" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1379.500000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">S3</text></g><g id="build_workflow.Terraform"><g class="shape" ><rect x="1773" y="50" width="218" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1882.000000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Terraform</text></g><g id="build_workflow.AWS"><g class="shape" ><rect x="2369" y="50" width="155" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="2446.500000" y="125.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">AWS</text></g><g id="build_workflow.(push -&gt; GHA)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 437.500000 118.500000 C 539.900000 118.500000 592.300000 118.500000 693.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3697729349)"/><text class="text-italic" x="567.000000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Triggers</text></g><g id="build_workflow.(GHA -&gt; S3)[0]"><path d="M 968.500000 118.500000 C 1105.300000 118.500000 1174.700000 118.500000 1309.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3697729349)"/><text class="text-italic" x="1140.000000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Builds zip &amp; pushes it</text></g><g id="build_workflow.(S3 &lt;-&gt; Terraform)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 1449.500000 118.500000 C 1575.900000 118.500000 1641.300000 118.500000 1768.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#3697729349)"/><text class="text-italic" x="1609.500000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Pulls zip to deploy</text></g><g id="build_workflow.(Terraform -&gt; AWS)[0]"><path d="M 1993.500000 118.500000 C 2141.900000 118.500000 2217.300000 118.500000 2364.500000 118.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3697729349)"/><text class="text-italic" x="2180.500000" y="124.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Changes the live lambdas</text></g><mask id="3697729349" maskUnits="userSpaceOnUse" x="-100" y="-100" width="2832" height="441">
<rect x="-100" y="-100" width="2832" height="441" fill="white"></rect> <rect x="-100" y="-100" width="2832" height="441" fill="white"></rect>
<rect x="540.000000" y="108.000000" width="54" height="21" fill="black"></rect> <rect x="540.000000" y="108.000000" width="54" height="21" fill="black"></rect>
<rect x="1071.000000" y="108.000000" width="138" height="21" fill="black"></rect> <rect x="1071.000000" y="108.000000" width="138" height="21" fill="black"></rect>

Before

Width:  |  Height:  |  Size: 795 KiB

After

Width:  |  Height:  |  Size: 795 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "build_workflow", "id": "build_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -45,7 +45,7 @@
}, },
{ {
"id": "build_workflow.push", "id": "build_workflow.push",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 87, "x": 87,
"y": 87 "y": 87
@ -86,7 +86,7 @@
}, },
{ {
"id": "build_workflow.GHA", "id": "build_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 671, "x": 671,
"y": 87 "y": 87
@ -127,7 +127,7 @@
}, },
{ {
"id": "build_workflow.S3", "id": "build_workflow.S3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1278, "x": 1278,
"y": 87 "y": 87
@ -168,7 +168,7 @@
}, },
{ {
"id": "build_workflow.Terraform", "id": "build_workflow.Terraform",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1728, "x": 1728,
"y": 87 "y": 87
@ -209,7 +209,7 @@
}, },
{ {
"id": "build_workflow.AWS", "id": "build_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 2315, "x": 2315,
"y": 87 "y": 87

View file

@ -39,7 +39,7 @@ width="2737" height="491" viewBox="-90 -90 2737 491"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="build_workflow"><g class="shape" ><rect x="12" y="12" width="2533" height="287" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="1278.500000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">lambda-build.yaml</text></g><g id="build_workflow.push"><g class="shape" ><rect x="87" y="87" width="330" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="252.000000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Push to main branch</text></g><g id="build_workflow.GHA"><g class="shape" ><rect x="671" y="87" width="269" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="805.500000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">GitHub Actions</text></g><g id="build_workflow.S3"><g class="shape" ><rect x="1278" y="87" width="131" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1343.500000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">S3</text></g><g id="build_workflow.Terraform"><g class="shape" ><rect x="1728" y="87" width="218" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1837.000000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Terraform</text></g><g id="build_workflow.AWS"><g class="shape" ><rect x="2315" y="87" width="155" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="2392.500000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">AWS</text></g><g id="build_workflow.(push -&gt; GHA)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 419.000000 155.500000 L 667.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1057310123)"/><text class="text-italic" x="544.000000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Triggers</text></g><g id="build_workflow.(GHA -&gt; S3)[0]"><path d="M 942.000000 155.500000 L 1274.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1057310123)"/><text class="text-italic" x="1109.000000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Builds zip &amp; pushes it</text></g><g id="build_workflow.(S3 &lt;-&gt; Terraform)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 1413.000000 155.500000 L 1724.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#1057310123)"/><text class="text-italic" x="1568.500000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Pulls zip to deploy</text></g><g id="build_workflow.(Terraform -&gt; AWS)[0]"><path d="M 1948.000000 155.500000 L 2311.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1057310123)"/><text class="text-italic" x="2130.500000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Changes the live lambdas</text></g><mask id="1057310123" maskUnits="userSpaceOnUse" x="-100" y="-100" width="2737" height="491"> ]]></script><g id="build_workflow"><g class="shape" ><rect x="12" y="12" width="2533" height="287" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="1278.500000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">lambda-build.yaml</text></g><g id="build_workflow.push"><g class="shape" ><rect x="87" y="87" width="330" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="252.000000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Push to main branch</text></g><g id="build_workflow.GHA"><g class="shape" ><rect x="671" y="87" width="269" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="805.500000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">GitHub Actions</text></g><g id="build_workflow.S3"><g class="shape" ><rect x="1278" y="87" width="131" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1343.500000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">S3</text></g><g id="build_workflow.Terraform"><g class="shape" ><rect x="1728" y="87" width="218" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1837.000000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">Terraform</text></g><g id="build_workflow.AWS"><g class="shape" ><rect x="2315" y="87" width="155" height="137" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="2392.500000" y="162.000000" style="text-anchor:middle;font-size:25px;fill:#0A0F25">AWS</text></g><g id="build_workflow.(push -&gt; GHA)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 419.000000 155.500000 L 667.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2089705521)"/><text class="text-italic" x="544.000000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Triggers</text></g><g id="build_workflow.(GHA -&gt; S3)[0]"><path d="M 942.000000 155.500000 L 1274.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2089705521)"/><text class="text-italic" x="1109.000000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Builds zip &amp; pushes it</text></g><g id="build_workflow.(S3 &lt;-&gt; Terraform)[0]"><marker id="mk-2510427236" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" /> </marker><path d="M 1413.000000 155.500000 L 1724.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-start="url(#mk-2510427236)" marker-end="url(#mk-3990223579)" mask="url(#2089705521)"/><text class="text-italic" x="1568.500000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Pulls zip to deploy</text></g><g id="build_workflow.(Terraform -&gt; AWS)[0]"><path d="M 1948.000000 155.500000 L 2311.000000 155.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2089705521)"/><text class="text-italic" x="2130.500000" y="161.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">Changes the live lambdas</text></g><mask id="2089705521" maskUnits="userSpaceOnUse" x="-100" y="-100" width="2737" height="491">
<rect x="-100" y="-100" width="2737" height="491" fill="white"></rect> <rect x="-100" y="-100" width="2737" height="491" fill="white"></rect>
<rect x="517.000000" y="145.000000" width="54" height="21" fill="black"></rect> <rect x="517.000000" y="145.000000" width="54" height="21" fill="black"></rect>
<rect x="1040.000000" y="145.000000" width="138" height="21" fill="black"></rect> <rect x="1040.000000" y="145.000000" width="138" height="21" fill="black"></rect>

Before

Width:  |  Height:  |  Size: 795 KiB

After

Width:  |  Height:  |  Size: 795 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "\"ninety\\nnine\"", "id": "\"ninety\\nnine\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -45,7 +45,7 @@
}, },
{ {
"id": "eighty\reight", "id": "eighty\reight",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 211, "x": 211,
"y": 8 "y": 8
@ -86,7 +86,7 @@
}, },
{ {
"id": "\"seventy\r\\nseven\"", "id": "\"seventy\r\\nseven\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 422, "x": 422,
"y": 0 "y": 0
@ -127,7 +127,7 @@
}, },
{ {
"id": "\"a\\\\yode\"", "id": "\"a\\\\yode\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 644, "x": 644,
"y": 8 "y": 8
@ -168,7 +168,7 @@
}, },
{ {
"id": "there", "id": "there",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 864, "x": 864,
"y": 242 "y": 242
@ -209,7 +209,7 @@
}, },
{ {
"id": "'a\\\"ode'", "id": "'a\\\"ode'",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 858, "x": 858,
"y": 8 "y": 8
@ -250,7 +250,7 @@
}, },
{ {
"id": "\"a\\\\node\"", "id": "\"a\\\\node\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1072, "x": 1072,
"y": 8 "y": 8

View file

@ -39,7 +39,7 @@ width="1431" height="572" viewBox="-102 -102 1431 572"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="&#34;ninety\nnine&#34;"><g class="shape" ><rect x="0" y="0" width="151" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="75.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="75.500000" dy="0.000000">ninety</tspan><tspan x="75.500000" dy="21.000000">nine</tspan></text></g><g id="eighty&#xD;eight"><g class="shape" ><rect x="211" y="8" width="151" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="286.500000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">eighty&#xD;eight</text></g><g id="&#34;seventy&#xD;\nseven&#34;"><g class="shape" ><rect x="422" y="0" width="162" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="503.000000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="503.000000" dy="0.000000">seventy&#xD;</tspan><tspan x="503.000000" dy="21.000000">seven</tspan></text></g><g id="&#34;a\\yode&#34;"><g class="shape" ><rect x="644" y="8" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="721.000000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\yode</text></g><g id="there"><g class="shape" ><rect x="864" y="242" width="143" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="935.500000" y="308.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">there</text></g><g id="&#39;a\&#34;ode&#39;"><g class="shape" ><rect x="858" y="8" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="935.000000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\&#34;ode</text></g><g id="&#34;a\\node&#34;"><g class="shape" ><rect x="1072" y="8" width="155" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1149.500000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\node</text></g><g id="(&#34;a\\yode&#34; -&gt; there)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 721.000000 136.000000 C 721.000000 180.400000 749.500000 207.049065 859.962840 265.377574" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1203581638)"/></g><g id="(&#39;a\&#34;ode&#39; -&gt; there)[0]"><path d="M 935.000000 136.000000 C 935.000000 180.400000 935.000000 202.000000 935.000000 238.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1203581638)"/></g><g id="(&#34;a\\node&#34; -&gt; there)[0]"><path d="M 1149.500000 136.000000 C 1149.500000 180.400000 1120.900000 207.000000 1010.042356 265.142121" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1203581638)"/></g><mask id="1203581638" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1431" height="572"> ]]></script><g id="&#34;ninety\nnine&#34;"><g class="shape" ><rect x="0" y="0" width="151" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="75.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="75.500000" dy="0.000000">ninety</tspan><tspan x="75.500000" dy="21.000000">nine</tspan></text></g><g id="eighty&#xD;eight"><g class="shape" ><rect x="211" y="8" width="151" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="286.500000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">eighty&#xD;eight</text></g><g id="&#34;seventy&#xD;\nseven&#34;"><g class="shape" ><rect x="422" y="0" width="162" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="503.000000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="503.000000" dy="0.000000">seventy&#xD;</tspan><tspan x="503.000000" dy="21.000000">seven</tspan></text></g><g id="&#34;a\\yode&#34;"><g class="shape" ><rect x="644" y="8" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="721.000000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\yode</text></g><g id="there"><g class="shape" ><rect x="864" y="242" width="143" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="935.500000" y="308.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">there</text></g><g id="&#39;a\&#34;ode&#39;"><g class="shape" ><rect x="858" y="8" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="935.000000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\&#34;ode</text></g><g id="&#34;a\\node&#34;"><g class="shape" ><rect x="1072" y="8" width="155" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1149.500000" y="74.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\node</text></g><g id="(&#34;a\\yode&#34; -&gt; there)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 721.000000 136.000000 C 721.000000 180.400000 749.500000 207.049065 859.962840 265.377574" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2074513119)"/></g><g id="(&#39;a\&#34;ode&#39; -&gt; there)[0]"><path d="M 935.000000 136.000000 C 935.000000 180.400000 935.000000 202.000000 935.000000 238.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2074513119)"/></g><g id="(&#34;a\\node&#34; -&gt; there)[0]"><path d="M 1149.500000 136.000000 C 1149.500000 180.400000 1120.900000 207.000000 1010.042356 265.142121" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2074513119)"/></g><mask id="2074513119" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1431" height="572">
<rect x="-100" y="-100" width="1431" height="572" fill="white"></rect> <rect x="-100" y="-100" width="1431" height="572" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 327 KiB

After

Width:  |  Height:  |  Size: 327 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "\"ninety\\nnine\"", "id": "\"ninety\\nnine\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -45,7 +45,7 @@
}, },
{ {
"id": "eighty\reight", "id": "eighty\reight",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 183, "x": 183,
"y": 20 "y": 20
@ -86,7 +86,7 @@
}, },
{ {
"id": "\"seventy\r\\nseven\"", "id": "\"seventy\r\\nseven\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 354, "x": 354,
"y": 12 "y": 12
@ -127,7 +127,7 @@
}, },
{ {
"id": "\"a\\\\yode\"", "id": "\"a\\\\yode\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 536, "x": 536,
"y": 28 "y": 28
@ -168,7 +168,7 @@
}, },
{ {
"id": "there", "id": "there",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 715, "x": 715,
"y": 254 "y": 254
@ -209,7 +209,7 @@
}, },
{ {
"id": "'a\\\"ode'", "id": "'a\\\"ode'",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 710, "x": 710,
"y": 28 "y": 28
@ -250,7 +250,7 @@
}, },
{ {
"id": "\"a\\\\node\"", "id": "\"a\\\\node\"",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 884, "x": 884,
"y": 28 "y": 28

View file

@ -39,7 +39,7 @@ width="1231" height="572" viewBox="-90 -90 1231 572"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="&#34;ninety\nnine&#34;"><g class="shape" ><rect x="12" y="12" width="151" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="87.500000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="87.500000" dy="0.000000">ninety</tspan><tspan x="87.500000" dy="21.000000">nine</tspan></text></g><g id="eighty&#xD;eight"><g class="shape" ><rect x="183" y="20" width="151" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="258.500000" y="86.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">eighty&#xD;eight</text></g><g id="&#34;seventy&#xD;\nseven&#34;"><g class="shape" ><rect x="354" y="12" width="162" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="435.000000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="435.000000" dy="0.000000">seventy&#xD;</tspan><tspan x="435.000000" dy="21.000000">seven</tspan></text></g><g id="&#34;a\\yode&#34;"><g class="shape" ><rect x="536" y="28" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="613.000000" y="94.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\yode</text></g><g id="there"><g class="shape" ><rect x="715" y="254" width="143" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="786.500000" y="320.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">there</text></g><g id="&#39;a\&#34;ode&#39;"><g class="shape" ><rect x="710" y="28" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="787.000000" y="94.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\&#34;ode</text></g><g id="&#34;a\\node&#34;"><g class="shape" ><rect x="884" y="28" width="155" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="961.500000" y="94.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\node</text></g><g id="(&#34;a\\yode&#34; -&gt; there)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 613.000000 156.000000 L 613.000000 194.000000 S 613.000000 204.000000 623.000000 204.000000 L 741.250000 204.000000 S 751.250000 204.000000 751.250000 214.000000 L 751.250000 250.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3116272567)"/></g><g id="(&#39;a\&#34;ode&#39; -&gt; there)[0]"><path d="M 787.000000 156.000000 L 787.000000 250.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3116272567)"/></g><g id="(&#34;a\\node&#34; -&gt; there)[0]"><path d="M 961.500000 156.000000 L 961.500000 194.000000 S 961.500000 204.000000 951.500000 204.000000 L 832.750000 204.000000 S 822.750000 204.000000 822.750000 214.000000 L 822.750000 250.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3116272567)"/></g><mask id="3116272567" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1231" height="572"> ]]></script><g id="&#34;ninety\nnine&#34;"><g class="shape" ><rect x="12" y="12" width="151" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="87.500000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="87.500000" dy="0.000000">ninety</tspan><tspan x="87.500000" dy="21.000000">nine</tspan></text></g><g id="eighty&#xD;eight"><g class="shape" ><rect x="183" y="20" width="151" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="258.500000" y="86.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">eighty&#xD;eight</text></g><g id="&#34;seventy&#xD;\nseven&#34;"><g class="shape" ><rect x="354" y="12" width="162" height="142" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="435.000000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25"><tspan x="435.000000" dy="0.000000">seventy&#xD;</tspan><tspan x="435.000000" dy="21.000000">seven</tspan></text></g><g id="&#34;a\\yode&#34;"><g class="shape" ><rect x="536" y="28" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="613.000000" y="94.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\yode</text></g><g id="there"><g class="shape" ><rect x="715" y="254" width="143" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="786.500000" y="320.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">there</text></g><g id="&#39;a\&#34;ode&#39;"><g class="shape" ><rect x="710" y="28" width="154" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="787.000000" y="94.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\&#34;ode</text></g><g id="&#34;a\\node&#34;"><g class="shape" ><rect x="884" y="28" width="155" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="961.500000" y="94.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a\node</text></g><g id="(&#34;a\\yode&#34; -&gt; there)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 613.000000 156.000000 L 613.000000 194.000000 S 613.000000 204.000000 623.000000 204.000000 L 741.250000 204.000000 S 751.250000 204.000000 751.250000 214.000000 L 751.250000 250.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#498943364)"/></g><g id="(&#39;a\&#34;ode&#39; -&gt; there)[0]"><path d="M 787.000000 156.000000 L 787.000000 250.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#498943364)"/></g><g id="(&#34;a\\node&#34; -&gt; there)[0]"><path d="M 961.500000 156.000000 L 961.500000 194.000000 S 961.500000 204.000000 951.500000 204.000000 L 832.750000 204.000000 S 822.750000 204.000000 822.750000 214.000000 L 822.750000 250.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#498943364)"/></g><mask id="498943364" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1231" height="572">
<rect x="-100" y="-100" width="1231" height="572" fill="white"></rect> <rect x="-100" y="-100" width="1231" height="572" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "build_workflow", "id": "build_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -45,7 +45,7 @@
}, },
{ {
"id": "build_workflow.push", "id": "build_workflow.push",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 50, "x": 50,
"y": 73 "y": 73
@ -86,7 +86,7 @@
}, },
{ {
"id": "build_workflow.GHA", "id": "build_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 81, "x": 81,
"y": 382 "y": 382
@ -127,7 +127,7 @@
}, },
{ {
"id": "build_workflow.S3", "id": "build_workflow.S3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 150, "x": 150,
"y": 771 "y": 771
@ -168,7 +168,7 @@
}, },
{ {
"id": "build_workflow.Terraform", "id": "build_workflow.Terraform",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 106, "x": 106,
"y": 1153 "y": 1153
@ -209,7 +209,7 @@
}, },
{ {
"id": "build_workflow.AWS", "id": "build_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 138, "x": 138,
"y": 1462 "y": 1462
@ -250,7 +250,7 @@
}, },
{ {
"id": "deploy_workflow", "id": "deploy_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 470, "x": 470,
"y": 0 "y": 0
@ -291,7 +291,7 @@
}, },
{ {
"id": "deploy_workflow.manual", "id": "deploy_workflow.manual",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 520, "x": 520,
"y": 73 "y": 73
@ -332,7 +332,7 @@
}, },
{ {
"id": "deploy_workflow.GHA", "id": "deploy_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 521, "x": 521,
"y": 382 "y": 382
@ -373,7 +373,7 @@
}, },
{ {
"id": "deploy_workflow.AWS", "id": "deploy_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 578, "x": 578,
"y": 771 "y": 771
@ -414,7 +414,7 @@
}, },
{ {
"id": "apollo_workflow", "id": "apollo_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 881, "x": 881,
"y": 0 "y": 0
@ -455,7 +455,7 @@
}, },
{ {
"id": "apollo_workflow.apollo", "id": "apollo_workflow.apollo",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1069, "x": 1069,
"y": 73 "y": 73
@ -496,7 +496,7 @@
}, },
{ {
"id": "apollo_workflow.GHA", "id": "apollo_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1053, "x": 1053,
"y": 382 "y": 382
@ -537,7 +537,7 @@
}, },
{ {
"id": "apollo_workflow.AWS", "id": "apollo_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1110, "x": 1110,
"y": 771 "y": 771

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 799 KiB

After

Width:  |  Height:  |  Size: 799 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "build_workflow", "id": "build_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -45,7 +45,7 @@
}, },
{ {
"id": "build_workflow.push", "id": "build_workflow.push",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 87, "x": 87,
"y": 87 "y": 87
@ -86,7 +86,7 @@
}, },
{ {
"id": "build_workflow.GHA", "id": "build_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 117, "x": 117,
"y": 450 "y": 450
@ -127,7 +127,7 @@
}, },
{ {
"id": "build_workflow.S3", "id": "build_workflow.S3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 186, "x": 186,
"y": 813 "y": 813
@ -168,7 +168,7 @@
}, },
{ {
"id": "build_workflow.Terraform", "id": "build_workflow.Terraform",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 143, "x": 143,
"y": 1176 "y": 1176
@ -209,7 +209,7 @@
}, },
{ {
"id": "build_workflow.AWS", "id": "build_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 174, "x": 174,
"y": 1539 "y": 1539
@ -250,7 +250,7 @@
}, },
{ {
"id": "deploy_workflow", "id": "deploy_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 512, "x": 512,
"y": 335 "y": 335
@ -291,7 +291,7 @@
}, },
{ {
"id": "deploy_workflow.manual", "id": "deploy_workflow.manual",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 587, "x": 587,
"y": 410 "y": 410
@ -332,7 +332,7 @@
}, },
{ {
"id": "deploy_workflow.GHA", "id": "deploy_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 588, "x": 588,
"y": 773 "y": 773
@ -373,7 +373,7 @@
}, },
{ {
"id": "deploy_workflow.AWS", "id": "deploy_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 645, "x": 645,
"y": 1216 "y": 1216
@ -414,7 +414,7 @@
}, },
{ {
"id": "apollo_workflow", "id": "apollo_workflow",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 953, "x": 953,
"y": 375 "y": 375
@ -455,7 +455,7 @@
}, },
{ {
"id": "apollo_workflow.apollo", "id": "apollo_workflow.apollo",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1175, "x": 1175,
"y": 450 "y": 450
@ -496,7 +496,7 @@
}, },
{ {
"id": "apollo_workflow.GHA", "id": "apollo_workflow.GHA",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1160, "x": 1160,
"y": 813 "y": 813
@ -537,7 +537,7 @@
}, },
{ {
"id": "apollo_workflow.AWS", "id": "apollo_workflow.AWS",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1217, "x": 1217,
"y": 1176 "y": 1176

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 799 KiB

After

Width:  |  Height:  |  Size: 799 KiB

View file

@ -55,7 +55,7 @@
}, },
{ {
"id": "ico", "id": "ico",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 188, "x": 188,
"y": 14 "y": 14

View file

@ -39,7 +39,7 @@ width="492" height="332" viewBox="-102 -102 492 332"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="img"><g class="shape" ><image href="https://icons.terrastruct.com/infra/019-network.svg" x="0" y="0" width="128" height="128" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:2;" /></g></g><g id="ico"><g class="shape" ><rect x="188" y="14" width="100" height="100" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg" x="213.000000" y="39.000000" width="50" height="50" /></g><mask id="1658185428" maskUnits="userSpaceOnUse" x="-100" y="-100" width="492" height="332"> ]]></script><g id="img"><g class="shape" ><image href="https://icons.terrastruct.com/infra/019-network.svg" x="0" y="0" width="128" height="128" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:2;" /></g></g><g id="ico"><g class="shape" ><rect x="188" y="14" width="100" height="100" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg" x="213.000000" y="39.000000" width="50" height="50" /></g><mask id="2468208653" maskUnits="userSpaceOnUse" x="-100" y="-100" width="492" height="332">
<rect x="-100" y="-100" width="492" height="332" fill="white"></rect> <rect x="-100" y="-100" width="492" height="332" fill="white"></rect>
</mask><style type="text/css"><![CDATA[]]></style></svg> </mask><style type="text/css"><![CDATA[]]></style></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -55,7 +55,7 @@
}, },
{ {
"id": "ico", "id": "ico",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 160, "x": 160,
"y": 26 "y": 26

View file

@ -39,7 +39,7 @@ width="452" height="332" viewBox="-90 -90 452 332"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="img"><g class="shape" ><image href="https://icons.terrastruct.com/infra/019-network.svg" x="12" y="12" width="128" height="128" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:2;" /></g></g><g id="ico"><g class="shape" ><rect x="160" y="26" width="100" height="100" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg" x="185.000000" y="51.000000" width="50" height="50" /></g><mask id="2006067969" maskUnits="userSpaceOnUse" x="-100" y="-100" width="452" height="332"> ]]></script><g id="img"><g class="shape" ><image href="https://icons.terrastruct.com/infra/019-network.svg" x="12" y="12" width="128" height="128" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:2;" /></g></g><g id="ico"><g class="shape" ><rect x="160" y="26" width="100" height="100" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg" x="185.000000" y="51.000000" width="50" height="50" /></g><mask id="882453984" maskUnits="userSpaceOnUse" x="-100" y="-100" width="452" height="332">
<rect x="-100" y="-100" width="452" height="332" fill="white"></rect> <rect x="-100" y="-100" width="452" height="332" fill="white"></rect>
</mask><style type="text/css"><![CDATA[]]></style></svg> </mask><style type="text/css"><![CDATA[]]></style></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "x", "id": "x",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -45,7 +45,7 @@
}, },
{ {
"id": "x.a", "id": "x.a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 50, "x": 50,
"y": 50 "y": 50
@ -86,7 +86,7 @@
}, },
{ {
"id": "x.b", "id": "x.b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 263, "x": 263,
"y": 50 "y": 50

View file

@ -39,7 +39,7 @@ width="630" height="430" viewBox="-102 -102 630 430"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="x"><g class="shape" ><rect x="0" y="0" width="426" height="226" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="213.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">x</text></g><g id="x.a"><g class="shape" ><rect x="50" y="50" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="106.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="x.b"><g class="shape" ><rect x="263" y="50" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="319.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="x.(a -&gt; a)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 164.637464 72.228272 C 189.666667 54.675325 198.000000 50.000000 200.500000 50.000000 C 203.000000 50.000000 206.333333 62.600000 208.833333 81.500000 C 211.333333 100.400000 211.333333 125.600000 208.833333 144.500000 C 206.333333 163.400000 189.666667 171.324675 166.274928 154.920080" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4032396985)"/></g><mask id="4032396985" maskUnits="userSpaceOnUse" x="-100" y="-100" width="630" height="430"> ]]></script><g id="x"><g class="shape" ><rect x="0" y="0" width="426" height="226" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="213.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">x</text></g><g id="x.a"><g class="shape" ><rect x="50" y="50" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="106.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="x.b"><g class="shape" ><rect x="263" y="50" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="319.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="x.(a -&gt; a)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 164.637464 72.228272 C 189.666667 54.675325 198.000000 50.000000 200.500000 50.000000 C 203.000000 50.000000 206.333333 62.600000 208.833333 81.500000 C 211.333333 100.400000 211.333333 125.600000 208.833333 144.500000 C 206.333333 163.400000 189.666667 171.324675 166.274928 154.920080" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1725002276)"/></g><mask id="1725002276" maskUnits="userSpaceOnUse" x="-100" y="-100" width="630" height="430">
<rect x="-100" y="-100" width="630" height="430" fill="white"></rect> <rect x="-100" y="-100" width="630" height="430" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 649 KiB

After

Width:  |  Height:  |  Size: 649 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "x", "id": "x",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -45,7 +45,7 @@
}, },
{ {
"id": "x.a", "id": "x.a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 137, "x": 137,
"y": 87 "y": 87
@ -86,7 +86,7 @@
}, },
{ {
"id": "x.b", "id": "x.b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 270, "x": 270,
"y": 87 "y": 87

View file

@ -39,7 +39,7 @@ width="650" height="480" viewBox="-90 -90 650 480"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="x"><g class="shape" ><rect x="12" y="12" width="446" height="276" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="235.000000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">x</text></g><g id="x.a"><g class="shape" ><rect x="137" y="87" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="193.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="x.b"><g class="shape" ><rect x="270" y="87" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="326.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="x.(a -&gt; a)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 135.000000 129.000000 L 97.000000 129.000000 S 87.000000 129.000000 87.000000 139.000000 L 87.000000 161.000000 S 87.000000 171.000000 97.000000 171.000000 L 133.000000 171.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#108613724)"/></g><mask id="108613724" maskUnits="userSpaceOnUse" x="-100" y="-100" width="650" height="480"> ]]></script><g id="x"><g class="shape" ><rect x="12" y="12" width="446" height="276" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="235.000000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">x</text></g><g id="x.a"><g class="shape" ><rect x="137" y="87" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="193.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="x.b"><g class="shape" ><rect x="270" y="87" width="113" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="326.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="x.(a -&gt; a)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 135.000000 129.000000 L 97.000000 129.000000 S 87.000000 129.000000 87.000000 139.000000 L 87.000000 161.000000 S 87.000000 171.000000 97.000000 171.000000 L 133.000000 171.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1153458095)"/></g><mask id="1153458095" maskUnits="userSpaceOnUse" x="-100" y="-100" width="650" height="480">
<rect x="-100" y="-100" width="650" height="480" fill="white"></rect> <rect x="-100" y="-100" width="650" height="480" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 649 KiB

After

Width:  |  Height:  |  Size: 649 KiB

View file

@ -44,7 +44,7 @@
}, },
{ {
"id": "queue.M0", "id": "queue.M0",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 50, "x": 50,
"y": 198 "y": 198
@ -85,7 +85,7 @@
}, },
{ {
"id": "queue.M1", "id": "queue.M1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 235, "x": 235,
"y": 198 "y": 198
@ -126,7 +126,7 @@
}, },
{ {
"id": "queue.M2", "id": "queue.M2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 420, "x": 420,
"y": 198 "y": 198
@ -167,7 +167,7 @@
}, },
{ {
"id": "queue.M3", "id": "queue.M3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 605, "x": 605,
"y": 198 "y": 198
@ -208,7 +208,7 @@
}, },
{ {
"id": "queue.M4", "id": "queue.M4",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 790, "x": 790,
"y": 198 "y": 198
@ -249,7 +249,7 @@
}, },
{ {
"id": "queue.M5", "id": "queue.M5",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 976, "x": 976,
"y": 198 "y": 198
@ -290,7 +290,7 @@
}, },
{ {
"id": "queue.M6", "id": "queue.M6",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1161, "x": 1161,
"y": 198 "y": 198

View file

@ -801,7 +801,7 @@ width="1540" height="578" viewBox="-102 -102 1540 578"><style type="text/css">
</div></foreignObject></g></g><g id="m5_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="994.000000" y="12.000000" width="90" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Last message</p> </div></foreignObject></g></g><g id="m5_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="994.000000" y="12.000000" width="90" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Last message</p>
</div></foreignObject></g></g><g id="m6_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="1154.000000" y="0.000000" width="140" height="48"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Next message will be<br /> </div></foreignObject></g></g><g id="m6_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="1154.000000" y="0.000000" width="140" height="48"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Next message will be<br />
inserted here</p> inserted here</p>
</div></foreignObject></g></g><g id="queue.M0"><g class="shape" ><rect x="50" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="112.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M0</text></g><g id="queue.M1"><g class="shape" ><rect x="235" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="297.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M1</text></g><g id="queue.M2"><g class="shape" ><rect x="420" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="482.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M2</text></g><g id="queue.M3"><g class="shape" ><rect x="605" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="667.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M3</text></g><g id="queue.M4"><g class="shape" ><rect x="790" y="198" width="126" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="853.000000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M4</text></g><g id="queue.M5"><g class="shape" ><rect x="976" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1038.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M5</text></g><g id="queue.M6"><g class="shape" ><rect x="1161" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1223.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M6</text></g><g id="(m0_desc -&gt; queue.M0)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 112.500000 38.000000 C 112.500000 85.600000 112.500000 158.000000 112.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2000745678)"/></g><g id="(m2_desc -&gt; queue.M2)[0]"><path d="M 482.500000 38.000000 C 482.500000 85.600000 482.500000 158.000000 482.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2000745678)"/></g><g id="(m5_desc -&gt; queue.M5)[0]"><path d="M 1038.500000 38.000000 C 1038.500000 85.600000 1038.500000 158.000000 1038.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2000745678)"/></g><g id="(m6_desc -&gt; queue.M6)[0]"><path d="M 1223.500000 50.000000 C 1223.500000 88.000000 1223.500000 158.000000 1223.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2000745678)"/></g><mask id="2000745678" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1540" height="578"> </div></foreignObject></g></g><g id="queue.M0"><g class="shape" ><rect x="50" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="112.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M0</text></g><g id="queue.M1"><g class="shape" ><rect x="235" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="297.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M1</text></g><g id="queue.M2"><g class="shape" ><rect x="420" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="482.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M2</text></g><g id="queue.M3"><g class="shape" ><rect x="605" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="667.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M3</text></g><g id="queue.M4"><g class="shape" ><rect x="790" y="198" width="126" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="853.000000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M4</text></g><g id="queue.M5"><g class="shape" ><rect x="976" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1038.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M5</text></g><g id="queue.M6"><g class="shape" ><rect x="1161" y="198" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1223.500000" y="264.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M6</text></g><g id="(m0_desc -&gt; queue.M0)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 112.500000 38.000000 C 112.500000 85.600000 112.500000 158.000000 112.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2449571301)"/></g><g id="(m2_desc -&gt; queue.M2)[0]"><path d="M 482.500000 38.000000 C 482.500000 85.600000 482.500000 158.000000 482.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2449571301)"/></g><g id="(m5_desc -&gt; queue.M5)[0]"><path d="M 1038.500000 38.000000 C 1038.500000 85.600000 1038.500000 158.000000 1038.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2449571301)"/></g><g id="(m6_desc -&gt; queue.M6)[0]"><path d="M 1223.500000 50.000000 C 1223.500000 88.000000 1223.500000 158.000000 1223.500000 194.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2449571301)"/></g><mask id="2449571301" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1540" height="578">
<rect x="-100" y="-100" width="1540" height="578" fill="white"></rect> <rect x="-100" y="-100" width="1540" height="578" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 664 KiB

After

Width:  |  Height:  |  Size: 664 KiB

View file

@ -44,7 +44,7 @@
}, },
{ {
"id": "queue.M0", "id": "queue.M0",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 87, "x": 87,
"y": 240 "y": 240
@ -85,7 +85,7 @@
}, },
{ {
"id": "queue.M1", "id": "queue.M1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 232, "x": 232,
"y": 240 "y": 240
@ -126,7 +126,7 @@
}, },
{ {
"id": "queue.M2", "id": "queue.M2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 377, "x": 377,
"y": 240 "y": 240
@ -167,7 +167,7 @@
}, },
{ {
"id": "queue.M3", "id": "queue.M3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 522, "x": 522,
"y": 240 "y": 240
@ -208,7 +208,7 @@
}, },
{ {
"id": "queue.M4", "id": "queue.M4",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 667, "x": 667,
"y": 240 "y": 240
@ -249,7 +249,7 @@
}, },
{ {
"id": "queue.M5", "id": "queue.M5",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 813, "x": 813,
"y": 240 "y": 240
@ -290,7 +290,7 @@
}, },
{ {
"id": "queue.M6", "id": "queue.M6",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 958, "x": 958,
"y": 240 "y": 240

View file

@ -801,7 +801,7 @@ width="1350" height="633" viewBox="-90 -90 1350 633"><style type="text/css">
</div></foreignObject></g></g><g id="m5_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="830.000000" y="36.000000" width="90" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Last message</p> </div></foreignObject></g></g><g id="m5_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="830.000000" y="36.000000" width="90" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Last message</p>
</div></foreignObject></g></g><g id="m6_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="950.000000" y="12.000000" width="140" height="48"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Next message will be<br /> </div></foreignObject></g></g><g id="m6_desc"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="950.000000" y="12.000000" width="140" height="48"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>Next message will be<br />
inserted here</p> inserted here</p>
</div></foreignObject></g></g><g id="queue.M0"><g class="shape" ><rect x="87" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="149.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M0</text></g><g id="queue.M1"><g class="shape" ><rect x="232" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="294.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M1</text></g><g id="queue.M2"><g class="shape" ><rect x="377" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="439.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M2</text></g><g id="queue.M3"><g class="shape" ><rect x="522" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="584.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M3</text></g><g id="queue.M4"><g class="shape" ><rect x="667" y="240" width="126" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="730.000000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M4</text></g><g id="queue.M5"><g class="shape" ><rect x="813" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="875.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M5</text></g><g id="queue.M6"><g class="shape" ><rect x="958" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1020.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M6</text></g><g id="(m0_desc -&gt; queue.M0)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 149.500000 62.000000 L 149.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1429777714)"/></g><g id="(m2_desc -&gt; queue.M2)[0]"><path d="M 439.500000 62.000000 L 439.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1429777714)"/></g><g id="(m5_desc -&gt; queue.M5)[0]"><path d="M 875.500000 62.000000 L 875.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1429777714)"/></g><g id="(m6_desc -&gt; queue.M6)[0]"><path d="M 1020.500000 62.000000 L 1020.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1429777714)"/></g><mask id="1429777714" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1350" height="633"> </div></foreignObject></g></g><g id="queue.M0"><g class="shape" ><rect x="87" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="149.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M0</text></g><g id="queue.M1"><g class="shape" ><rect x="232" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="294.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M1</text></g><g id="queue.M2"><g class="shape" ><rect x="377" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="439.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M2</text></g><g id="queue.M3"><g class="shape" ><rect x="522" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="584.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M3</text></g><g id="queue.M4"><g class="shape" ><rect x="667" y="240" width="126" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="730.000000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M4</text></g><g id="queue.M5"><g class="shape" ><rect x="813" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="875.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M5</text></g><g id="queue.M6"><g class="shape" ><rect x="958" y="240" width="125" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1020.500000" y="306.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">M6</text></g><g id="(m0_desc -&gt; queue.M0)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 149.500000 62.000000 L 149.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3171385237)"/></g><g id="(m2_desc -&gt; queue.M2)[0]"><path d="M 439.500000 62.000000 L 439.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3171385237)"/></g><g id="(m5_desc -&gt; queue.M5)[0]"><path d="M 875.500000 62.000000 L 875.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3171385237)"/></g><g id="(m6_desc -&gt; queue.M6)[0]"><path d="M 1020.500000 62.000000 L 1020.500000 236.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3171385237)"/></g><mask id="3171385237" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1350" height="633">
<rect x="-100" y="-100" width="1350" height="633" fill="white"></rect> <rect x="-100" y="-100" width="1350" height="633" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 664 KiB

After

Width:  |  Height:  |  Size: 664 KiB

View file

@ -44,7 +44,7 @@
}, },
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -85,7 +85,7 @@
}, },
{ {
"id": "b", "id": "b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 441 "y": 441

View file

@ -804,7 +804,7 @@ width="317" height="771" viewBox="-102 -102 317 771"><style type="text/css">
</ol> </ol>
</li> </li>
</ul> </ul>
</div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="0" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="56.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="b"><g class="shape" ><rect x="0" y="441" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="56.500000" y="507.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="(a -&gt; md)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 56.500000 128.000000 C 56.500000 166.000000 56.500000 186.000000 56.500000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2837502795)"/></g><g id="(md -&gt; b)[0]"><path d="M 56.500000 343.000000 C 56.500000 381.000000 56.500000 401.000000 56.500000 437.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2837502795)"/></g><mask id="2837502795" maskUnits="userSpaceOnUse" x="-100" y="-100" width="317" height="771"> </div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="0" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="56.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="b"><g class="shape" ><rect x="0" y="441" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="56.500000" y="507.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="(a -&gt; md)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 56.500000 128.000000 C 56.500000 166.000000 56.500000 186.000000 56.500000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3337638975)"/></g><g id="(md -&gt; b)[0]"><path d="M 56.500000 343.000000 C 56.500000 381.000000 56.500000 401.000000 56.500000 437.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3337638975)"/></g><mask id="3337638975" maskUnits="userSpaceOnUse" x="-100" y="-100" width="317" height="771">
<rect x="-100" y="-100" width="317" height="771" fill="white"></rect> <rect x="-100" y="-100" width="317" height="771" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 661 KiB

After

Width:  |  Height:  |  Size: 661 KiB

View file

@ -44,7 +44,7 @@
}, },
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -85,7 +85,7 @@
}, },
{ {
"id": "b", "id": "b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 453 "y": 453

View file

@ -804,7 +804,7 @@ width="317" height="771" viewBox="-90 -90 317 771"><style type="text/css">
</ol> </ol>
</li> </li>
</ul> </ul>
</div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="12" y="12" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="68.500000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="b"><g class="shape" ><rect x="12" y="453" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="68.500000" y="519.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="(a -&gt; md)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 68.500000 140.000000 L 68.500000 234.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2378193313)"/></g><g id="(md -&gt; b)[0]"><path d="M 68.500000 355.000000 L 68.500000 449.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2378193313)"/></g><mask id="2378193313" maskUnits="userSpaceOnUse" x="-100" y="-100" width="317" height="771"> </div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="12" y="12" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="68.500000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="b"><g class="shape" ><rect x="12" y="453" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="68.500000" y="519.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="(a -&gt; md)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 68.500000 140.000000 L 68.500000 234.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3073814113)"/></g><g id="(md -&gt; b)[0]"><path d="M 68.500000 355.000000 L 68.500000 449.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3073814113)"/></g><mask id="3073814113" maskUnits="userSpaceOnUse" x="-100" y="-100" width="317" height="771">
<rect x="-100" y="-100" width="317" height="771" fill="white"></rect> <rect x="-100" y="-100" width="317" height="771" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 660 KiB

After

Width:  |  Height:  |  Size: 660 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "x", "id": "x",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 105, "x": 105,
"y": 0 "y": 0
@ -85,7 +85,7 @@
}, },
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 105, "x": 105,
"y": 263 "y": 263

View file

@ -797,7 +797,7 @@ width="784" height="593" viewBox="-100 -102 784 593"><style type="text/css">
margin: 0 -1.6em 0.25em 0.2em; margin: 0 -1.6em 0.25em 0.2em;
} }
</style><g id="x" style='opacity:0.400000'><g class="shape" ><rect x="105" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="161.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text></g><g id="y" style='opacity:0.400000'><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="278.000000" y="51.000000" width="304" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>linux: because a PC is a terrible thing to waste</p> </style><g id="x" style='opacity:0.400000'><g class="shape" ><rect x="105" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="161.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text></g><g id="y" style='opacity:0.400000'><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="278.000000" y="51.000000" width="304" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>linux: because a PC is a terrible thing to waste</p>
</div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="105" y="263" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="161.500000" y="329.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="(x -&gt; a)[0]" style='opacity:0.400000'><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 161.000000 128.000000 C 161.000000 180.800000 161.000000 208.300000 161.000000 259.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1383729554)"/><text class="text-italic" x="161.000000" y="192.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E"><tspan x="161.000000" dy="0.000000">You don&#39;t have to know how the computer works,</tspan><tspan x="161.000000" dy="18.500000">just how to work the computer.</tspan></text></g><mask id="1383729554" maskUnits="userSpaceOnUse" x="-100" y="-100" width="784" height="593"> </div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="105" y="263" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="161.500000" y="329.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="(x -&gt; a)[0]" style='opacity:0.400000'><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 161.000000 128.000000 C 161.000000 180.800000 161.000000 208.300000 161.000000 259.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3838456096)"/><text class="text-italic" x="161.000000" y="192.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E"><tspan x="161.000000" dy="0.000000">You don&#39;t have to know how the computer works,</tspan><tspan x="161.000000" dy="18.500000">just how to work the computer.</tspan></text></g><mask id="3838456096" maskUnits="userSpaceOnUse" x="-100" y="-100" width="784" height="593">
<rect x="-100" y="-100" width="784" height="593" fill="white"></rect> <rect x="-100" y="-100" width="784" height="593" fill="white"></rect>
<rect x="0.000000" y="176.000000" width="322" height="37" fill="black"></rect> <rect x="0.000000" y="176.000000" width="322" height="37" fill="black"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 804 KiB

After

Width:  |  Height:  |  Size: 804 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "x", "id": "x",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 116, "x": 116,
"y": 12 "y": 12
@ -85,7 +85,7 @@
}, },
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 116, "x": 116,
"y": 375 "y": 375

View file

@ -797,7 +797,7 @@ width="743" height="693" viewBox="-88 -90 743 693"><style type="text/css">
margin: 0 -1.6em 0.25em 0.2em; margin: 0 -1.6em 0.25em 0.2em;
} }
</style><g id="x" style='opacity:0.400000'><g class="shape" ><rect x="116" y="12" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="172.500000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text></g><g id="y" style='opacity:0.400000'><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="249.000000" y="63.000000" width="304" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>linux: because a PC is a terrible thing to waste</p> </style><g id="x" style='opacity:0.400000'><g class="shape" ><rect x="116" y="12" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="172.500000" y="78.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">x</text></g><g id="y" style='opacity:0.400000'><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="249.000000" y="63.000000" width="304" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md" style="background-color:transparent;color:#0A0F25;"><p>linux: because a PC is a terrible thing to waste</p>
</div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="116" y="375" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="172.500000" y="441.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="(x -&gt; a)[0]" style='opacity:0.400000'><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 173.000000 140.000000 L 173.000000 371.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4271261949)"/><text class="text-italic" x="173.000000" y="254.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E"><tspan x="173.000000" dy="0.000000">You don&#39;t have to know how the computer works,</tspan><tspan x="173.000000" dy="18.500000">just how to work the computer.</tspan></text></g><mask id="4271261949" maskUnits="userSpaceOnUse" x="-100" y="-100" width="743" height="693"> </div></foreignObject></g></g><g id="a"><g class="shape" ><rect x="116" y="375" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="172.500000" y="441.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="(x -&gt; a)[0]" style='opacity:0.400000'><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 173.000000 140.000000 L 173.000000 371.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3792250241)"/><text class="text-italic" x="173.000000" y="254.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E"><tspan x="173.000000" dy="0.000000">You don&#39;t have to know how the computer works,</tspan><tspan x="173.000000" dy="18.500000">just how to work the computer.</tspan></text></g><mask id="3792250241" maskUnits="userSpaceOnUse" x="-100" y="-100" width="743" height="693">
<rect x="-100" y="-100" width="743" height="693" fill="white"></rect> <rect x="-100" y="-100" width="743" height="693" fill="white"></rect>
<rect x="12.000000" y="238.000000" width="322" height="37" fill="black"></rect> <rect x="12.000000" y="238.000000" width="322" height="37" fill="black"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 804 KiB

After

Width:  |  Height:  |  Size: 804 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "k8s", "id": "k8s",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0
@ -45,7 +45,7 @@
}, },
{ {
"id": "k8s.m1", "id": "k8s.m1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 116, "x": 116,
"y": 50 "y": 50
@ -86,7 +86,7 @@
}, },
{ {
"id": "k8s.m2", "id": "k8s.m2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 368, "x": 368,
"y": 50 "y": 50
@ -127,7 +127,7 @@
}, },
{ {
"id": "k8s.m3", "id": "k8s.m3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 620, "x": 620,
"y": 50 "y": 50
@ -168,7 +168,7 @@
}, },
{ {
"id": "k8s.w1", "id": "k8s.w1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 872, "x": 872,
"y": 50 "y": 50
@ -209,7 +209,7 @@
}, },
{ {
"id": "k8s.w2", "id": "k8s.w2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1125, "x": 1125,
"y": 50 "y": 50
@ -250,7 +250,7 @@
}, },
{ {
"id": "k8s.w3", "id": "k8s.w3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1378, "x": 1378,
"y": 50 "y": 50
@ -291,7 +291,7 @@
}, },
{ {
"id": "osvc", "id": "osvc",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 347 "y": 347
@ -332,7 +332,7 @@
}, },
{ {
"id": "osvc.vm1", "id": "osvc.vm1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 171, "x": 171,
"y": 397 "y": 397
@ -373,7 +373,7 @@
}, },
{ {
"id": "osvc.vm2", "id": "osvc.vm2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 369, "x": 369,
"y": 397 "y": 397

View file

@ -39,7 +39,7 @@ width="1825" height="777" viewBox="-102 -102 1825 777"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="k8s"><g class="shape" ><rect x="0" y="0" width="1621" height="226" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="810.500000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">Kubernetes</text></g><g id="osvc"><g class="shape" ><rect x="0" y="347" width="555" height="226" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="277.500000" y="380.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">opensvc</text></g><g id="k8s.m1"><g class="shape" ><rect x="116" y="50" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="212.000000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master1</text></g><g id="k8s.m2"><g class="shape" ><rect x="368" y="50" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="464.000000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master2</text></g><g id="k8s.m3"><g class="shape" ><rect x="620" y="50" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="716.000000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master3</text></g><g id="k8s.w1"><g class="shape" ><rect x="872" y="50" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="968.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker1</text></g><g id="k8s.w2"><g class="shape" ><rect x="1125" y="50" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1221.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker2</text></g><g id="k8s.w3"><g class="shape" ><rect x="1378" y="50" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1474.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker3</text></g><g id="osvc.vm1"><g class="shape" ><rect x="171" y="397" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="239.000000" y="463.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM1</text></g><g id="osvc.vm2"><g class="shape" ><rect x="369" y="397" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="437.000000" y="463.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM2</text></g><g id="(k8s -&gt; osvc)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 99.000000 228.000000 C 99.000000 274.400000 99.000000 298.700000 99.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3578790011)"/><text class="text-italic" x="99.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">keycloak</text></g><g id="(k8s -&gt; osvc)[1]"><path d="M 201.000000 228.000000 C 201.000000 274.400000 201.000000 298.700000 201.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3578790011)"/><text class="text-italic" x="201.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">heptapod</text></g><g id="(k8s -&gt; osvc)[2]"><path d="M 297.000000 228.000000 C 297.000000 274.400000 297.000000 298.700000 297.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3578790011)"/><text class="text-italic" x="297.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">harbor</text></g><g id="(k8s -&gt; osvc)[3]"><path d="M 378.000000 228.000000 C 378.000000 274.400000 378.000000 298.700000 378.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3578790011)"/><text class="text-italic" x="378.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">vault</text></g><mask id="3578790011" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1825" height="777"> ]]></script><g id="k8s"><g class="shape" ><rect x="0" y="0" width="1621" height="226" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="810.500000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">Kubernetes</text></g><g id="osvc"><g class="shape" ><rect x="0" y="347" width="555" height="226" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="277.500000" y="380.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">opensvc</text></g><g id="k8s.m1"><g class="shape" ><rect x="116" y="50" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="212.000000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master1</text></g><g id="k8s.m2"><g class="shape" ><rect x="368" y="50" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="464.000000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master2</text></g><g id="k8s.m3"><g class="shape" ><rect x="620" y="50" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="716.000000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master3</text></g><g id="k8s.w1"><g class="shape" ><rect x="872" y="50" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="968.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker1</text></g><g id="k8s.w2"><g class="shape" ><rect x="1125" y="50" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1221.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker2</text></g><g id="k8s.w3"><g class="shape" ><rect x="1378" y="50" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1474.500000" y="116.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker3</text></g><g id="osvc.vm1"><g class="shape" ><rect x="171" y="397" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="239.000000" y="463.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM1</text></g><g id="osvc.vm2"><g class="shape" ><rect x="369" y="397" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="437.000000" y="463.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM2</text></g><g id="(k8s -&gt; osvc)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 99.000000 228.000000 C 99.000000 274.400000 99.000000 298.700000 99.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4136994385)"/><text class="text-italic" x="99.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">keycloak</text></g><g id="(k8s -&gt; osvc)[1]"><path d="M 201.000000 228.000000 C 201.000000 274.400000 201.000000 298.700000 201.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4136994385)"/><text class="text-italic" x="201.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">heptapod</text></g><g id="(k8s -&gt; osvc)[2]"><path d="M 297.000000 228.000000 C 297.000000 274.400000 297.000000 298.700000 297.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4136994385)"/><text class="text-italic" x="297.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">harbor</text></g><g id="(k8s -&gt; osvc)[3]"><path d="M 378.000000 228.000000 C 378.000000 274.400000 378.000000 298.700000 378.000000 343.500000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#4136994385)"/><text class="text-italic" x="378.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">vault</text></g><mask id="4136994385" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1825" height="777">
<rect x="-100" y="-100" width="1825" height="777" fill="white"></rect> <rect x="-100" y="-100" width="1825" height="777" fill="white"></rect>
<rect x="70.000000" y="276.000000" width="59" height="21" fill="black"></rect> <rect x="70.000000" y="276.000000" width="59" height="21" fill="black"></rect>
<rect x="169.000000" y="276.000000" width="65" height="21" fill="black"></rect> <rect x="169.000000" y="276.000000" width="65" height="21" fill="black"></rect>

Before

Width:  |  Height:  |  Size: 795 KiB

After

Width:  |  Height:  |  Size: 795 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "k8s", "id": "k8s",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12
@ -45,7 +45,7 @@
}, },
{ {
"id": "k8s.m1", "id": "k8s.m1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 87, "x": 87,
"y": 87 "y": 87
@ -86,7 +86,7 @@
}, },
{ {
"id": "k8s.m2", "id": "k8s.m2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 299, "x": 299,
"y": 87 "y": 87
@ -127,7 +127,7 @@
}, },
{ {
"id": "k8s.m3", "id": "k8s.m3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 511, "x": 511,
"y": 87 "y": 87
@ -168,7 +168,7 @@
}, },
{ {
"id": "k8s.w1", "id": "k8s.w1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 723, "x": 723,
"y": 87 "y": 87
@ -209,7 +209,7 @@
}, },
{ {
"id": "k8s.w2", "id": "k8s.w2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 936, "x": 936,
"y": 87 "y": 87
@ -250,7 +250,7 @@
}, },
{ {
"id": "k8s.w3", "id": "k8s.w3",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 1149, "x": 1149,
"y": 87 "y": 87
@ -291,7 +291,7 @@
}, },
{ {
"id": "osvc", "id": "osvc",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 397, "x": 397,
"y": 559 "y": 559
@ -332,7 +332,7 @@
}, },
{ {
"id": "osvc.vm1", "id": "osvc.vm1",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 472, "x": 472,
"y": 634 "y": 634
@ -373,7 +373,7 @@
}, },
{ {
"id": "osvc.vm2", "id": "osvc.vm2",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 628, "x": 628,
"y": 634 "y": 634

View file

@ -39,7 +39,7 @@ width="1609" height="1027" viewBox="-90 -90 1609 1027"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="k8s"><g class="shape" ><rect x="12" y="12" width="1405" height="276" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="714.500000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">Kubernetes</text></g><g id="osvc"><g class="shape" ><rect x="397" y="559" width="442" height="276" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="618.000000" y="592.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">opensvc</text></g><g id="k8s.m1"><g class="shape" ><rect x="87" y="87" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="183.000000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master1</text></g><g id="k8s.m2"><g class="shape" ><rect x="299" y="87" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="395.000000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master2</text></g><g id="k8s.m3"><g class="shape" ><rect x="511" y="87" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="607.000000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master3</text></g><g id="k8s.w1"><g class="shape" ><rect x="723" y="87" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="819.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker1</text></g><g id="k8s.w2"><g class="shape" ><rect x="936" y="87" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1032.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker2</text></g><g id="k8s.w3"><g class="shape" ><rect x="1149" y="87" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1245.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker3</text></g><g id="osvc.vm1"><g class="shape" ><rect x="472" y="634" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="540.000000" y="700.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM1</text></g><g id="osvc.vm2"><g class="shape" ><rect x="628" y="634" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="696.000000" y="700.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM2</text></g><g id="(k8s -&gt; osvc)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 293.000000 290.000000 L 293.000000 449.000000 S 293.000000 459.000000 303.000000 459.000000 L 475.600000 459.000000 S 485.600000 459.000000 485.600000 469.000000 L 485.600000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1623327787)"/><text class="text-italic" x="353.500000" y="465.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">keycloak</text></g><g id="(k8s -&gt; osvc)[1]"><path d="M 574.000000 290.000000 L 574.000000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1623327787)"/><text class="text-italic" x="574.500000" y="429.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">heptapod</text></g><g id="(k8s -&gt; osvc)[2]"><path d="M 855.000000 290.000000 L 855.000000 449.000000 S 855.000000 459.000000 845.000000 459.000000 L 672.400000 459.000000 S 662.400000 459.000000 662.400000 469.000000 L 662.400000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1623327787)"/><text class="text-italic" x="794.500000" y="465.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">harbor</text></g><g id="(k8s -&gt; osvc)[3]"><path d="M 1136.000000 290.000000 L 1136.000000 499.000000 S 1136.000000 509.000000 1126.000000 509.000000 L 760.800000 509.000000 S 750.800000 509.000000 750.800000 519.000000 L 750.800000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1623327787)"/><text class="text-italic" x="1028.500000" y="515.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">vault</text></g><mask id="1623327787" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1609" height="1027"> ]]></script><g id="k8s"><g class="shape" ><rect x="12" y="12" width="1405" height="276" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="714.500000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">Kubernetes</text></g><g id="osvc"><g class="shape" ><rect x="397" y="559" width="442" height="276" style="fill:#E3E9FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="618.000000" y="592.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">opensvc</text></g><g id="k8s.m1"><g class="shape" ><rect x="87" y="87" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="183.000000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master1</text></g><g id="k8s.m2"><g class="shape" ><rect x="299" y="87" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="395.000000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master2</text></g><g id="k8s.m3"><g class="shape" ><rect x="511" y="87" width="192" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="607.000000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-master3</text></g><g id="k8s.w1"><g class="shape" ><rect x="723" y="87" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="819.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker1</text></g><g id="k8s.w2"><g class="shape" ><rect x="936" y="87" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1032.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker2</text></g><g id="k8s.w3"><g class="shape" ><rect x="1149" y="87" width="193" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="1245.500000" y="153.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">k8s-worker3</text></g><g id="osvc.vm1"><g class="shape" ><rect x="472" y="634" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="540.000000" y="700.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM1</text></g><g id="osvc.vm2"><g class="shape" ><rect x="628" y="634" width="136" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text-bold" x="696.000000" y="700.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">VM2</text></g><g id="(k8s -&gt; osvc)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 293.000000 290.000000 L 293.000000 449.000000 S 293.000000 459.000000 303.000000 459.000000 L 475.600000 459.000000 S 485.600000 459.000000 485.600000 469.000000 L 485.600000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1050316171)"/><text class="text-italic" x="353.500000" y="465.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">keycloak</text></g><g id="(k8s -&gt; osvc)[1]"><path d="M 574.000000 290.000000 L 574.000000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1050316171)"/><text class="text-italic" x="574.500000" y="429.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">heptapod</text></g><g id="(k8s -&gt; osvc)[2]"><path d="M 855.000000 290.000000 L 855.000000 449.000000 S 855.000000 459.000000 845.000000 459.000000 L 672.400000 459.000000 S 662.400000 459.000000 662.400000 469.000000 L 662.400000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1050316171)"/><text class="text-italic" x="794.500000" y="465.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">harbor</text></g><g id="(k8s -&gt; osvc)[3]"><path d="M 1136.000000 290.000000 L 1136.000000 499.000000 S 1136.000000 509.000000 1126.000000 509.000000 L 760.800000 509.000000 S 750.800000 509.000000 750.800000 519.000000 L 750.800000 555.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1050316171)"/><text class="text-italic" x="1028.500000" y="515.000000" style="text-anchor:middle;font-size:16px;fill:#676C7E">vault</text></g><mask id="1050316171" maskUnits="userSpaceOnUse" x="-100" y="-100" width="1609" height="1027">
<rect x="-100" y="-100" width="1609" height="1027" fill="white"></rect> <rect x="-100" y="-100" width="1609" height="1027" fill="white"></rect>
<rect x="324.000000" y="449.000000" width="59" height="21" fill="black"></rect> <rect x="324.000000" y="449.000000" width="59" height="21" fill="black"></rect>
<rect x="542.000000" y="413.000000" width="65" height="21" fill="black"></rect> <rect x="542.000000" y="413.000000" width="65" height="21" fill="black"></rect>

Before

Width:  |  Height:  |  Size: 796 KiB

After

Width:  |  Height:  |  Size: 796 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "my network", "id": "my network",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 0, "x": 0,
"y": 0 "y": 0

View file

@ -39,7 +39,7 @@ width="394" height="356" viewBox="-102 -102 394 356"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="my network"><g class="shape" ><rect x="0" y="0" width="190" height="152" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg?fuga=1&amp;hoge" x="63.000000" y="44.000000" width="64" height="64" /><text class="text-bold" x="95.000000" y="21.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">my network</text></g><mask id="445669457" maskUnits="userSpaceOnUse" x="-100" y="-100" width="394" height="356"> ]]></script><g id="my network"><g class="shape" ><rect x="0" y="0" width="190" height="152" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg?fuga=1&amp;hoge" x="63.000000" y="44.000000" width="64" height="64" /><text class="text-bold" x="95.000000" y="21.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">my network</text></g><mask id="726057734" maskUnits="userSpaceOnUse" x="-100" y="-100" width="394" height="356">
<rect x="-100" y="-100" width="394" height="356" fill="white"></rect> <rect x="-100" y="-100" width="394" height="356" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 324 KiB

After

Width:  |  Height:  |  Size: 324 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "my network", "id": "my network",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 12, "x": 12,
"y": 12 "y": 12

View file

@ -39,7 +39,7 @@ width="394" height="356" viewBox="-90 -90 394 356"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="my network"><g class="shape" ><rect x="12" y="12" width="190" height="152" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg?fuga=1&amp;hoge" x="75.000000" y="56.000000" width="64" height="64" /><text class="text-bold" x="107.000000" y="33.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">my network</text></g><mask id="3849356313" maskUnits="userSpaceOnUse" x="-100" y="-100" width="394" height="356"> ]]></script><g id="my network"><g class="shape" ><rect x="12" y="12" width="190" height="152" style="fill:#F7F8FE;stroke:#0D32B2;stroke-width:2;" /></g><image href="https://icons.terrastruct.com/infra/019-network.svg?fuga=1&amp;hoge" x="75.000000" y="56.000000" width="64" height="64" /><text class="text-bold" x="107.000000" y="33.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">my network</text></g><mask id="1665874494" maskUnits="userSpaceOnUse" x="-100" y="-100" width="394" height="356">
<rect x="-100" y="-100" width="394" height="356" fill="white"></rect> <rect x="-100" y="-100" width="394" height="356" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 324 KiB

After

Width:  |  Height:  |  Size: 324 KiB

View file

@ -0,0 +1,606 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "Office chatter",
"type": "sequence_diagram",
"pos": {
"x": 0,
"y": 0
},
"width": 741,
"height": 1166,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Office chatter",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 164,
"labelHeight": 41,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Office chatter.alice",
"type": "rectangle",
"pos": {
"x": 24,
"y": 110
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Alice",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 38,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "Office chatter.bob",
"type": "rectangle",
"pos": {
"x": 274,
"y": 110
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Bobby",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 48,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "Office chatter.awkward small talk",
"type": "rectangle",
"pos": {
"x": 482,
"y": 110
},
"width": 235,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "awkward small talk",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 135,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "Office chatter.awkward small talk.awkward small talk",
"type": "rectangle",
"pos": {
"x": 593,
"y": 350
},
"width": 12,
"height": 158,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#E3E9FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 135,
"labelHeight": 26,
"zIndex": 2,
"level": 3
},
{
"id": "Office chatter.awkward small talk.awkward small talk.ok",
"type": "page",
"pos": {
"x": 538,
"y": 366
},
"width": 122,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "ok",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 22,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5,
"level": 4
},
{
"id": "Office chatter.awkward small talk.icebreaker attempt",
"type": "rectangle",
"pos": {
"x": 593,
"y": -9223372036854775808
},
"width": 12,
"height": 80,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
"borderRadius": 0,
"fill": "#DEE1EB",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": true,
"fields": null,
"methods": null,
"columns": null,
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 134,
"labelHeight": 26,
"zIndex": 2,
"level": 3
},
{
"id": "Office chatter.awkward small talk.unfortunate outcome",
"type": "rectangle",
"pos": {
"x": 593,
"y": -9223372036854775808
},
"width": 12,
"height": 80,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
"borderRadius": 0,
"fill": "#DEE1EB",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": true,
"fields": null,
"methods": null,
"columns": null,
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 148,
"labelHeight": 26,
"zIndex": 2,
"level": 3
}
],
"connections": [
{
"id": "Office chatter.(alice -> bob)[1]",
"src": "Office chatter.alice",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.bob",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "uhm, hi",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 50,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 99,
"y": 622
},
{
"x": 349,
"y": 622
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "Office chatter.(bob -> alice)[1]",
"src": "Office chatter.bob",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.alice",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "oh, hello",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 56,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 349,
"y": 752
},
{
"x": 99,
"y": 752
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "Office chatter.(alice -> bob)[0]",
"src": "Office chatter.alice",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.bob",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "what did you have for lunch?",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 187,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 99,
"y": 882
},
{
"x": 349,
"y": 882
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "Office chatter.(bob -> alice)[0]",
"src": "Office chatter.bob",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.alice",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "that's personal",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 349,
"y": 1012
},
{
"x": 99,
"y": 1012
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "(Office chatter.alice -- )[0]",
"src": "Office chatter.alice",
"srcArrow": "none",
"srcLabel": "",
"dst": "alice-lifeline-end-3851299086",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 6,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 99,
"y": 236
},
{
"x": 99,
"y": 1142
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 1
},
{
"id": "(Office chatter.bob -- )[0]",
"src": "Office chatter.bob",
"srcArrow": "none",
"srcLabel": "",
"dst": "bob-lifeline-end-3036726343",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 6,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 349,
"y": 236
},
{
"x": 349,
"y": 1142
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 1
},
{
"id": "(Office chatter.awkward small talk -- )[0]",
"src": "Office chatter.awkward small talk",
"srcArrow": "none",
"srcLabel": "",
"dst": "awkward small talk-lifeline-end-861194358",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 6,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 599.5,
"y": 236
},
{
"x": 599.5,
"y": 1142
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 1
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 473 KiB

View file

@ -0,0 +1,606 @@
{
"name": "",
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "Office chatter",
"type": "sequence_diagram",
"pos": {
"x": 12,
"y": 12
},
"width": 741,
"height": 1166,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Office chatter",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 164,
"labelHeight": 41,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "Office chatter.alice",
"type": "rectangle",
"pos": {
"x": 36,
"y": 122
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Alice",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 38,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "Office chatter.bob",
"type": "rectangle",
"pos": {
"x": 286,
"y": 122
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "Bobby",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 48,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "Office chatter.awkward small talk",
"type": "rectangle",
"pos": {
"x": 494,
"y": 122
},
"width": 235,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "awkward small talk",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 135,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "Office chatter.awkward small talk.awkward small talk",
"type": "rectangle",
"pos": {
"x": 605,
"y": 362
},
"width": 12,
"height": 158,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#E3E9FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 135,
"labelHeight": 26,
"zIndex": 2,
"level": 3
},
{
"id": "Office chatter.awkward small talk.awkward small talk.ok",
"type": "page",
"pos": {
"x": 550,
"y": 378
},
"width": 122,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#FFFFFF",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "ok",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 22,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 5,
"level": 4
},
{
"id": "Office chatter.awkward small talk.icebreaker attempt",
"type": "rectangle",
"pos": {
"x": 605,
"y": -9223372036854775808
},
"width": 12,
"height": 80,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
"borderRadius": 0,
"fill": "#DEE1EB",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": true,
"fields": null,
"methods": null,
"columns": null,
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 134,
"labelHeight": 26,
"zIndex": 2,
"level": 3
},
{
"id": "Office chatter.awkward small talk.unfortunate outcome",
"type": "rectangle",
"pos": {
"x": 605,
"y": -9223372036854775808
},
"width": 12,
"height": 80,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 0,
"borderRadius": 0,
"fill": "#DEE1EB",
"stroke": "#0D32B2",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": true,
"fields": null,
"methods": null,
"columns": null,
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 148,
"labelHeight": 26,
"zIndex": 2,
"level": 3
}
],
"connections": [
{
"id": "Office chatter.(alice -> bob)[1]",
"src": "Office chatter.alice",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.bob",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "uhm, hi",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 50,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 111,
"y": 634
},
{
"x": 361,
"y": 634
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "Office chatter.(bob -> alice)[1]",
"src": "Office chatter.bob",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.alice",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "oh, hello",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 56,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 361,
"y": 764
},
{
"x": 111,
"y": 764
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "Office chatter.(alice -> bob)[0]",
"src": "Office chatter.alice",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.bob",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "what did you have for lunch?",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 187,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 111,
"y": 894
},
{
"x": 361,
"y": 894
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "Office chatter.(bob -> alice)[0]",
"src": "Office chatter.bob",
"srcArrow": "none",
"srcLabel": "",
"dst": "Office chatter.alice",
"dstArrow": "triangle",
"dstLabel": "",
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "that's personal",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelHeight": 21,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"labelPercentage": 0,
"route": [
{
"x": 361,
"y": 1024
},
{
"x": 111,
"y": 1024
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 4
},
{
"id": "(Office chatter.alice -- )[0]",
"src": "Office chatter.alice",
"srcArrow": "none",
"srcLabel": "",
"dst": "alice-lifeline-end-3851299086",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 6,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 111,
"y": 248
},
{
"x": 111,
"y": 1154
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 1
},
{
"id": "(Office chatter.bob -- )[0]",
"src": "Office chatter.bob",
"srcArrow": "none",
"srcLabel": "",
"dst": "bob-lifeline-end-3036726343",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 6,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 361,
"y": 248
},
{
"x": 361,
"y": 1154
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 1
},
{
"id": "(Office chatter.awkward small talk -- )[0]",
"src": "Office chatter.awkward small talk",
"srcArrow": "none",
"srcLabel": "",
"dst": "awkward small talk-lifeline-end-861194358",
"dstArrow": "none",
"dstLabel": "",
"opacity": 1,
"strokeDash": 6,
"strokeWidth": 2,
"stroke": "#0D32B2",
"label": "",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "",
"color": "#676C7E",
"italic": true,
"bold": false,
"underline": false,
"labelWidth": 0,
"labelHeight": 0,
"labelPosition": "",
"labelPercentage": 0,
"route": [
{
"x": 611.5,
"y": 248
},
{
"x": 611.5,
"y": 1154
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 1
}
]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 473 KiB

View file

@ -43,6 +43,88 @@
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
{
"id": "foo.a",
"type": "rectangle",
"pos": {
"x": 24,
"y": 110
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 12,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "foo.b",
"type": "rectangle",
"pos": {
"x": 274,
"y": 110
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{ {
"id": "foobar", "id": "foobar",
"type": "sequence_diagram", "type": "sequence_diagram",
@ -84,91 +166,9 @@
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
{
"id": "foo.a",
"type": "",
"pos": {
"x": 24,
"y": 110
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 12,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "foo.b",
"type": "",
"pos": {
"x": 274,
"y": 110
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{ {
"id": "foobar.c", "id": "foobar.c",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 24, "x": 24,
"y": 730 "y": 730
@ -209,7 +209,7 @@
}, },
{ {
"id": "foobar.d", "id": "foobar.d",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 274, "x": 274,
"y": 730 "y": 730

View file

@ -39,7 +39,7 @@ width="648" height="1340" viewBox="-100 -100 648 1340"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="foo"><g class="shape" ><rect x="0" y="0" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="224.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foo</text></g><g id="foobar"><g class="shape" ><rect x="0" y="620" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="224.000000" y="653.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foobar</text></g><g id="foo.a"><g class="shape" ><rect x="24" y="110" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="99.000000" y="176.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="foo.b"><g class="shape" ><rect x="274" y="110" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="349.000000" y="176.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="foobar.c"><g class="shape" ><rect x="24" y="730" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="99.000000" y="796.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">c</text></g><g id="foobar.d"><g class="shape" ><rect x="274" y="730" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="349.000000" y="796.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(foo -&gt; foobar)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 224.000000 521.000000 C 224.000000 560.000000 224.000000 580.000000 224.000000 617.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#557222977)"/></g><g id="(foo.a -- )[0]"><path d="M 99.000000 238.000000 L 99.000000 495.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#557222977)"/></g><g id="(foo.b -- )[0]"><path d="M 349.000000 238.000000 L 349.000000 495.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#557222977)"/></g><g id="(foobar.c -- )[0]"><path d="M 99.000000 858.000000 L 99.000000 1115.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#557222977)"/></g><g id="(foobar.d -- )[0]"><path d="M 349.000000 858.000000 L 349.000000 1115.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#557222977)"/></g><g id="foo.(a -&gt; b)[0]"><path d="M 101.000000 366.000000 L 345.000000 366.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#557222977)"/></g><g id="foobar.(c -&gt; d)[0]"><path d="M 101.000000 986.000000 L 345.000000 986.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#557222977)"/></g><mask id="557222977" maskUnits="userSpaceOnUse" x="-100" y="-100" width="648" height="1340"> ]]></script><g id="foo"><g class="shape" ><rect x="0" y="0" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="224.000000" y="33.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foo</text></g><g id="foobar"><g class="shape" ><rect x="0" y="620" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="224.000000" y="653.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foobar</text></g><g id="foo.a"><g class="shape" ><rect x="24" y="110" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="99.000000" y="176.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="foo.b"><g class="shape" ><rect x="274" y="110" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="349.000000" y="176.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="foobar.c"><g class="shape" ><rect x="24" y="730" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="99.000000" y="796.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">c</text></g><g id="foobar.d"><g class="shape" ><rect x="274" y="730" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="349.000000" y="796.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(foo -&gt; foobar)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 224.000000 521.000000 C 224.000000 560.000000 224.000000 580.000000 224.000000 617.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2494592993)"/></g><g id="(foo.a -- )[0]"><path d="M 99.000000 238.000000 L 99.000000 495.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#2494592993)"/></g><g id="(foo.b -- )[0]"><path d="M 349.000000 238.000000 L 349.000000 495.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#2494592993)"/></g><g id="(foobar.c -- )[0]"><path d="M 99.000000 858.000000 L 99.000000 1115.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#2494592993)"/></g><g id="(foobar.d -- )[0]"><path d="M 349.000000 858.000000 L 349.000000 1115.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#2494592993)"/></g><g id="foo.(a -&gt; b)[0]"><path d="M 101.000000 366.000000 L 345.000000 366.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2494592993)"/></g><g id="foobar.(c -&gt; d)[0]"><path d="M 101.000000 986.000000 L 345.000000 986.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#2494592993)"/></g><mask id="2494592993" maskUnits="userSpaceOnUse" x="-100" y="-100" width="648" height="1340">
<rect x="-100" y="-100" width="648" height="1340" fill="white"></rect> <rect x="-100" y="-100" width="648" height="1340" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

View file

@ -43,6 +43,88 @@
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
{
"id": "foo.a",
"type": "rectangle",
"pos": {
"x": 36,
"y": 122
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 12,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "foo.b",
"type": "rectangle",
"pos": {
"x": 286,
"y": 122
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{ {
"id": "foobar", "id": "foobar",
"type": "sequence_diagram", "type": "sequence_diagram",
@ -84,91 +166,9 @@
"zIndex": 0, "zIndex": 0,
"level": 1 "level": 1
}, },
{
"id": "foo.a",
"type": "",
"pos": {
"x": 36,
"y": 122
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 12,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{
"id": "foo.b",
"type": "",
"pos": {
"x": 286,
"y": 122
},
"width": 150,
"height": 126,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "#EDF0FD",
"stroke": "#0D32B2",
"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": "#0A0F25",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 13,
"labelHeight": 26,
"labelPosition": "INSIDE_MIDDLE_CENTER",
"zIndex": 0,
"level": 2
},
{ {
"id": "foobar.c", "id": "foobar.c",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 36, "x": 36,
"y": 742 "y": 742
@ -209,7 +209,7 @@
}, },
{ {
"id": "foobar.d", "id": "foobar.d",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 286, "x": 286,
"y": 742 "y": 742

View file

@ -39,7 +39,7 @@ width="648" height="1340" viewBox="-88 -88 648 1340"><style type="text/css">
svgEl.setAttribute("height", height * ratio - 16); svgEl.setAttribute("height", height * ratio - 16);
} }
}); });
]]></script><g id="foo"><g class="shape" ><rect x="12" y="12" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="236.000000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foo</text></g><g id="foobar"><g class="shape" ><rect x="12" y="632" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="236.000000" y="665.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foobar</text></g><g id="foo.a"><g class="shape" ><rect x="36" y="122" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="111.000000" y="188.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="foo.b"><g class="shape" ><rect x="286" y="122" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="361.000000" y="188.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="foobar.c"><g class="shape" ><rect x="36" y="742" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="111.000000" y="808.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">c</text></g><g id="foobar.d"><g class="shape" ><rect x="286" y="742" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="361.000000" y="808.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(foo -&gt; foobar)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 236.000000 533.000000 L 236.000000 629.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3896282040)"/></g><g id="(foo.a -- )[0]"><path d="M 111.000000 250.000000 L 111.000000 507.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#3896282040)"/></g><g id="(foo.b -- )[0]"><path d="M 361.000000 250.000000 L 361.000000 507.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#3896282040)"/></g><g id="(foobar.c -- )[0]"><path d="M 111.000000 870.000000 L 111.000000 1127.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#3896282040)"/></g><g id="(foobar.d -- )[0]"><path d="M 361.000000 870.000000 L 361.000000 1127.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#3896282040)"/></g><g id="foo.(a -&gt; b)[0]"><path d="M 113.000000 378.000000 L 357.000000 378.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3896282040)"/></g><g id="foobar.(c -&gt; d)[0]"><path d="M 113.000000 998.000000 L 357.000000 998.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#3896282040)"/></g><mask id="3896282040" maskUnits="userSpaceOnUse" x="-100" y="-100" width="648" height="1340"> ]]></script><g id="foo"><g class="shape" ><rect x="12" y="12" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="236.000000" y="45.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foo</text></g><g id="foobar"><g class="shape" ><rect x="12" y="632" width="448" height="520" style="fill:#FFFFFF;stroke:#0D32B2;stroke-width:0;" /></g><text class="text" x="236.000000" y="665.000000" style="text-anchor:middle;font-size:28px;fill:#0A0F25">foobar</text></g><g id="foo.a"><g class="shape" ><rect x="36" y="122" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="111.000000" y="188.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">a</text></g><g id="foo.b"><g class="shape" ><rect x="286" y="122" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="361.000000" y="188.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">b</text></g><g id="foobar.c"><g class="shape" ><rect x="36" y="742" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="111.000000" y="808.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">c</text></g><g id="foobar.d"><g class="shape" ><rect x="286" y="742" width="150" height="126" style="fill:#EDF0FD;stroke:#0D32B2;stroke-width:2;" /></g><text class="text" x="361.000000" y="808.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">d</text></g><g id="(foo -&gt; foobar)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 236.000000 533.000000 L 236.000000 629.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1614682088)"/></g><g id="(foo.a -- )[0]"><path d="M 111.000000 250.000000 L 111.000000 507.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#1614682088)"/></g><g id="(foo.b -- )[0]"><path d="M 361.000000 250.000000 L 361.000000 507.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#1614682088)"/></g><g id="(foobar.c -- )[0]"><path d="M 111.000000 870.000000 L 111.000000 1127.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#1614682088)"/></g><g id="(foobar.d -- )[0]"><path d="M 361.000000 870.000000 L 361.000000 1127.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#1614682088)"/></g><g id="foo.(a -&gt; b)[0]"><path d="M 113.000000 378.000000 L 357.000000 378.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1614682088)"/></g><g id="foobar.(c -&gt; d)[0]"><path d="M 113.000000 998.000000 L 357.000000 998.000000" class="connection" style="fill:none;stroke:#0D32B2;stroke-width:2;" marker-end="url(#mk-3990223579)" mask="url(#1614682088)"/></g><mask id="1614682088" maskUnits="userSpaceOnUse" x="-100" y="-100" width="648" height="1340">
<rect x="-100" y="-100" width="648" height="1340" fill="white"></rect> <rect x="-100" y="-100" width="648" height="1340" fill="white"></rect>
</mask><style type="text/css"><![CDATA[ </mask><style type="text/css"><![CDATA[

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

View file

@ -4,7 +4,7 @@
"shapes": [ "shapes": [
{ {
"id": "a", "id": "a",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 24, "x": 24,
"y": 74 "y": 74
@ -45,7 +45,7 @@
}, },
{ {
"id": "b", "id": "b",
"type": "", "type": "rectangle",
"pos": { "pos": {
"x": 274, "x": 274,
"y": 74 "y": 74

Some files were not shown because too many files have changed in this diff Show more