Skip to main content

Debugging Rigs

Slipway Debugger

Slipway comes with a built-in debugger to help you diagnose problems with Rigs.

To demonstrate this, we'll create a mock Rig using the built-in special Component passthrough:

mock_rig.json
{
"rigging": {
"start": {
"component": "passthrough",
"input": {
"line": "The quick"
}
},
"animals": {
"component": "passthrough",
"input": [ "brown fox", "lazy dog" ]
},
"first_half": {
"component": "passthrough",
"input": {
"line_1": "$$.start.line",
"line_2": "$$.animals[0]"
}
},
"final": {
"component": "passthrough",
"input": {
"line_1": "$$.first_half.line_1",
"line_2": "$$.first_half.line_2",
"line_3": "jumped over the",
"line_4": "$$.animals[0]"
}
}
}
}

The passthough component simply passes the Component's input through to its output.

If you run this using slipway run you will see the following output:

> slipway run mock_rig.json
Launching mock_rig.json

◩ animals ┆ 569fab51 ┆ 24 bytes
│─◩ start ┆ b54b3a01 ┆ 20 bytes
├─┴─□ first_half ┆ ┆
└───┴─□ final ┆ ┆

Running "start"...
Running "animals"...

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 42ns of 42ns
│─■ start ┆ b54b3a01 ➜ b54b3a01 ┆ 20 bytes ➜ 20 bytes ┆ 333ns of 333ns
├─┴─◩ first_half ┆ 0e5dbab3 ┆ 43 bytes
└───┴─□ final ┆ ┆

Running "first_half"...

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 42ns of 42ns
│─■ start ┆ b54b3a01 ➜ b54b3a01 ┆ 20 bytes ➜ 20 bytes ┆ 333ns of 333ns
├─┴─■ first_half ┆ 0e5dbab3 ➜ 0e5dbab3 ┆ 43 bytes ➜ 43 bytes ┆ 166ns of 166ns
└───┴─◩ final ┆ 3889234e ┆ 91 bytes

Running "final"...
No more components to run.

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 42ns of 42ns
│─■ start ┆ b54b3a01 ➜ b54b3a01 ┆ 20 bytes ➜ 20 bytes ┆ 333ns of 333ns
├─┴─■ first_half ┆ 0e5dbab3 ➜ 0e5dbab3 ┆ 43 bytes ➜ 43 bytes ┆ 166ns of 166ns
└───┴─■ final ┆ 3889234e ➜ 3889234e ┆ 91 bytes ➜ 91 bytes ┆ 208ns of 208ns

Component "final" output:
{
"line_1": "The quick",
"line_2": "brown fox",
"line_3": "jumped over the",
"line_4": "brown fox"
}

The output is showing the current state of the Rig as each component is evaluated.

Take for example the following section of the output:

■ animals         ┆  569fab51 ➜ 569fab51  ┆  24 bytes ➜ 24 bytes  ┆  42ns  of 42ns
│─■ start ┆ b54b3a01 ➜ b54b3a01 ┆ 20 bytes ➜ 20 bytes ┆ 333ns of 333ns
├─┴─◩ first_half ┆ 0e5dbab3 ┆ 43 bytes
└───┴─□ final ┆ ┆

Each line represents a Component referenced in the Rig:

  • The lines on the far left draw the dependencies between the Components.
    • Lines connecting to the side of a Component are inputs.
    • Lines coming from the bottom of a Component are outputs.
  • The box represents the component state:
    • indicates the Component does not yet have either an input nor an output.
    • indicates the Component has an input, but there is no output yet.
    • indicates the Component has both an input and an output.
    • indicates the Component has no input, but does have an output (this can happen if the output is overridden in the debugger).
  • The Component handle is displayed in the first column, after the box.
  • The second column shows the input and output hashes.
    • If the hashes have a symbol that means the input directly led to the output.
    • If the hashes have a ! symbol that means the output was overridden.
  • The third column shows the input and output data sizes.
  • The forth column shows the Component execution time.
    • The format x of y indicates the Component took y time to execute overall, of which x was spent running the Component's code. These may be different if, for example, the component needs to be JIT compiled before execution.

After the Rig has finished executing, the result of the Component with handle final is output. Only leaf node Component results are output. A leaf node is a Component whose output is not used by any other Component.

There is a problem here: The last line output from final should be "lazy dog", not "brown fox". Obviously the mistake here is trivial, but it works as a debugging exercise.

Let's step through each Component using the Slipway debugger.

Run the following command:

slipway debug mock_rig.json

You will see some output and a new terminal prompt:

> slipway debug mock_rig.json
Debugging mock_rig.json

◩ animals ┆ 569fab51 ┆ 24 bytes
│─◩ start ┆ b54b3a01 ┆ 20 bytes
├─┴─□ first_half ┆ ┆
└───┴─□ final ┆ ┆

Type help for commands.
⛵️ >>

The output matches the first set of output you saw when running the rig above. It is the state of the Rig before any Components have been run.

The state shows us that animals and start are both able to run, because they have inputs (neither depend on any other Components).

What the above text doesn't show is that in the terminal the four handles are partially underlined as follows:

  • animals
  • start
  • first_half
  • final

The underlines are shortcuts. Instead of writing out the entire handle when debugging, we can just write the underlined part. As there are two handles beginning with f, the shortcuts are f for the first and fi for the second.

Let's run the component start using its shortcut:

run s

We now see:

⛵️ >> run s

◩ animals ┆ 569fab51 ┆ 24 bytes
│─■ start ┆ b54b3a01 ➜ b54b3a01 ┆ 20 bytes ➜ 20 bytes ┆ 5µs of 5µs
├─┴─□ first_half ┆ ┆
└───┴─□ final ┆ ┆

⛵️ >>

Now we can see that start has been run, and has an output.

We can view the output of start:

output s

This will open the output in a the text editor (using the edit crate).

If you simply close the file, then you will return to the debugger in the same state as before.

However if you make changes and save the file, then you will override the output of the Component. This is useful for quickly testing changes to the output of one Component to see how it affects downstream Components.

If you change the text in the JSON from The quick to The quickish, then save and close the file, you will see the following output:

◩ animals         ┆  569fab51             ┆  24 bytes
│─■ start ┆ b54b3a01 ! f9f77ed9 ┆ 20 bytes ! 23 bytes ┆ 7µs of 7µs
├─┴─□ first_half ┆ ┆
└───┴─□ final ┆ ┆

⛵️ >>

Note the ! in the second and third columns, indicating that the input did not directly lead to the output. In your terminal you'll also see that the hash and sizes to the right of the ! are underlined, indicating it is the output that has been overridden.

Let's run animals next. We don't need to use the shortcut a if we don't want to:

run animals

You will see the output:

⛵️ >> run animals

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 117µs of 117µs
│─■ start ┆ b54b3a01 ! f9f77ed9 ┆ 20 bytes ! 23 bytes ┆ 7µs of 7µs
├─┴─◩ first_half ┆ 2c87db9d ┆ 46 bytes
└───┴─□ final ┆ ┆

⛵️ >>

Now the Component first_half is able to run, as both its input Components have outputs.

Let's run it:

⛵️ >> run f

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 117µs of 117µs
│─■ start ┆ b54b3a01 ! f9f77ed9 ┆ 20 bytes ! 23 bytes ┆ 7µs of 7µs
├─┴─■ first_half ┆ 2c87db9d ➜ 2c87db9d ┆ 46 bytes ➜ 46 bytes ┆ 3µs of 3µs
└───┴─◩ final ┆ 706d487d ┆ 94 bytes

⛵️ >>

View it's output:

output f

You will see the output that incorporates our changes to the output of start:

{
"line_1": "The quickish",
"line_2": "brown fox"
}

Close the output of first_half, and run final:

⛵️ >> run fi

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 117µs of 117µs
│─■ start ┆ b54b3a01 ! f9f77ed9 ┆ 20 bytes ! 23 bytes ┆ 7µs of 7µs
├─┴─■ first_half ┆ 2c87db9d ➜ 2c87db9d ┆ 46 bytes ➜ 46 bytes ┆ 3µs of 3µs
└───┴─■ final ┆ 706d487d ➜ 706d487d ┆ 94 bytes ➜ 94 bytes ┆ 3µs of 3µs

⛵️ >>

The Rig is now complete, but we are still in the debugger.

If you look at the output of final with output fi you'll see our incorrect output:

{
"line_1": "The quickish",
"line_2": "brown fox",
"line_3": "jumped over the",
"line_4": "brown fox"
}

Close the output. Let's try and fix it.

First let's look at the output of animals by running output a:

[
"brown fox",
"lazy dog"
]

Ok, the last line of our final component output should be "lazy dog", which is at index 1. Close the output without changing it.

Next let's look at the input of final:

input fi

A text editor opens with the following:

{
"line_1": "$$.first_half.line_1",
"line_2": "$$.first_half.line_2",
"line_3": "jumped over the",
"line_4": "$$.animals[0]"
}

Hmm, out last line is pointing at index 0, not index 1. Let's change that:

{
"line_1": "$$.first_half.line_1",
"line_2": "$$.first_half.line_2",
"line_3": "jumped over the",
"line_4": "$$.animals[1]"
}

Save and close the file. You'll see the following in the debugger:

■ animals         ┆  569fab51 ➜ 569fab51  ┆  24 bytes ➜ 24 bytes  ┆  117µs of 117µs
│─■ start ┆ b54b3a01 ! f9f77ed9 ┆ 20 bytes ! 23 bytes ┆ 7µs of 7µs
├─┴─■ first_half ┆ 2c87db9d ➜ 2c87db9d ┆ 46 bytes ➜ 46 bytes ┆ 3µs of 3µs
└───┴─■ final ┆ cd9bade0 ! 706d487d ┆ 93 bytes ! 94 bytes ┆ 3µs of 3µs

⛵️ >>

The final Component now has a ! symbol in the second and third columns, and the input has and size is underlined, indicating the input is overridden.

In addition, the output of final will be red in your terminal, indicating it is stale.

Let's re-run it:

⛵️ >> run fi

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 117µs of 117µs
│─■ start ┆ b54b3a01 ! f9f77ed9 ┆ 20 bytes ! 23 bytes ┆ 7µs of 7µs
├─┴─■ first_half ┆ 2c87db9d ➜ 2c87db9d ┆ 46 bytes ➜ 46 bytes ┆ 3µs of 3µs
└───┴─■ final ┆ cd9bade0 ➜ cd9bade0 ┆ 93 bytes ➜ 93 bytes ┆ 7µs of 7µs

⛵️ >>

The output will be similar to before, but now the ! for final has turned back into an arrow, indicating the output derives from the input, and the output is green. The input is still underlined, indicating it is still overridden.

View the output of final again:

output fi

You'll see the following JSON:

{
"line_1": "The quickish",
"line_2": "brown fox",
"line_3": "jumped over the",
"line_4": "lazy dog"
}

Great! We've fixed the problem! Note that we've only fixed it in the debugger, we still need to go back and modify the Rig file if we want to keep the fix.

Additional commands

Before we stop, there are a few useful debugger commands we haven't used yet.

--clear

Let's look at the help for the output command:

output --help

You'll see the following:

⛵️ >> output --help
Override or view the output of a component

Usage: output [OPTIONS] <HANDLE>

Arguments:
<HANDLE> The component to update

Options:
-c, --clear Clear the output override
-h, --help Print help

Note there is a --clear option. We can use that to clear our overridden output to the start Component:

⛵️ >> output s --clear

■ animals ┆ 569fab51 ➜ 569fab51 ┆ 24 bytes ➜ 24 bytes ┆ 117µs of 117µs
│─■ start ┆ b54b3a01 ➜ b54b3a01 ┆ 20 bytes ➜ 20 bytes ┆ 7µs of 7µs
├─┴─■ first_half ┆ 0e5dbab3 ! 2c87db9d ┆ 43 bytes ! 46 bytes ┆ 3µs of 3µs
└───┴─■ final ┆ cd9bade0 ➜ cd9bade0 ┆ 93 bytes ➜ 93 bytes ┆ 7µs of 7µs

You'll see that we've now invalidated the output of first_half: It's output is red, and it has an ! indicating the output does not derive from it's new input.

Run first_half and the output of final will be similarly invalidated, so run that as well and inspect its output:

run f
run fi
output fi

You'll see our final output JSON, exactly as we want it:

{
"line_1": "The quick",
"line_2": "brown fox",
"line_3": "jumped over the",
"line_4": "lazy dog"
}

render

Another command we haven't used is the render command.

⛵️ >> render --help
Render the output of a component

Usage: render [OPTIONS] <HANDLE>

Arguments:
<HANDLE> The component to render

Options:
-s, --save <SAVE> The optional file path to save the rendered output
-h, --help Print help

If the component outputs a canvas, this will render the output as an image to the command line. If your terminal doesn't support inline images, or you want to save it as a file, you can use the --save option and specify a file path.

exit

Finally, when you want to exit the debugger, simply type exit.

Generated Debug Rigs

Sometimes you want to debug a Component but the problematic Component is being run from inside the rigging of another Component. Other times the Component might be being run by another Component through the Host API.

The slipway debug command isn't able to step inside Components to run these deeply embedded Components in isolation. We could create a new Rig to try and isolate the problematic Component, and debug that instead, but doing that can be time consuming and challenging.

Instead can generate a "debug" Rig. This flattens the entire Rig, including all Component executions made within other Components, into a series of root level Component calls with their inputs fully resolved to JSON.

To demonstrate this, let's create a Rig which uses both Fragment components and callouts to the Host API:

debug_rig_example.json
{
"description": "Renders some text above a chart.",
"constants": {
"width": 800,
"height": 480
},
"rigging": {
"render": {
"component": "slipwayhq.render.0.6.1",
"callouts": {
"echarts": {
"component": "slipwayhq.echarts.0.5.1",
"allow": [
{ "permission": "fonts" },
{ "permission": "registry_components" }
]
}
},
"allow": [
{ "permission": "fonts" },
{ "permission": "registry_components" }
],
"input": {
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "Container",
"separator": true,
"items": [
{
"type": "TextBlock",
"text": "The quick brown fox jumped over the lazy dog. I repeat, the quick brown fox jumped over the lazy dog. Once more, the quick brown fox jumped over the lazy dog.",
"wrap": true
}
]
},
{
"type": "Container",
"height": "stretch",
"items": [
{
"type": "Image",
"height": "stretch",
"url": "component://echarts?width=$width&height=$height",
"body": {
"chart": {
"xAxis": {
"type": "category",
"data": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
]
},
"yAxis": {
"type": "value"
},
"series": [
{
"data": [
150,
230,
224,
218,
135,
147,
260
],
"type": "line"
}
]
}
}
}
]
}
]
},
"canvas": {
"width": "$.constants.width",
"height": "$.constants.height"
}
}
}
}
}

This Rig calls the slipwayhq.render component, and asks it to render a image generated by calling the slipwayhq.echarts component, which returns a chart using some hard-coded data.

The slipwayhq.echarts Component is a Fragment Component, that internally calls the slipwayhq.echarts_svg and slipwayhq.svg Components.

If you were to debug this rig:

slipway debug --allow-fonts --allow-registry-components debug_rig_example.json

All you would see is the root render Component:

Debugging debug_rig_example.json

◩ render ┆ 6818153c ┆ 655 bytes

Type help for commands.
⛵️ >>

Not very useful if we want to debug the echarts_svg Component.

Lets generate a debug rig from this:

slipway run --output-debug-rig "debug_rig_example_generated.json" --allow-fonts --allow-registry-components debug_rig_example.json

This runs the Rig and outputs a debug rig called debug_rig_example_generated.json.

Let's debug that Rig instead:

slipway debug --allow-fonts --allow-registry-components debug_rig_example_generated.json

This is what we now see:

Debugging debug_rig_example_generated.json

◩ render ┆ 6818153c ┆ 655 bytes
◩ render_then_echarts_then_echarts ┆ dad81b3d ┆ 204 bytes
◩ render_then_echarts_then_input ┆ dad81b3d ┆ 204 bytes
◩ render_then_echarts_then_output ┆ 39cd9b81 ┆ 6.50 kb

Type help for commands.
⛵️ >>

We now have four Component handles we can run, representing each time a Component was run in the original Rig. Each handle contains the fully resolved input for that Component, taken from the instant we ran the Component when we generated the debug Rig. This means there are no longer dependencies between the handles, and each can be inspected and run immediately in the debugger.

Permissions of each Component are also preserved by specifying the full permission chain for each Component. This ensures that each Component in a debug Rig is only able to do as much as it could do in the original Rig.

Note that because each Component in a debug Rig contains the fully resolved input, the Rig files can get quite large.

The full generated debug Rig is shown below for completeness:

debug_rig_example_generated.json
{
"description": "Automatically generated debug rig.",
"rigging": {
"render_then_echarts_then_output": {
"component": "slipwayhq.svg.0.6.0",
"input": {
"height": 400,
"svg": "<svg width=\"768\" height=\"400\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\" viewBox=\"0 0 768 400\">\n<rect width=\"768\" height=\"400\" x=\"0\" y=\"0\" fill=\"none\"></rect>\n<path d=\"M76.8 330.5L691.2 330.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 285.5L691.2 285.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 240.5L691.2 240.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 195.5L691.2 195.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 150.5L691.2 150.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 105.5L691.2 105.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 60.5L691.2 60.5\" fill=\"transparent\" stroke=\"#E0E6F1\" class=\"zr0-cls-0\"></path>\n<path d=\"M76.8 330.5L691.2 330.5\" fill=\"transparent\" stroke=\"#6E7079\" stroke-linecap=\"round\" class=\"zr0-cls-0\"></path>\n<path d=\"M77.5 330L77.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M164.5 330L164.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M252.5 330L252.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M340.5 330L340.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M428.5 330L428.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M515.5 330L515.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M603.5 330L603.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<path d=\"M691.5 330L691.5 335\" fill=\"transparent\" stroke=\"#6E7079\" class=\"zr0-cls-0\"></path>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 330)\" fill=\"#6E7079\">0</text>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 285)\" fill=\"#6E7079\">50</text>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 240)\" fill=\"#6E7079\">100</text>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 195)\" fill=\"#6E7079\">150</text>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 150)\" fill=\"#6E7079\">200</text>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 105)\" fill=\"#6E7079\">250</text>\n<text dominant-baseline=\"central\" text-anchor=\"end\" style=\"font-size:12px;font-family:sans-serif;\" transform=\"translate(68.8 60)\" fill=\"#6E7079\">300</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(120.6857 338)\" fill=\"#6E7079\">Mon</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(208.4571 338)\" fill=\"#6E7079\">Tue</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(296.2286 338)\" fill=\"#6E7079\">Wed</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(384 338)\" fill=\"#6E7079\">Thu</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(471.7714 338)\" fill=\"#6E7079\">Fri</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(559.5429 338)\" fill=\"#6E7079\">Sat</text>\n<text dominant-baseline=\"central\" text-anchor=\"middle\" style=\"font-size:12px;font-family:sans-serif;\" y=\"6\" transform=\"translate(647.3143 338)\" fill=\"#6E7079\">Sun</text>\n<g clip-path=\"url(#zr0-c0)\">\n<path d=\"M120.7 195L208.5 123L296.2 128.4L384 133.8L471.8 208.5L559.5 197.7L647.3 96\" fill=\"transparent\" stroke=\"#5470c6\" stroke-width=\"2\" stroke-linejoin=\"bevel\" class=\"zr0-cls-2\"></path>\n</g>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,120.6857,195)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"0\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,208.4571,123)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"1\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,296.2286,128.4)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"2\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,384,133.8)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"3\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,471.7714,208.5)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"4\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,559.5428,197.7)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"5\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<path d=\"M1 0A1 1 0 1 1 1 -0.1A1 1 0 0 1 1 0\" transform=\"matrix(2,0,0,2,647.3143,96)\" fill=\"#fff\" stroke=\"#5470c6\" ecmeta_series_index=\"0\" ecmeta_data_index=\"6\" ecmeta_ssr_type=\"chart\" class=\"zr0-cls-3\"></path>\n<defs >\n<clipPath id=\"zr0-c0\">\n<path d=\"M75 59l618 0l0 272l-618 0Z\" fill=\"#000\" class=\"zr0-cls-1\"></path>\n</clipPath>\n</defs>\n<style ><![CDATA[\n.zr0-cls-0:hover {\npointer-events:none;\n}\n.zr0-cls-1:hover {\ncursor:pointer;\nfill:rgba(0,0,0,1);\n}\n.zr0-cls-2:hover {\ncursor:pointer;\n}\n.zr0-cls-3:hover {\ncursor:pointer;\nfill:rgba(255,255,255,1);\n}\n\n]]>\n\n</style>\n</svg>",
"width": 768
},
"permissions_chain": [
{
"allow": [
{
"permission": "fonts"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
}
]
},
"render_then_echarts_then_input": {
"component": "passthrough",
"input": {
"chart": {
"series": [
{
"data": [
150,
230,
224,
218,
135,
147,
260
],
"type": "line"
}
],
"xAxis": {
"data": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
],
"type": "category"
},
"yAxis": {
"type": "value"
}
},
"height": 400,
"width": 768
},
"permissions_chain": [
{
"allow": [],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
}
]
},
"render_then_echarts_then_echarts": {
"component": "slipwayhq.echarts_svg.0.5.0",
"input": {
"chart": {
"series": [
{
"data": [
150,
230,
224,
218,
135,
147,
260
],
"type": "line"
}
],
"xAxis": {
"data": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
],
"type": "category"
},
"yAxis": {
"type": "value"
}
},
"height": 400,
"width": 768
},
"permissions_chain": [
{
"allow": [],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
}
]
},
"render": {
"component": "slipwayhq.render.0.6.1",
"input": {
"canvas": {
"height": 480,
"width": 800
},
"card": {
"body": [
{
"items": [
{
"text": "The quick brown fox jumped over the lazy dog. I repeat, the quick brown fox jumped over the lazy dog. Once more, the quick brown fox jumped over the lazy dog.",
"type": "TextBlock",
"wrap": true
}
],
"separator": true,
"type": "Container"
},
{
"height": "stretch",
"items": [
{
"body": {
"chart": {
"series": [
{
"data": [
150,
230,
224,
218,
135,
147,
260
],
"type": "line"
}
],
"xAxis": {
"data": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
],
"type": "category"
},
"yAxis": {
"type": "value"
}
}
},
"height": "stretch",
"type": "Image",
"url": "component://echarts?width=$width&height=$height"
}
],
"type": "Container"
}
],
"type": "AdaptiveCard"
}
},
"permissions_chain": [
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
},
{
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
],
"deny": []
}
],
"callouts": {
"echarts": {
"component": "slipwayhq.echarts.0.5.0",
"allow": [
{
"permission": "fonts"
},
{
"permission": "registry_components"
}
]
}
}
}
}
}